読者です 読者をやめる 読者になる 読者になる

C 言語を読み書きできないけど neovim のソースコードを読む (2)

引き続き読んでいきます。あんまり進んでいる感じがしないけど楽しいです。

ソースコードはどこから読む?

  • main.cmain 関数から実行されるはずなので、そこから順番に追っていく。

main 関数の引数

  int main(int argc, char **argv)
  • int argcchar **argv の2種類。
  • int argcコマンドライン引数の数。char **argv は引数として渡された文字列だろうけど、調べると大体でてくるのが char *argv[]になってる。ポインタのポインタを使っている理由は後から分かるはず。
  • TODO: なぜ **argv という書き方になっているのか?

変数の定義

  char_u      *fname = NULL;            /* file name from command line */
  mparm_T params;                       /* various parameters passed between
                                         * main() and other functions. */
  • コメントから察するに main 関数とその他の関数でパラメーターの受け渡しをするときに使う。

mch_early_init 関数

init_params 関数

  • main.c で定義されてる。
/*
 * Many variables are in "params" so that we can pass them to invoked
 * functions without a lot of arguments.  "argc" and "argv" are also
 * copied, so that they can be changed. */
static void init_params(mparm_T *paramp, int argc, char **argv)
{
  vim_memset(paramp, 0, sizeof(*paramp));
  paramp->argc = argc;
  paramp->argv = argv;
  paramp->want_full_screen = TRUE;
  paramp->use_debug_break_level = -1;
  paramp->window_count = -1;
}
  • たくさんあるパラメーターをまとめて扱いやすくするためかな?

vim_memset 関数

  • misc2.c で定義されてる?
#ifndef HAVE_MEMSET
void * vim_memset(ptr, c, size)
void    *ptr;
int c;
size_t size;
{
  char *p = ptr;

  while (size-- > 0)
    *p++ = c;
  return ptr;
}
#endif
  • これって定義しているコードなんだろうか?知っている関数の定義の文法じゃないような。
  • http://wisdom.sakura.ne.jp/programming/c/c33.html ← ここによると、この方法でも関数の定義ができるようだ。ただ、伝統形式と書いてあるので古いやり方らしい。括弧内に型と変数名を一緒に並べる書き方が推奨されているのなら、リファクタリングのポイントになるかも。
  • 引数として渡されたものを何かしらの処理をして返してる。(雑)

site_t 型

atexit 関数

  • C で用意されている標準関数。プログラムの実行終了時に実行する関数を予約することができる。finally 的なイメージを持った。 by http://www.c-tipsref.com/reference/stdlib/atexit.html
  • なので、プログラム終了時に vim_mem_profile_dump 関数が実行されるように予約していることになる。

vim_mem_profile_dump 関数

  • misc2.c で定義されている。

init_startuptime 関数

  • main.c で定義されている。定義内容は下記のとおり。
/*
 * Initialize global startuptime file if "--startuptime" passed as an argument.
 */
static void init_startuptime(mparm_T *paramp)
{
#ifdef STARTUPTIME
  int i;
  for (i = 1; i < paramp->argc; ++i) {
    if (STRICMP(paramp->argv[i], "--startuptime") == 0 && i + 1 < paramp->argc) {
      time_fd = mch_fopen(paramp->argv[i + 1], "a");
      TIME_MSG("--- VIM STARTING ---");
      break;
    }
  }
#endif
  starttime = time(NULL);
}
  • 引数として --startuptime が渡されたら、global startuptime file を初期化するとのこと。global startuptime file って何。
  • 今頃理解したけど、引数にある mparm_T *parampコマンドライン引数を格納してるので、paramp->argv[i] とか、paramp->argc とかでアクセスできるので便利。
  • --startuptime オプションは vim hoge --startuptime moge で起動時間を書き出すことができる。そのファイルを初期化しているということだろう。たぶん。 http://qiita.com/tachiba/items/3c1d29d74f35bdcf11a9

define は関数にも使える

  • こんな感じで。でもなんで置き換えてるんだろう?
  • TODO: なぜ define で関数名を置き換えてる?
#  define mch_fopen(n, p)       fopen((n), (p))

mb_init 関数

  • mbyte.c で宣言されている。
  • マルチバイト文字を使うための準備。
  • p_enc に格納されている値を 8bit- で始まるか?とか iso-8859- で始まるか?とか調べている。とすると p_enc にはエンコーディングの文字列が入ってそう。p_enc に値を格納している箇所を探す。
  • p_enc に値を入れているのは option.cset_init_1 関数で見つかった。後述の enc_locale 関数の返り値を格納してる。

enc_locale 関数

  • mbyte.c で定義されている。
  • たぶん OS のロケール(言語、文字コード)を取得するためのユーザー定義関数。

canonicalize とは

strncmp 関数

C にも三項演算子がある

getenv 関数

C 標準関数は大文字で表記するルール(もしくは習慣)がある?

  • そんな雰囲気。

init_var_dict 関数

  • dictionay を初期化するユーザー定義関数。
  • TODO: dictionay とは?

アロー演算子

ポインタについての分かりやすい解説を見つけた

qnx_init 関数

  • 定義場所が見つからないし、C の標準関数ではなさそう。
  • TODO: qnx_init は何?