t-sin / inquisitor

Encoding/end-of-line detection and external-format abstraction for Common Lisp
34 stars 3 forks source link

detect-end-of-lineが常にnilを返します #26

Closed cxxxr closed 8 years ago

cxxxr commented 8 years ago

Common Lispのloopマクロ

(loop for i from 1 to 3
         with j = i
         collect (list i j))

with j = iはループ毎に更新されるのではなく最初に一回だけなので 結果は((1 1) (2 2) (3 3))ではなく((1 1) (2 1) (3 1))です

detect-end-of-lineのloopを見てみると

(loop for n = (read-sequence vec stream) ; ここでバッファ変数vecを更新して
         with eol = (eol-guess-from-vector vec) ; ここで前の行のvecではなく空のバッファのvecを使ってeolには常にnilが入る
         until (or (zerop n)
                      (not (null eol))) ; eolは常にnilなので(not (null eol))は常にnilでloopを抜ける
         finally (return eol))

この結果detect-end-of-lineは常にnilを返します

このloopのwithをforに変えて動かすと正しく動くはずなんですがテストが通りません テストの失敗した部分を見てみると
× :LF is expected to be NIL となっています しかしこれは:LFが正しいはずなんです

他の場所でも :UCS-2LE is expected to be :UTF-16BE や :BIG5 is expected to be :ISO-2022-TW がありますが これもdetect-end-of-lineの結果を引きずってるみたいです

常にnilを返すバグを無視してテストのほうを変えて動くようにしてるように見えます この機能は都合が悪くてわざと一時的に動かないようにしてるんでしょうか

気が向いたら直しておいてほしいです

t-sin commented 8 years ago

おお…。ご指摘ありがとうございます。

(loop for n = (read-sequence vec stream) ; ここでバッファ変数vecを更新して
         with eol = (eol-guess-from-vector vec) ; ここで前の行のvecではなく空のバッファのvecを使ってeolには常にnilが入る
         until (or (zerop n)

これはその通りですね。気付けずに首をずっと傾げてた部分でした。

25 はacceptします。


パスしないテストというと

 If file has no newline then return NIL
    × :LF is expected to be NIL  ; ←これ
    ✓ NIL is expected to be NIL 

ですかね…?

これ、関数でいうとdetect-end-of-lineじゃなくてeol-quess-from-vectorのテストなんです。 ファイルが改行を含まないときはnilを返そうと決意して、そう実装したらでてきたバグ(#23)で、いまいち原因がわかっていません。

こいつが足を引っぱりまくっているのは事実なので、すぐに対処します。

25 はマージしますが、このissueはまだ開いたままにしておきます。

cxxxr commented 8 years ago

23ですがnilではなく:lfを返すのはファイルの末尾に改行があるから正しいと思います

t-sin commented 8 years ago

はい。すみません。しっかりとLFついてますね。

テストコードが悪いです。テストコードの追加・修正した上で、クローズとします。

t-sin commented 8 years ago

e40955aで正しいテスケースを追加しました。一旦クローズします。

cxxxr commented 8 years ago

ありがとうございます