5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

自作エディタをつくるAdvent Calendar 2016

Day 16

コンソールで動くエディタを作る(16日目) バグ・プルリクエスト・バグ

Last updated at Posted at 2016-12-16

本稿は自作エディタをつくる Advent Calendar 2016の16日目です、レポジトリはこちら

バグ

昨日分を公開した直後に、カーソルがたくさん出てしまうバグをこっそりなおしました。
めっちゃケアレスミスでした

今度こそ、この文章を作ったエディタで書いて・・・って思ったけど、冒頭の定型文を前日文からコピペすると
main(9961,0x7fffbcfd63c0) malloc: *** error for object 0x7f9fb6c02768: incorrect checksum for freed object - object was probably modified after being freed.
が出てきたので、結局VS Codeで書いてます。直さなきゃ!
(いつも作業メモをとりながらコードを書いて、それを手直しして公開しています)

プルリクエスト

ありがたいことに、akinomyoga氏から2件プルリクエストをもらったので、読んでいきます。

プルリクエスト1件目 makefile

頂いたプルリクエストから引用すると

Makefile の修正
・ .o: → .c.o:
・ .c.o ルールに入力ファイル $< が指定されていなかったのを修正
・ リンク時に指定している -Wall -Wextra オプションをコンパイル時にも指定

diffをみると

-.o:
-gcc -g -c $@
+.c.o:
+gcc -g -Wall -Wextra -c -o $@ $<

順番が前後しますが

指摘3件目のオプションの件はdiffをみてすぐに理解できました。いままでxxx.c->xxx.oのときは-Wall -Wextraをつけておらず、.oの結合のときにつけてました。両方つけないとダメだよ、という旨です。
8日目にこのオプションをつけた時に

今まで無視されていた警告もでるようですが、現時点では効果が実感できません。

と書いてましたが、当たり前ですね・・・。警告が本来は出ていましたが、スルーしてしまっていました。

指摘2件目$<は、どのヘッダファイルを読んでコンパイルするかの話で、一般論として$<をつけるべきのようです。
自分のレポジトリのヘッダファイルはオレオレ仕様で、これを使って自動生成しているので、インクルードガードが全部ついています。
そこに甘えて、困ったら適当にincludeを足しているのでビルド自体は通るのですが、本来なら不要なincludeがあることを示唆していそうです。
あとで不要なincludeを削っていくようにしたいです。

コメントで教えてもらった内容によると、$^を指定する場合もあるが、BSD makeのみ対応のようです。
両者で指定範囲が異なるものの、僕の理解だと依存先の依存先の・・・というように末尾に達してからコンパイルを始めるために、結果としては変わらない・・のかな?(自信がない)

指摘1件目 の拡張子を.c.oにするのは、慣習的にはそうするよ、という感じでしょうか?
世の中のMakefileをgithubで眺めてみます。他の人のMakefileめっちゃ長いな・・・
他の人のMakefileだと、%.oになっているのが多いのですが、自分のをそうするとビルドが通らなくなります。
最終的に、拡張子が.oになるのは正しいが、指定は*.oにするべきなのではないか?という気がしてきました。

そのあたりで悩んでいると、issueにコメントをいただきます。そのコメントを頼りに、勘違いがいくつか明らかになります

  • .c.oは拡張子ではなくサフィックスルールと呼び、拡張子が.oになるものにマッチする
  • .oまたは*.oは指定として正しくない。正しくないものを指定すると、gcc -g -c $@には来ない。
    • 結果的にデフォルト設定にフォールバックして、gccではなくccでビルドが通る

また、ccにフォールバックしなくなったので-gオプションが効いて、lldbの出力が少し賢くなった気がします。
まだデバッガを使いこなせてないですが「よくわからないけど思い通り動かない」状態を脱したので、慣れていきたいところ。

プルリクエスト2件目 セグフォ

試してみたのですけれど行末で改行すると Segmentation fault しました。
取り敢えず修正しました。

申し訳なさがすごいです、冒頭のエラーはそのせいでしょうか。
自分でも再現するか確認して、普通に100%再現しました。言い訳の余地がない・・・
メッセージがSegmentation fault: 11なので、冒頭のエラーではなさそうですね。

とりあえず、もらったプルリクエストで動作を確認してみます。
指摘された問題はなおっていますが、ファイルの末尾で改行した後にバックスペースを押すと同様にSegmentation fault: 11で落ちます。
どんどん出てくるバグ・・・

コミットを分けてくれているので、順に読んでいきます。

  • null-checkの考慮漏れ
    • if (current->next) でnull-checkしていたが、if (current)if (current->next)で2回チェックしないといけない。
    • たぶん、似たミスをしているところが他にもある
  • スペルミス devide -> divide
  • null-checkの考慮漏れ、場所は違うが理由は同じ

インデント、空白とタブが混ざっていてた・・・、あとで直さなきゃ

バグ修正・・・?

上で見つかったバグたちを、自作エディタを使って順に潰していきます。

  • 落ちる
  • 保存するファイル名の最後が化ける(フォルダ+ファイル名指定時)
  • 明らかに機能が少ない

ので、結構辛いです。現時点だと(C言語だと)、行数表示が欲しい。
他の言語で欲しいと思ったことはあんまりなかったですが。

しかし、動作確認しながら該当コードも読めるっていう一石二鳥な体験?ができます!
ただ、ビルドが通らなくなると(gulpで自動的にmake cleanされて)エディタがなくなるので
予備のエディタとgitが基本的に生命線です。

とりあえず、gccのwarningを直して、(15日目コメントより)保存をfwriteにしてみました。

ちょっと心がくじけてきたので!?、続きは明日にします。

インデントのタブを空白に

わりとタブで揃ってたのですが、

$ find . | grep '\.c$' | sed 's/\(.*\)/ expand -t 2 \1 > \1.bak /g' | sh
$ find . | grep '\.c\.bak$' | sed 's/\(.*\)\.bak/ mv \1.bak \1 /g' | sh

でまとめて空白に直しました。

タブ文字、僕の環境だとコンソール上の見た目の文字幅が半角ではない・・・つらい(半角扱いされてる)

今日のまとめ

  • どんどん出てくるバグ
  • さらにどんどん出てくるバグ
  • 人生初の、会社ではない人からのプルリクエスト
  • マリオラン1-3クリア

プルリクエストほんとうにありがとうございました。
curses、調べよう調べようと思ってやってないので明日こそ調べるぞ!

5
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?