Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

行の途中に改行コードがある状況について考える #1000

Closed
berryzplus opened this issue Aug 17, 2019 · 17 comments
Closed

行の途中に改行コードがある状況について考える #1000

berryzplus opened this issue Aug 17, 2019 · 17 comments
Labels
question Further information is requested 【ChangeLog除外】

Comments

@berryzplus
Copy link
Contributor

問題内容

テキスト描画の処理改善を検討していて、以下のコメントを見付けました。

bool CFigure_Eol::Match(const wchar_t* pText, int nTextLen) const
{
// 2014.06.18 折り返し・最終行だとDrawImpでcEol.GetLen()==0になり無限ループするので
// もしも行の途中に改行コードがあった場合はMatchさせない
if(nTextLen == 2 && pText[0]==L'\r' && pText[1]==L'\n')return true;
if(nTextLen == 1 && WCODE::IsLineDelimiterExt(pText[0]))return true;
return false;
}

引用

もしも 行の途中に改行コード があった場合はMatchさせない

太字部分が謎ポイントです。

「行」とは、ドキュメント全体を改行コードで区切り、「先頭ないし直前の改行コードの次の文字から改行コードまで」を1まとまりに扱う「概念上の単位」です。行データは内部的に CDocLine のインスタンスになります。CDocLineのデータ内に改行コードを挿入しようとした場合、CDocLineMgr が CDocLine を分割するようになっています。サクラエディタのデータ編集機構は、すべてのデータ編集操作を CDocLineMgr 経由で行う設計になっています。

コメントで指摘される事態は、設計的にありえないと思うんですが、
日付が比較的新しいのでバグ対策として入ったコメントかもしれません。

ぼく個人としては「行の途中に改行コード」の想定はアフォだ!と思っています。
単なる思い込みである可能性を否めないのでとりあえずissueを立てておきます。

もし本当に行の途中に改行コードが入る状況が発生するなら、それはバグだと思っています。

  • つまりそれは、 CDocLineMgr を経由せずにデータを挿入しているってこと。
  • イレギュラー操作を機能で作りこむのは構わないと思いますが、既存仕様を壊しちゃいかんでしょ、と思っています。

当面のゴール設定はせずに、私見とか思い付きとかを幅広く募集する感じです。

再現手順

不明

問題のカテゴリ

  • 仕様の問題
@arigayas
Copy link

テキストファイルではなく、バイナリファイルを開いた場合に発生する可能性があるのかな?と
素人ながらに思いました。

@berryzplus
Copy link
Contributor Author

サクラエディタのファイル読み込みは、いわゆるバイナリモードで行われています。osやcランタイムの介入による文字化けを防ぐために、あえて全部バイナリで読んでいます。

普通に開いた場合に、元ネタがバイナリだからという理由で行区切りを取り違える可能性はないと思います。

いま思い付いたんですが、文字コード変換で先行バイトになり得る文字が変わった場合にはあり得るのかも…

やや怪しいのがアプリ外からのコピペのケースです。バイナリ貼り付けができるようになってるみたいだから。

※それでもCDocLineを経由したら自動で分割されるはずです:smile:

@KENCHjp
Copy link
Member

KENCHjp commented Aug 19, 2019

突然哲学的なタイトルのIssueだなと(笑)
行は改行コードで終端を迎えるはずなので、行の途中に改行が来ることは定義上ありえない言葉かなと思います。
描画上の行の途中に改行コードが割り込んでも行が分割されない何かの”不具合”あるとしか想像できないのですが、どうでしょう。。。
バイナリファイルを読み込んだ時の対応なんて最悪コケても文句言われないような(笑)

@berryzplus
Copy link
Contributor Author

哲学w

次アクションは、実際想定通りなの?を追求してみる感じだと思ってます。

@beru beru added the question Further information is requested 【ChangeLog除外】 label Aug 23, 2019
@beru
Copy link
Contributor

beru commented Aug 23, 2019

b22a783#diff-86563f6d4d65814b433d19ae3f81824b

https://sourceforge.net/p/sakura-editor/patchunicode/842/

http://sakura.qp.land.to/?BugReport%2F169

今のソースコードとは違う昔のソースコードで特定の条件で無限ループに入ってしまうバグが有ったようで、その対策として入れた修正に対するコメントのようです。

改行コードで NEL って初耳なので調べてみました。

http://euc.jp/i18n/charcode.ja.html#chap5

C1 制御文字集合 の規格の 0x85 が復帰改行を行うNEL(next line)という制御文字のようです。

バイナリファイルを開いてその特殊な改行コードに該当する文字を取り扱った際の不具合を解消した時の名残のようです。

@berryzplus
Copy link
Contributor Author

う~む。ざっくり言って
NEL,PS,LSの3文字を改行コードとして表示する対応
のバグってことなんすね。

NEL = ASCII New Line(8ビットコードだが、sjisには存在しない。utf-8では2バイト文字)
LS = Unicode Line Seperator(名前のとおりUnicode専用)
PS = Unicode Paragraph Seperator(名前のとおりUnicode専用)

サクラエディタの内部文字コードは拡張UTF-16LEなので、
3つとも表現可能なのがハマりポイントだったのかも。

ちなみにサクラエディタの拡張UTF-16LEの仕様は以下の通り。

  • 正常系 A⇒W変換、W⇒A変換をして正しく元に戻せる文字は普通にA⇒W変換する。
  • 異常系 A⇒W変換できなかった、または、W⇒A変換をして元に戻らなかった文字を1バイトずつ0xDC00 と OR した wchar_t値 として文字列に埋め込む。0xDC00は、本来はサロゲートペアの2ワード目に使われるマスクで、正常なutf16leのコードシーケンスには現れない。

@berryzplus
Copy link
Contributor Author

ああ、「単独で現れない」ね。
0xD800でマスクされた値、0xDC00でマスクされた値が「連続で現れる」のをサロゲートペアというので。

@cugra
Copy link

cugra commented Aug 25, 2019

はじめまして。
関係あるかもしれない旧Wikiのバグ報告を挙げておきます。

LE,BE以外のUnicodeでもNEL,LS,PSがEOF直前で改行コードとみなされてしまう
投稿日: 2014-06-24 (火) 02:49:19
バージョン: 2.1.1.3
http://sakura.qp.land.to/?BugReport%2F172

ファイルを開いた状態でオプションをOFF→ONにした場合に現状のような各種バグが発生するのに目をつぶれば、オプション化も可能かと(私は共通設定推奨)。ただ改行を扱う箇所が多くそれらにオプションを渡すのが大変です。デフォルトはONにしたいです。でないとEBCDICを使うときにオプションをONにしないとNELがよめなく手間です。OFFにしたい理由が知りたいです。 -- Moca 2014-06-29 (日) 18:28:04
2.2.0.0ではNEL等は「デフォルトではOFF」になりました。 -- 2015-02-24 (火) 20:46:29
対応完了:2.2.0.0 -- 2015-02-24 (火) 20:47:06

@cugra
Copy link

cugra commented Aug 25, 2019

ちなみに私は当該バグ報告の起票者ですが、
そもそも本当はNEL,LS,PSのオプション化も不要(機能自体削除希望)のスタンスでした。

Mocaさんは特にEBCDICでNL(NEL)を改行とみなさせるために
この機能を本体に取り込んだようですが、
EBCDICでいえばNLのみを改行とみなすのが一般的だと思いますので、
どうしてもEBCDIC対応を取り込むのであれば、
EBCDICの時だけCR(0x0D)もLF(0x25)もCRLFも改行せず、
NL(0x15)だけを改行とみなすのがデフォルト動作となるのが最も望ましいと考えます。

参考
https://www.ibm.com/support/knowledgecenter/ja/SSGH4D_15.1.0/com.ibm.xlf151.aix.doc/language_ref/asciit.html

@cugra
Copy link

cugra commented Aug 25, 2019

すみません、
本件の修正と修正コメントは次のバグ報告が起因だったようです。

EOL描画で無応答
投稿者: anonymous
投稿日: 2014-06-18 (水) 18:17:13
バージョン: 2.1.0.0-2.1.1.3(rev.3081以後)
http://sakura.qp.land.to/?BugReport%2F169

@berryzplus
Copy link
Contributor Author

EBCDICって、コードページ対応で初めて使えるようになったんじゃないのかな?
コードページ対応はbyteシーケンスをUnicodeシーケンスに変換することで成り立ってるので、
EBCDIC上のコードが何であれ、Unicodeだけを見て挙動を判断する感じが自然な気がしました。

そもそも本当はNEL,LS,PSのオプション化も不要(機能自体削除希望)のスタンスでした。

最終的にどうするかは分からんですが、個人的にはオプションは外すことを考えています。
オプションで無効/有効を切り替える、ではなく、常に有効としたいです。

何故かというと、NEL,LS,PSをサポートしないコードページを変換したUnicodeシーケンスにそれらの文字が登場する可能性はゼロだからです。コードページでNELがサポートされるのなら、それはそれとして「認識できないバイナリ」ではなく「NEL(復帰改行)」として見せるのが自然な気がします。

@usagisita
Copy link
Contributor

好みとかではなく実務として、変なデータを扱う場合に、コンパイラとかLintとかとタグジャンプや連携する場合に、行番号がずれるのは勘弁してほしいのではないでしょうか。
相手のツールをいじるのは難しい場合が多いので、なんらかの選択肢があると、玄人向けではあるけど、助かる人もいるのではないかと愚考します。

@cugra
Copy link

cugra commented Aug 25, 2019

これも当時Mocaさんに伝えませんでしたが、
UnicodeでLF,CR,CRLFの従来からの3つに加えて、
NEL,LS,PSの3種類だけを追加するのは片手落ちだと思っていました。
もしどうしてもUnicodeにおける改行を追加するという思想を推し進めるなら
垂直タブVTと改ページFFでも次行の1桁目に改行復帰すべきだと思います。

参考URL
http://www.unicode.org/reports/tr13/tr13-9.html#Definitions

@berryzplus
Copy link
Contributor Author

好みとかではなく実務として、変なデータを扱う場合に、コンパイラとかLintとかとタグジャンプや連携する場合に、行番号がずれるのは勘弁してほしいのではないでしょうか。

ああ、それはマジ勘弁ですね。<行番号ずれる

サクラエディタには、物理行とレイアウト行の2つの概念があります。
いまは、物理行でもNEL,LS,PSが改行文字扱いになったりならなかったりしてるんですが、これを「絶対に含まない」に変えたらいいと思います。そうすればNEL,LS,PSの問題を純粋に「どう見せるか?」の話にできそうです。どう見せるか?は好みの問題なので、設定で変えてもいい気がしてきます・・・実装めんどいので矢印の見え方以外を変えられるようにするのには抵抗ありますが・・・。

垂直タブVTと改ページFFでも次行の1桁目に改行復帰すべきだと思います。

ばーてぃかるたぶとか、ふぉーむふぃーどとか、
現代っ子が知らなさそうな単語なので、誰かが困るまで全力で放置する所存です。
垂直方向のタブはあまり使われないので、標準的なタブ幅がない認識です。
ふぉーむ1枚のサイズを定義しとかないと、ffは意味をなさない気がします。

まぁ、それを言い出すと「PSって単なる改行じゃないんだけど?」みたいなややこしい話も出てきそうなので、仕様的なところを楽しくかつ真面目に考えられる人が集まってきてからやりたいな、と思っています。

画面表示の direct draw 対応ができるまでは、印刷の話をしづらいってとこもあります。

@berryzplus
Copy link
Contributor Author

一時的な総括

本件、仕様バグが確定した認識です。

再現方法

  1. NEL,PS,LSを無効にする
  2. なんらかの方法でNEL文字(0x85)を入力する
  3. NEL,PS,LSを有効にする 設定変更時に物理行の行末記号巻き替え処理が走らないので、普通に行の途中に「改行コード(NEL)」がある状態が発生する。

取りうる対策

  1. 設定変更時に物理行の行末を巻き替える処理を入れる
  2. 「サポートする行末」の設定が物理行に影響を与えないようにする

正攻法はたぶん1案です。
設定が反映問題は他にもたくさんあるので、横展開として実施するプランです。
現状のサクラエディタの行データは、全行インメモリになってるので、設定変更時に行末を編集する処理を入れると、最悪「設定を変えると固まることがある」の不具合になりかねません。
なので、この方法は全力で避けたい感じです。

代替案は、既存の改行クラスCEolを物理行向けとレイアウト行向けに分離する、と言ってます。

  • 従来
    • 物理行 CRLF, LF, CRで改行。設定によりNEL,PS,LSでも改行。
    • レイアウト行 CRLF, LF, CRで改行。設定によりNEL,PS,LSでも改行。
  • 提案
    • 物理行 CRLF, LF, CRで改行。それ以外では改行しない。
    • レイアウト行 CRLF, LF, CRで改行。設定によりNEL,PS,LSでも改行。 レイアウトマネージャにより挿入される、折り返し記号とEOF記号も改行記号として扱う。

基本となる物理行の行区切りに、「世間的には非標準」である特殊記号を含めないことにより、他ツールとの互換性を確保できることがメリットだと思います。

この issue については、修正が完了してからのcloseとしたいです。
影響範囲がボチボチ大きいので、とりあえずは #1034 のマージ待ちです。

@berryzplus
Copy link
Contributor Author

#1034 はとっくの昔にマージされてるので着手可能。対応要です。

@berryzplus
Copy link
Contributor Author

モチベーションが尽きたので閉じてしまいます。 #1394

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested 【ChangeLog除外】
Projects
None yet
Development

No branches or pull requests

6 participants