Vimのソース内で自作した関数の結果を確認する

 Vimにコントリビュートしたいけど、 「char_u*って? typval_Tってなんじゃい? eval1? :h expr1?」 っていう状態だった。

 とりあえず、自作関数で動作を確認したい。

    static void
mine(void)
{
    static int b = 0;
    if (!b) {
	b = 1;
	char_u* x = vim_strsave((char_u*) "10");
	typval_T y = { VAR_UNKNOWN, 0, {0} };
	eval1(&x, &y, 1);
	printf("\n");  // ここをX行目と仮定する
    }

  1. eval.hのex_echo関数をエディタで開く。
  2. その上に上記のmine関数を定義する。
    • 名前はmineでなくてもよい。内容もお好みで。
  3. ex_echo関数の変数宣言句の下で、mineを呼び出す。
    • /*
       * ":echo expr1 ..."	print each argument separated with a space, add a
       *			newline at the end.
       * ":echon expr1 ..."	print each argument plain.
       */
          void
      ex_echo(exarg_T *eap)
      {
          char_u	*arg = eap->arg;
          typval_T	rettv;
          char_u	*tofree;
          char_u	*p;
          int		needclr = TRUE;
          int		atstart = TRUE;
          char_u	numbuf[NUMBUFLEN];
          int		did_emsg_before = did_emsg;
          int		called_emsg_before = called_emsg;
      
          mine();  // ha-ya!
      
          if (eap->skip)
          ++emsg_skip;
          while (*arg != NUL && *arg != '|' && *arg != '\n' && !got_int)
  4. CLIでmake
  5. Vimで:packadd termdebug, :execute 'Termdebug' expand('~/path/to/vim/src/vim')
  6. gdbウィンドウでb mineからのrun -u NONE --noplugin
  7. Vimウィンドウで:echo 10
    • 10でなくてもよい。なんでもいいからex_echoを呼び出す。
  8. gdbウィンドウでnして、mineのX行目へ進む。
    • X行目については、上記mineの定義を参照。
  9. gdbウィンドウで結果を確認する。
    • Breakpoint 1, mine () at eval.c:8897
      8897    {
      (gdb) n
      8899        if (!b) {
      (gdb) 
      8900            b = 1;
      (gdb) 
      8901            char_u* x = vim_strsave((char_u*) "10");
      (gdb) 
      8902            typval_T y = { VAR_UNKNOWN, 0, {0} };
      (gdb) 
      8903            eval1(&x, &y, 1);
      (gdb) 
      8904            printf("\n");
      (gdb) p x
      $1 = (char_u *) 0x5555558cbb52 ""
      (gdb) p y
      $2 = {v_type = VAR_NUMBER, v_lock = 0 '\000', vval = {v_number = 10, v_float = 4.9406564584124654e-323, v_string = 0xa <error: Cannot access memory at address
       0xa>, v_list = 0xa, v_dict = 0xa, v_partial = 0xa, v_job = 0xa, v_channel = 0xa, v_blob = 0xa}}
      (gdb) p y.v_type
      $3 = VAR_NUMBER
      (gdb) p y.vval.v_number
      $4 = 10

完了!

筆者プロフィール

my-latest-logo

aiya000(あいや)

せつラボ 〜圏論の基本〜」 「せつラボ2~雲と天使と関手圏~」 「矢澤にこ先輩といっしょに代数!」を書いています!

強い静的型付けとテストを用いて、バグを防ぐのが好き。Haskell・TypeScript。