For Development HEAD DRAFTSearch (procedure/syntax/module):

12.65 text.diff - テキストストリームの相違点を計算する

Module: text.diff

このモジュールでは、util.lcs (util.lcs - 最長共通サブシーケンス参照)を 使って、2つのテキストストリーム、あるいは2つの文字列の相違点を計算します。

Function: diff src-a src-b :key reader eq-fn

{text.diff} テキストソースsrc-asrc-bから“編集リスト”を生成します。

それぞれのテキストソース、src-asrc-bは入力ポートか文字列です。 もし文字列であれば、それは内部的に文字列ポートに変換されます。 そして、2つのソースからのテキストストリームは、それらに対してreaderを繰り返し 呼ぶことによってシーケンスに変換されます。デフォルトのreaderread-lineで、 2つのシーケンスは編集リストを計算するためにlcs-edit-listに渡されます。 lcs-edit-listには、等値を検査する関数eq-fnも渡されます。

編集リストとは、src-aからsrc-bへテキストシーケンスを 変更するためのコマンドのセットです。編集リストの詳細な説明は、 lcs-edit-listを参照してください。

(diff "a\nb\nc\nd\n" "b\ne\nd\nf\n")
⇒
  (((- 0 "a"))
   ((- 2 "c") (+ 1 "e"))
   ((+ 3 "f")))
Function: diff-report src-a src-b :key reader eq-fn writer

{text.diff} 2つのテキストソースのdiffをとって、その結果をきれいに表示するための 簡易手続きです。この手続きは、2つのテキストソースの相違点を計算する ためにlcs-foldを呼び出します。src-asrc-breadereq-fnの意味は、diffの場合と同じです。

writerは2つの引数、テキスト要素とタイプ(シンボル+、 シンボル-、あるいは#fのいずれか)を取る手続きです。 テキスト要素がsrc-aにしかない場合は、writerがそのテキスト要素と -とともに呼ばれます。テキスト要素がsrc-bにしかない場合は、 writerはそのテキスト要素と+とともに呼ばれます。 テキスト要素が両方のソースにある場合は、writerはそのテキスト要素と #fとともに呼ばれます。writerのデフォルトの手続きは、 渡されたテキスト要素を現在の出力ポートにユニファイドdiffのようなフォーマットで 出力します。

(diff-report "a\nb\nc\nd\n" "b\ne\nd\nf\n")

displays:

- a
  b
- c
+ e
  d
+ f
Function: diff-report/context src-a src-b :key reader eq-fn writer context-size

{text.diff} diff-reportと同じように、二つのテキストソースの差違を出力しますが、 コンテキスト形式を使います。

(diff-report/context "a\nb\nc\nd\n" "b\ne\nd\nf\n")

は次を出力します:

***************
*** 1,4 ****
- a
  b
! c
  d
--- 1,4 ----
  b
! e
  d
+ f

この手続きはlcs-edit-list/contextを呼んでコンテキストdiffを得て、 それをdiff -cと同じ形式にして出力します。

各 “hunk” (差異を含む塊)はセパレータ***************で始まり、 その後にsrc-aからの抜粋、そしてsrc-bからの抜粋が続きます。 各抜粋の先頭には、そのhunkの範囲を示す行番号が出力されます (開始と終了の行番号、どちらも範囲に含まれる、最初の行は1)。

抜粋の中では、src-aから削除された行の前に-が、 src-bに挿入された行の前に+が、そして置き換えられた行の前に!が、 それぞれ付加されます。

1つのhunkが、挿入のみ、または削除のみで構成されている場合、 変更のない方は抜粋が省略されます。

(diff-report/context "a\nb\nc\n" "a\nc\n")
 prints:
***************
*** 1,3 ****
  a
- b
  c
--- 1,2 ----

特別な場合として、一方のソースが空だった場合、その抜粋のヘッダの行番号は0となります。

(diff-report/context "" "a\nb\nc\n")
 prints:
***************
*** 0 ****
--- 1,3 ----
+ a
+ b
+ c

readerwritereq-fnキーワード引数の意味は diff-reportと同じです。context-sizeキーワード引数は 各hunkの前後に文脈表示のために付加される、変更のなかった行の最大数を指定します。

Function: diff-report/unified src-a src-b :key reader eq-fn writer context-size

{text.diff} diff-report/contextと似ていますが、diff -uと同じ 「unified diff」形式で結果を表示します。

(diff-report/unified "a\nb\nc\nd\n" "a\nx\nd\n")
 prints:
@@ -1,4 +1,3 @@
 a
-b
-c
+x
 d

各hunkは次のヘッダで始まります:

@@ -p,q +r,s @@

ここで、psrc-aにおけるhunkの開始行、 qsrc-aにおけるhunkの長さ、 rsrc-bにおけるhunkの開始行、 ssrc-bにおけるhunkの長さです。

行番号は1から始まります。また、hunkの長さが1の場合、それは省略されます。

src-aから削除された行には-が、 src-bに追加された行には+が、 そして変更のない行にはスペースが付加されます。

特別な場合として、どちらかの入力が空だった場合、その開始行と長さはともに0となります。

(diff-report/unified "a\nb\nc\n" "")
 prints:
@@ -1,3 +0,0 @@
-a
-b
-c

readereq-fnwritercontext-sizeキーワード引数は diff-report/contextと同じです。

この手続きはtest*/diffでテスト結果との差異を示すのに使われています (gauche.test - 単体テスト参照)。



For Development HEAD DRAFTSearch (procedure/syntax/module):
DRAFT