@node Library modules - Utilities, C to Scheme mapping, Library modules - SRFIs, Top
@chapter Library modules - Utilities
@c NODE ライブラリモジュール - ユーティリティ


@c ----------------------------------------------------------------------
@menu
* Binary I/O::                  binary.io
* Packing binary data::         binary.pack
* Running Chibi-scheme test suite::  compat.chibi-test
* Rational-less arithmetic::    compat.norational
* A common job descriptor for control modules::  control.job
* Thread pools::                control.thread-pool
* Password hashing::            crypt.bcrypt
* Cache::                       data.cache
* Heap::                        data.heap
* Immutable deques::            data.ideque
* Immutable map::               data.imap
* Priority map::                data.priority-map
* Queue::                       data.queue
* Random data generators::      data.random
* Ring buffer::                 data.ring-buffer
* Skew binary random-access lists::  data.skew-list
* Sparse data containers::      data.sparse
* Trie::                        data.trie
* Database independent access layer::  dbi
* Generic DBM interface::       dbm
* File-system dbm::             dbm.fsdbm
* GDBM interface::              dbm.gdbm
* NDBM interface::              dbm.ndbm
* Original DBM interface::      dbm.odbm
* Filtering file content::      file.filter
* Filesystem utilities::        file.util
* Mathematic constants::        math.const
* Mersenne-Twister random number generator::  math.mt-random
* Prime numbers::               math.prime
* Windows support::             os.windows
* PEG parser combinators::      parser.peg
* RFC822 message parsing::      rfc.822
* Base64 encoding/decoding::    rfc.base64
* HTTP cookie handling::        rfc.cookie
* FTP::                         rfc.ftp
* HMAC keyed-hashing::          rfc.hmac
* HTTP::                        rfc.http
* ICMP packets::                rfc.icmp
* IP packets::                  rfc.ip
* JSON parsing and construction::  rfc.json
* MD5 message digest::          rfc.md5
* MIME message handling::       rfc.mime
* Quoted-printable encoding/decoding::  rfc.quoted-printable
* SHA message digest::          rfc.sha
* Transport layer security::    rfc.tls
* URI parsing and construction::  rfc.uri
* UUID::                        rfc.uuid
* Zlib compression library::    rfc.zlib
* SLIB::                        slib
* Functional XML parser::       sxml.ssax
* SXML query language::         sxml.sxpath
* Manipulating SXML structure::  sxml.tools
* Serializing XML and HTML from SXML::  sxml.serializer
* Text terminal control::       text.console
* CSV tables::                  text.csv
* Calculate difference of text streams::  text.diff
* EDN parsing and construction::  text.edn
* Running external editor::     text.external-editor
* Gap buffer::                  text.gap-buffer
* Localized messages::          text.gettext
* Simple HTML document construction::  text.html-lite
* Display with pager::          text.pager
* Parsing input stream::        text.parse
* Showing progress on text terminals::  text.progress
* SQL parsing and construction::  text.sql
* Simple template expander::    text.template
* Transliterate characters::    text.tr
* Lazy text construction::      text.tree
* Combination library::         util.combinations
* Message digester framework::  util.digest
* Calculate dominator tree::    util.dominator
* Determine isomorphism::       util.isomorph
* The longest common subsequence::  util.lcs
* Levenshtein edit distance::   util.levenshtein
* Pattern matching::            util.match
* SLIB-compatible record type::  util.record
* Relation framework::          util.relation
* Stream library::              util.stream
* Topological sort::            util.toposort
* Unification::                 util.unification
* CGI utility::                 www.cgi
* CGI testing::                 www.cgi.test
* CSS parsing and construction::  www.css
@end menu

@c ----------------------------------------------------------------------
@node Binary I/O, Packing binary data, Library modules - Utilities, Library modules - Utilities
@section @code{binary.io} - Binary I/O
@c NODE バイナリI/O, @code{binary.io} - バイナリI/O

@deftp {Module} binary.io
@mdindex binary.io
@c EN
This module provides basic procedures to perform binary I/O
of numeric data.  Each datum can be read from or written to a port,
and got from or put to a uniform vector (see @ref{Uniform vectors}).
For structured binary data I/O,
more convenient @code{pack} utility is implemented
on top of this module (see @ref{Packing binary data}).
You might want to use this module directly if you need
speed or want a flexible control of endianness.

See also @ref{Uniform vectors}, which provides binary block I/O.
@c JP
このモジュールは数値データを読み書きするバイナリ入出力用の基本手続きを提
供します。各データはポートあるいはユニフォームベクタ
(@ref{Uniform vectors}参照)から読み込み、あるいはそれらへ書き出すことが
できます。
構造をもつバイナリデータの入出力については、便利な
@code{pack}ユーティリティがこのモジュールを使って実装されています
(@ref{Packing binary data}を参照してください)。
スピードあるいはエンディアンの柔軟な制御などをやりたいときにこのモジュー
ルが使えます。

バイナリのブロック入出力については@ref{Uniform vectors}を参照してくだ
さい。
@c COMMON
@end deftp

@c EN
@subheading Endianness
Most procedures of this module take an optional @var{endian} argument,
specifying the byte order of the binary input.
It must be either one of symbols @code{big-endian}, @code{little-endian},
or @code{arm-little-endian}.
If the endian argument is omitted, the current value of the builtin
parameter @code{default-endian} is used (@pxref{Endianness}).
(For 8-bit I/O procedures like @code{read-u8} the endian
argument has no effect, but is accepted for consistency).
@c JP
@subheading エンディアン
このモジュールのほとんどの手続はオプション引数として@var{endian}引数を
とります。これは@code{big-endian}、@code{little-endian}、
@code{arm-little-endian}のいずれかのシンボルでなければなりません。
エンディアン引数が省略された場合には、組込みパラメータ@code{default-endian}
の現在値が使われます (@ref{Endianness}参照)。
(@code{read-u8}の ような
8ビット入出力手続ではエンディアン引数は意味がありませんが、
一貫性のため受け入れるようにしてあります。)
@c COMMON

@c EN
@subheading I/O using port
@c JP
@subheading ポートを用いたI/O
@c COMMON

@defun read-u8 :optional port endian
@defunx read-u16 :optional port endian
@defunx read-u32 :optional port endian
@defunx read-u64 :optional port endian
@c MOD binary.io
@c EN
Reads 8, 16, 32 or 64 bit unsigned integer from @var{port}
with specified endian, respectively.  If @var{port} is omitted,
current input port is used.  If @var{port} reaches EOF before
a complete integer is read, EOF is returned.
@c JP
それぞれ指定したエンディアンで@var{port}から8、16、32、64ビット符号無
整数を読み込みます。@var{port}が省略された場合は、現在の入力ポートが使
われます。@var{port}が整数の読み込みが完了する前にEOFに到達してしまっ
た場合にはEOFが返ります。
@c COMMON
@end defun

@defun read-s8 :optional port endian
@defunx read-s16 :optional port endian
@defunx read-s32 :optional port endian
@defunx read-s64 :optional port endian
@c MOD binary.io
@c EN
Reads 8, 16, 32 or 64 bit 2's complement signed integer from @var{port}
with specified endian, respectively.  If @var{port} is omitted,
current input port is used.  If @var{port} reaches EOF before
a complete integer is read, EOF is returned.
@c JP
それぞれ指定したエンディアンで@var{port}から8、16、32、64ビット、2の補
数符号付き整数を読み込みます。@var{port}が省略された場合は、現在の入力
ポートが使われます。@var{port}が整数の読み込みが完了する前にEOFに到
達してしまった場合にはEOFが返ります。
@c COMMON
@end defun

@defun read-uint size :optional port endian
@defunx read-sint size :optional port endian
@c MOD binary.io
@c EN
More flexible version.  Reads @var{size}-octet unsigned
or signed integer from @var{port} with specified endian.
If @var{port} reaches EOF before a complete integer is read,
EOF is returned.
@c JP
さらに柔軟性が高く、@var{size}オクテットの符号無しあるいは符号付き整数
を@var{port}から指定のエンディアンで読み込みます。
@var{port}が整数の読み込みが完了する前にEOFに到
達してしまった場合にはEOFが返ります。
@c COMMON
@end defun

@defun read-ber-integer :optional port
@c MOD binary.io
@c EN
Reads BER compressed integer a la X.209.
A BER compressed integer is an unsigned integer in base 128,
most  significant digit first, where the high bit is set on all but the
final (least significant) byte.
@c JP
X.209のBER圧縮形式整数を読み込みます。BER圧縮形式整数は128進符号無し整
数です。最上位桁が最初にきます。最下位桁のバイトをのぞき、すべてのバイ
トの最上位ビットはオンになっています。
@c COMMON
@end defun

@defun write-u8 val :optional port endian
@defunx write-u16 val :optional port endian
@defunx write-u32 val :optional port endian
@defunx write-u64 val :optional port endian
@c MOD binary.io
@c EN
Writes a nonnegative integer @var{val} as 8, 16, 32 or 64 bit
unsigned integer
to @var{port} with specified endian, respectively.  @var{Val} must be within
the range of integers representable by the specified bits.
When @var{port} is omitted, current output port is used.
@c JP
それぞれ指定したエンディアンで@var{port}へ 8、16、32、64ビット、符号無
し整数として表現されている非負整数@var{val}を書き出します。
@var{val}はそれぞれ指定したビット数の範囲で表現できる値でなければなり
ません。@var{port}が省略された場合は、現在の出力ポートが使われます。
@c COMMON
@end defun

@defun write-s8 val :optional port endian
@defunx write-s16 val :optional port endian
@defunx write-s32 val :optional port endian
@defunx write-s64 val :optional port endian
@c MOD binary.io
@c EN
Writes an integer @var{val} as 8, 16, 32 or 64 bit
as 2's complement signed integer to @var{port} with specified endian,
respectively.  @var{Val} must be within
the range of integers representable by the specified bits.
When @var{port} is omitted, current output port is used.
@c JP
それぞれ指定したエンディアンで@var{port}へ 8、16、32、64ビット、2の補
数符号付き整数として表現されている整数@var{val}を書き出します。
@var{val}はそれぞれ指定したビット数の範囲で表現できる値でなければなり
ません。@var{port}が省略された場合は、現在の出力ポートが使われます。
@c COMMON
@end defun

@defun write-uint size val :optional port endian
@defunx write-sint size val :optional port endian
@c MOD binary.io
@c EN
More flexible version.  Writes an integer @var{val} as unsigned
or signed integer of @var{size} bytes to @var{port} with
specified endian.
When @var{port} is omitted, current output port is used.
@c JP
さらに柔軟性が高く、@var{size}オクテットの符号無しあるいは符号付き整数
@var{val}を@var{port}へ、指定のエンディアンで書き出します。
@var{port}が省略された場合は、現在の出力ポートが使われます。
@c COMMON
@end defun

@defun write-ber-integer val :optional port
@c MOD binary.io
@c EN
Writes a nonnegative integer @var{val} in BER compressed integer
to @var{port}.  See @code{read-ber-integer} above for BER format.
@c JP
BER圧縮形式の非負整数@var{val}を@var{port}へ書き出します。
BER圧縮形式については前述の@code{read-ber-integer}を見てください。
@c COMMON
@end defun

@defun read-f16 :optional port endian
@defunx read-f32 :optional port endian
@defunx read-f64 :optional port endian
@c MOD binary.io
@c EN
Reads 16, 32, or 64-bit floating point numbers, respectively.
32bit is IEEE754 single-precision, and 64bit is
IEEE754 double-precision numbers.  16-bit floating
point number consists of 1-bit sign, 5-bit exponent and
10-bit mantissa, as used in some HDR image format.

If @var{port} is omitted,
current input port is used.  If @var{port} reaches EOF before
a complete number is read, EOF is returned.
@c JP
それぞれ、16、32、64ビットの浮動小数点数を読み込みます。
32ビットはIEEE754単精度、64ビットは倍精度の浮動小数点数です。
16ビット浮動小数点数は、1ビットの符号、5ビットの指数、10ビットの仮数からなる、
HDRイメージフォーマット等に使われている形式です。

@var{port}が省略された場合には、
現在の入力ポートが使われます。@var{port}が数値の読み込みが完了する前に
EOFに到達してしまった場合にはEOFが返ります。
@c COMMON
@end defun

@defun write-f16 val :optional port endian
@defunx write-f32 val :optional port endian
@defunx write-f64 val :optional port endian
@c MOD binary.io
@c EN
Writes a real number @var{val} to @var{port} in 16,
32, or 64-bit floating point number, respectively.
If @var{port} is omitted, current output port is used.
@c JP
実数値@var{val}を、それぞれ16、32、64ビットの浮動小数点数として
書き出します。
@var{port}が省略された場合には、現在の出力ポートが使われます。
@c COMMON
@end defun


@c EN
@subheading I/O using uniform vectors
@c JP
@subheading ユニフォームベクタを用いたI/O
@c COMMON

@c EN
In the following routines, the argument @var{uv} can be any
type of uniform vector; if it is not a @code{u8vector}, it is
treated as if @code{(uvector-alias <u8vector> @var{uv})} is
called---that is, it reads directly from the memory image
that holds the uvector's content.  The @var{pos} argument
specifies the byte position from the beginning of the memory
area (it is always byte position, regardless of the uniform
vector's element size).
@c JP
以下のルーチンでは、引数 @var{uv} は任意の型のユニフォームベクタをとり
えます。@code{u8vector} ではない場合には @code{(uvector-alias
<u8vector> @var{uv})} が呼ばれたのと同様の扱いになります。すなわち、
uvectorの内容を保持するメモリイメージから直接読み込まれます。@var{pos}
引数は当該のメモリ領域の最初からのバイト位置を指定するのに使います(こ
れはユニフォームベクタの要素のサイズにかかわらず、つねにバイト位置です)。
@c COMMON

@defun get-u8 uv pos :optional endian
@defunx get-u16 uv pos :optional endian
@defunx get-u32 uv pos :optional endian
@defunx get-u64 uv pos :optional endian
@defunx get-s8 uv pos :optional endian
@defunx get-s16 uv pos :optional endian
@defunx get-s32 uv pos :optional endian
@defunx get-s64 uv pos :optional endian
@defunx get-f16 uv pos :optional endian
@defunx get-f32 uv pos :optional endian
@defunx get-f64 uv pos :optional endian
@c MOD binary.io
@c EN
Reads a number of a specific format from a uniform vector @var{uv},
starting at a byte position @var{pos}.  An error is signaled
if the specified position makes reference outside of the uniform
vector's content.  Returns the read number.
@c JP
ユニフォームベクタ @var{uv} のバイト位置 @var{pos} から指定したフォー
マットで数値を読み込み、その数値を返します。指定した位置が当該ユニフォー
ムベクタの内容のある範囲外を参照するものであった場合、エラーを示すシグ
ナルがあがります。
@c COMMON
@end defun

@defun get-u16be uv pos
@defunx get-u16le uv pos
@defunx get-u32be uv pos
@defunx get-u32le uv pos
@defunx get-u64be uv pos
@defunx get-u64le uv pos
@defunx get-s16be uv pos
@defunx get-s16le uv pos
@defunx get-s32be uv pos
@defunx get-s32le uv pos
@defunx get-s64be uv pos
@defunx get-s64le uv pos
@defunx get-f16be uv pos
@defunx get-f16le uv pos
@defunx get-f32be uv pos
@defunx get-f32le uv pos
@defunx get-f64be uv pos
@defunx get-f64le uv pos
@c MOD binary.io
@c EN
These are big-endian (@code{be}) or little-endian (@code{le}) specific
versions of @code{get-*} procedures.  In speed-sensitive code,
you might want to use these to avoid the overhead of optional-argument
handling.
@c JP
これらは、@code{get-*} 手続のエンディアン(ビッグエンディアン @code{be}
あるいはリトルエンディアン @code{le})を指定した版です。スピードを要求
されるコードではオプション引数処理のオーバーヘッドを避けるためこちらを
使うのがいいでしょう。
@c COMMON
@end defun

@defun get-uint size uv pos :optional endian
@defunx get-sint size uv pos :optional endian
@c MOD binary.io
@c EN
Read @var{size} octets from uvector @var{uv},
starting from @var{pos}-th octet, as an unsigned or signed integer,
respectively.
@c JP
ユニフォームベクタ@var{uv}の@var{pos}番目のオクテットから@var{size}オクテットを、
それぞれ符号無し、符号つき整数として読み取ります。
@c COMMON

@example
(get-uint 3 '#u8(1 2 3 4) 1 'big-endian)
  @result{} 131884 ; @r{#x020304}

(get-sint 3 '#u9(1 2 3 #xff) 1 'little-endian)
  @result{} -64766 ; @r{sign extended #xff0302}
@end example
@end defun

@defun put-u8! uv pos val :optional endian
@defunx put-u16! uv pos val :optional endian
@defunx put-u32! uv pos val :optional endian
@defunx put-u64! uv pos val :optional endian
@defunx put-s8! uv pos val :optional endian
@defunx put-s16! uv pos val :optional endian
@defunx put-s32! uv pos val :optional endian
@defunx put-s64! uv pos val :optional endian
@defunx put-f16! uv pos val :optional endian
@defunx put-f32! uv pos val :optional endian
@defunx put-f64! uv pos val :optional endian
@c MOD binary.io
@c EN
Writes a number @var{val} into a uniform vector @var{uv} in
a specific format, starting at a byte position @var{pos}.
An error is signaled
if the specified position makes reference outside of the uniform
vector's content.
@c JP
数値 @var{val} をユニフォームベクタ @var{uv} のバイト位置 @var{pos} か
ら指定されたフォーマットで書き出します。指定した位置が当該ユニフォーム
ベクタの内容のある範囲外を参照するものであった場合、エラーを示すシグナ
ルがあがります。
@c COMMON
@end defun

@defun put-u16be! uv pos val
@defunx put-u16le! uv pos val
@defunx put-u32be! uv pos val
@defunx put-u32le! uv pos val
@defunx put-u64be! uv pos val
@defunx put-u64le! uv pos val
@defunx put-s16be! uv pos val
@defunx put-s16le! uv pos val
@defunx put-s32be! uv pos val
@defunx put-s32le! uv pos val
@defunx put-s64be! uv pos val
@defunx put-s64le! uv pos val
@defunx put-f16be! uv pos val
@defunx put-f16le! uv pos val
@defunx put-f32be! uv pos val
@defunx put-f32le! uv pos val
@defunx put-f64be! uv pos val
@defunx put-f64le! uv pos val
@c MOD binary.io
@c EN
These are big-endian (@code{be}) or little-endian (@code{le}) specific
versions of @code{put-*} procedures.  In speed-sensitive code,
you might want to use these to avoid the overhead of optional-argument
handling.
@c JP
これらは、@code{put-*} 手続のエンディアン(ビッグエンディアン @code{be}
あるいはリトルエンディアン @code{le})を指定した版です。スピードを要求
されるコードではオプション引数処理のオーバーヘッドを避けるためこちらを
使うのがいいでしょう。
@c COMMON
@end defun

@defun put-uint! size uv pos val :optional endian
@defunx put-sint! size uv pos val :optional endian
@c MOD binary.io
@c EN
Write an unsigned or signed integer @var{val} into
an uvector @var{uv} starting from @var{pos}-th octet,
for @var{size} octets, respectively.
@c JP
それぞれ符号無しまたは符号つき整数@var{val}を、
ユニフォームベクタ@var{uv}の@var{pos}番目のオクテットから@var{size}オクテット分に
書き込みます。
@c COMMON
@end defun


@c EN
@subheading Compatibility notes
@c JP
@subheading 互換性への注
@c COMMON

@c EN
@code{read-u8} etc. were called @code{read-binary-uint8} etc., and
@code{read-f32} and @code{read-f64} were called @code{read-binary-float}
and @code{read-binary-double}, respectively.
These old names are still supported for the backward compatibility
but their use is deprecated.  The reason of the changes is
for brevity and for consistency with the uniform vectors.
@c JP
@code{read-u8} などは @code{read-binary-uint8} と呼ばれていたもので、
@code{read-f32} や @code{read-f64} はそれぞれ @code{read-binary-float}、
@code{read-binary-double} と呼ばれていたものです。
これらの古い名前は後方互換のためいまのところサポートされていますが、使
用については非推奨とします。この変更は名前の短縮とユニフォームベクタと
の一貫性維持のために行われました。
@c COMMON

@c ----------------------------------------------------------------------
@node Packing binary data, Running Chibi-scheme test suite, Binary I/O, Library modules - Utilities
@section @code{binary.pack} - Packing binary data
@c NODE バイナリデータのパック, @code{binary.pack} - バイナリデータのパック

@deftp {Module} binary.pack
@mdindex binary.pack
@c EN
This module provides an interface for packing and unpacking (writing
and reading) binary data with templates.  The functionality was
inspired largely by the Perl pack/unpack functions, with comparison of
similar features from other languages, however an effort was made to
make it more general and more efficient, to be usable for
database-like processing.  To that end, the most notable differences
are that any packable value is unpackable (and vice versa), and the
default behavior is to pack and unpack using port I/O, so you can seek
in a large file and unpack from it.  Also, templates may be stored as
dispatch closures to pack, unpack or even skip over values without
re-parsing the template.
@c JP
このモジュールは、バイナリデータをテンプレートを使って
パック/アンパック(読み書き)するためのインタフェースを提供します。
この機能は、その多くをPerlのpack/unpack関数から着想し、他の言語での
同じような機能と比較しながら、しかし、データベースライクな処理に
便利なように、より一般的でより効率が良くなるように実装しました。
これを受けて、最も大きな相違点は、全てのパック可能な値はアンパック
可能で(逆も同様)、パック/アンパックのデフォルトの振る舞いはポートI/Oを
使うので、巨大なファイルを読みながらそこからアンパックすることが
できます。また、テンプレートはディスパッチクロージャとして格納でき、
パック、アンパック、あるいは値のスキップさえも、テンプレートを
パーズし直すことなく行えます。
@c COMMON

@c See also binary.io - Binary I/O for utilities to read and write
@c individual binary values.
@end deftp

@defun pack template list :key output to-string?
@c MOD binary.pack
@c EN
Writes the values in @var{list} to the current output port, according
to the format specified by the string @var{template}.  The template
string is a series of single character codes, optionally followed by a
numeric count (which defaults to 1).
@c JP
@var{list}にある値を、文字列@var{template}で指定されたフォーマットに
したがって、現在の出力ポートに書き出します。テンプレート文字列は、
1文字のコードの連続で、オプションで(デフォルトが1である)カウント用の数字
が続きます。

@c EN
The format characters can generally be divided into string types,
which interpret the count as a string byte size, and object types,
which treat the count as a repetition indicator.  The count may be
specified as the character @code{*}, which means to use the full
size of the string for string types, and use all remaining values for
object types.
@c JP
フォーマット文字は一般的に、カウントを文字のバイト数と解釈する
文字列型と、カウントを繰り返し指示子と解釈するオブジェクト型に
分けられます。カウントは文字@code{*}で指定され、文字列型では
文字列の全体の長さを、オブジェクト型では残りの全ての値を使うことを
意味します。

@c EN
Counts may also be specified as a template enclosed in brackets, which
means the count is the byte size of the enclosed template.  For
example, @code{x[L]} skips a long.
@c JP
カウントは大括弧に囲まれたテンプレートとしても指定でき、その場合
カウントはその大括弧を囲んでいるテンプレートのバイト数を意味します。
例えば、@code{x[L]}はlongをスキップします。

@c EN
The special format character @code{/} may be used to indicate a
structure where the packed data contains a dynamic count followed by
the value itself.  The template is written as
@code{<count-item>/<value-item>}, where @code{<count-item>} is any
template character to be interpreted as a numeric count, and
@code{<value-item>} is any other template character to use this count.
If a normal count is given after @code{<value-item>} it is ignored.
@c JP
特別なフォーマット文字@code{/}は、パックされたデータが、値に続く
動的なカウント分を含むという構造を表すために使われます。
テンプレートは、@code{<count-item>/<value-item>}のように書かれ、
ここでは@code{<count-item>}は数値のカウントと解釈されるいかなる
テンプレート文字、@code{<value-item>}はこのカウントを使ういかなる
他のテンプレート文字です。
@code{<value-item}>の後に通常のカウントが与えられても、無視されます。

@c EN
The format character @code{@@} may be used with a count to pad to an
absolute position since the start of the template.
@c JP
フォーマット文字@code{@@}は、カウントとともに使われ、テンプレートの
最初からの絶対位置までパディングします。

@c EN
Sub-templates may be grouped inside parentheses.  If angle-brackets
are used, then they also behave as group operators but recursively
operate on nested lists.
@c JP
サブテンプレートは、括弧の中にグループ化されます。<>が使われると、
ネストされたリストに再帰的に適用されるグループ化オペレータとしても
振舞います。

@c EN
The string types:
@c JP
文字列型:

@c COMMON
@table @code
@item a
@c EN
An arbitrary incomplete string, null padded.
@c JP
任意の不完全文字列。NULLでパディングされます。
@c COMMON

@item A
@c EN
A text string, space padded.
@c JP
テキスト文字列。空白スペースでパディングされます。
@c COMMON

@item Z
@c EN
A null terminated (ASCIZ) string, null padded.
@c JP
NULL終端(ASCIZ)文字列。NULLでパディングされます。
@c COMMON

@item b
@c EN
A bit string (ascending bit order inside each byte).
@c JP
ビット文字列(それぞれのバイトにおけるビットオーダーは昇順)。
@c COMMON

@item B
@c EN
A bit string (descending bit order inside each byte).
@c JP
ビット文字列(それぞれのバイトにおけるビットオーダーは降順)。
@c COMMON

@item h
@c EN
A hex string (low nybble first).
@c JP
16進文字列(低いニブルが先)。
@c COMMON

@item H
@c EN
A hex string (high nybble first).
@c JP
16進文字列(高いニブルが先)。
@c COMMON
@end table

@c EN
The object types:
@c JP
オブジェクト型:
@c COMMON

@table @code
@item c
@c EN
A signed 8bit integer.
@c JP
符号付き8ビット整数。
@c COMMON

@item C
@c EN
An unsigned 8bit integer.
@c JP
符号なし8ビット整数。
@c COMMON

@item s
@c EN
A signed short (16 bit) value.
@c JP
符号付き16ビット整数。
@c COMMON

@item S
@c EN
An unsigned short (16 bit) value.
@c JP
符号なし16ビット整数。
@c COMMON

@item i
@c EN
A signed integer (>= 32 bit) value.
@c JP
符号付き整数(>= 32ビット)。
@c COMMON

@item I
@c EN
An unsigned integer (>= 32 bit) value.
@c JP
符号なし整数(>= 32ビット)。
@c COMMON

@item l
@c EN
A signed long (32 bit) value.
@c JP
符号付きlong(32ビット)。
@c COMMON

@item L
@c EN
An unsigned long (32 bit) value.
@c JP
符号なしlong(32ビット)。
@c COMMON

@item n, n!
@c EN
An unsigned and signed short (16 bit) in "network" (big-endian) order.
@c JP
ネットワークオーダー(ビッグエンディアン)での符号なし/符号つきshort(16ビット)。
@c COMMON

@item N, N!
@c EN
An unsigned and signed long (32 bit) in "network" (big-endian) order.
@c JP
ネットワークオーダー(ビッグエンディアン)での符号なし/符号つきlong(32ビット)。
@c COMMON

@item v, v!
@c EN
An unsigned and signed short (16 bit) in "VAX" (little-endian) order.
@c JP
VAXオーダー(リトルエンディアン)での符号なし/符号つきshort(16ビット)。
@c COMMON

@item V, V!
@c EN
An unsigned and signed long (32 bit) in "VAX" (little-endian) order.
@c JP
VAXオーダー(リトルエンディアン)での符号なし/符号つきlong(32ビット)。
@c COMMON

@item q
@c EN
A signed quad (64 bit) value.
@c JP
符号付きquad(64ビット)。
@c COMMON

@item Q
@c EN
An unsigned quad (64 bit) value.
@c JP
符号なしquad(64ビット)。
@c COMMON

@item f
@c EN
A single-precision float in the native format.
@c JP
ネイティブ形式の単精度float。
@c COMMON

@item d
@c EN
A double-precision float in the native format.
@c JP
ネイティブ形式の倍精度float。
@c COMMON

@item w
@c EN
A BER compressed integer.  An unsigned integer in base 128, most
significant digit first, where the high bit is set on all but the
final (least significant) byte.  Thus any size integer can be encoded,
but the encoding is efficient and small integers don't take up any
more space than they would in normal char/short/int encodings.
@c JP
BER圧縮された整数。ベース128における符号なし整数で、最も大きな桁が
最初で、高いビットが最後の(一番小さな)バイト以外にセットされる。
したがって、どのような大きさの整数もエンコードできるが、
エンコーディングは効率的で、小さな整数は通常のchar/short/int
エンコーディングの場合よりも占有する空間が少ない。
@c COMMON

@item x
@c EN
A null byte.
@c JP
NULLバイト。
@c COMMON

@item o
@c EN
An sexp, handled with @code{read} and @code{write}.
@c JP
S式。@code{read}と@code{write}で扱われる。
@c COMMON

@end table

@c EN
If the optional keyword @var{:output} is given that port is used
instead of the current output port.  If @var{:to-string?} is given and
true, then pack accumulates and returns the output as a string.

Note that the returned string may be an incomplete string
if the packed string contains a byte sequence invalid as
a character sequence.
@c JP
オプションのキーワード@var{:output}が与えられると、
現在の出力ポートの代わりにそのポートが使われます。
@var{:to-string?}が与えられそれが真である場合は、
パックは蓄積され、その出力は文字列として返ります。
@c COMMON

@example
(pack "CCCC" '(65 66 67 68) :to-string? #t)
 @result{} "ABCD"

(pack "C/a*" '("hello") :to-string? #t)
 @result{} "\x05hello"
@end example
@end defun

@defun unpack template :key :input :from-string
@c MOD binary.pack
@c EN
The complement of pack, unpack reads values from the current input
port assuming they've been packed according to the string template and
returns the values as a list.  unpack accepts the same format strings
as pack.  Further, the following tautology holds:
@c JP
packの逆を行うもので、unpackは現在の入力ポートから、値が文字列の
templateでパックされているものとして読み込み、その値をリストとして
返します。unpackはpackと同じフォーマット文字列を受け付けます。
また、いかなるリスト@var{x}とフォーマット文字列@var{fmt}においても、
次のようなトートロジーが維持されます。
@c COMMON

@example
(equal? x (unpack fmt :from-string (pack fmt x :to-string? #t)))
@end example

@c EN
for any list @var{x} and format string @var{fmt}.  The only exceptions
to this are when the template includes a @code{*} and when the
@code{o} template is used, since Scheme numeric literals cannot be
reliably delimited (though future versions of @code{pack} may
circumvent this by registering a new read syntax).

If the optional keyword @var{:input} is given that port is used
instead of the current input port.  If @var{:from-string} is given,
then pack reads input from that string.
@c JP
ただ一つの例外は、テンプレートが@code{*}を含み、@code{o}テンプレートが
使われている場合です。これは、Schemeの数値リテラルは確実に区切られる
ことができないからです(@code{pack}の将来のバージョンでは、
新しいread構文を登録することによってこれは回避されるでしょう)。

オプションのキーワード@var{:input}が与えられると、現在の入力ポートの
代わりにそのポートが使われます。@var{:from-string}が与えられると、
packはその文字列を入力とします。
@c COMMON

@example
(unpack "CCCC" :from-string "ABCD")
 @result{} '(65 66 67 68)

(unpack "C/a*" :from-string "\x05hello")
 @result{} '("hello")
@end example

@c EN
@emph{Note:} in the current version, @code{@@} in @code{unpack}
template has a bug and does not work as supposed.  It will
be fixed in the future version.
@c JP
@emph{註:} 現在のバージョンには、@code{unpack}のテンプレートの
@code{@@}が想定したように動かないというバグがあります。
将来のバージョンでfixされます。
@c COMMON
@end defun

@defun unpack-skip template :key :input
@c MOD binary.pack
@c EN
unpack-skip is the same as unpack except it does not return the
values.  In some cases, particularly with fixed-size templates, this
can be much more efficient when you just want to skip over a value.
@c JP
unpack-skipは、値を返さないことを除いてunpackと同じです。
いくつかのケースでは、特に固定サイズのテンプレートを使うときには、
単に値を読み飛ばしたいときにより効率的です。
@c COMMON
@end defun

@defun make-packer template
@c MOD binary.pack
@c EN
The low-level interface.  This function returns a dispatch closure
that can be used to pack, unpack and skip over the same cached
template.  The dispatch closure accepts symbol methods as follows:
@c JP
低レベルなインタフェースです。この関数は、pack、unpackやキャッシュ
された同じテンプレートを読み飛ばす時に使われるディスパッチクロージャを
返します。ディスパッチクロージャは、以下のようにシンボルメソッドを
受け付けます。
@c COMMON

@table @code
@item 'pack list
@c EN
pack the items in list to the current output port.
@c JP
listにあるアイテムを、現在の出力ポートへpackします。
@c COMMON

@item 'unpack
@c EN
unpack items from the current input port.
@c JP
現在の入力ポートからアイテムをunpackします。
@c COMMON

@item 'skip
@c EN
skip items from the current input port.
@c JP
現在の入力ポートからのアイテムをスキップします。
@c COMMON

@item 'packer
@c EN
return the cached 'pack closure
@c JP
キャッシュされた'packクロージャを返します。
@c COMMON

@item 'unpacker
@c EN
return the cached 'unpack closure.
@c JP
キャッシュされた'unpackクロージャを返します。
@c COMMON

@item 'skipper
@c EN
return the cached 'skip closure.
@c JP
キャッシュされた'skipクロージャを返します。
@c COMMON

@item 'length
@c EN
return the known fixed length of the template.
@c JP
テンプレートの知られている固定された長さを返します。
@c COMMON

@item 'variable-length?
@c EN
return #t if the template has variable length elements.
@c JP
テンプレートが可変長の要素を持っている場合に#tを返します。
@c COMMON
@end table
@end defun

@c ----------------------------------------------------------------------

@node Running Chibi-scheme test suite, Rational-less arithmetic, Packing binary data, Library modules - Utilities
@section @code{compat.chibi-test} - Running Chibi-scheme test suite
@c NODE Chibi schemeテストの実行, @code{compat.chibi-test} - Chibi schemeテストの実行

@deftp {Module} compat.chibi-test
@mdindex compat.chibi-test
@c EN
Quite a few srfis come with test suites that's to be run with
Chibi Scheme test framework.  This module enables Gauche to run
the test code as is.
@c JP
多くのsrfiには、Chibi Schemeのテストフレームワークで実行できるテストコードが
付いてきます。このモジュールはGaucheでそのテストコードを実行できるようにします。
@c COMMON
@end deftp

@defmac chibi-test code @dots{}
@c EN
Run @var{code} @dots{}, while translating Chibi test framework
to Gauche's.
@c JP
ChibiのテストフレームワークをGaucheのそれに置き換えながら、
@code{code} @dots{}を実行します。
@c COMMON

@c EN
A typical usage is to write a wrapper that includes the original
test code (suppose it's called @file{test-suite.scm}):
@c JP
典型的な使い方は、元のテストコード(@file{test-suite.scm}とします)を
includeするラッパーを書くことです。
@c COMMON

@example
(use gauche.test)
(test-start "running test-suite.scm")
(chibi-test
  (include "test-suite.scm"))
(test-end)
@end example

@c EN
Chibi's test directives are translated to Gauche's test directives
(@pxref{Unit testing}, for Gauche's test framework).
@c JP
Chibiのテストディレクティブは、Gaucheのテストフレームワークのテストディレクティブへと
変換されます(@ref{Unit testing}参照)。
@c COMMON

@c EN
The main thing is that Chibi allows expressions and definitions to
be intermingled within a body, while Gauche only allows all definitions
before expressions within a body.
We expand such body into nested @code{let} by @code{chibi-test} macro.
Chibi test macros (e.g. @code{test-assert}) are defined as local macros
in @code{chibi-test} expansion, which expand into @code{gauche.test}
macros.
@c JP
Chibiはボディ中に式と定義が交互に現れることを許していますが、Gaucheでは
ボディ中で全ての定義が式に先立たねばなりません。そこで、@code{chibi-test}マクロは
@code{code} @dots{}をネストした@code{let}に変換します。
また、Chibiテストマクロ(@code{test-assert}等)は変換後のコードではローカルマクロとして
定義され、そのローカルマクロは@code{gauche.test}マクロへと展開されます。
@c COMMON

@c EN
Note that we ignore @code{use} forms inside @code{chibi-test}; we might
want to use different modules that work better in Gauche.  Necessary
modules need to be @code{use}'d before you call @code{chibi-test}.
@c JP
なお、@code{chibi-test}中の@code{use}フォームは無視されます。
これは、Gaucheで実行するのに別のモジュールを使った方が良い場合があるからです。
必要なモジュールは@code{chibi-test}を呼ぶ前に@code{use}しておいてください。
@c COMMON

@c EN
You may want to check out @file{test/srfi.scm} in Gauche source tree
for the use case.
@c JP
Gaucheのソースツリーの@file{test/srfi.scm}に実際の使用例を見ることができます。
@c COMMON
@end defmac


@c ----------------------------------------------------------------------

@node Rational-less arithmetic, A common job descriptor for control modules, Running Chibi-scheme test suite, Library modules - Utilities
@section @code{compat.norational} - Rational-less arithmetic
@c NODE 有理数のない算術演算, @code{compat.norational} - 有理数のない算術演算

@deftp {Module} compat.norational
@mdindex compat.norational

@c EN
Until release 0.8.7, Gauche didn't have exact rational numbers.
It was able to read the rational number literals such as
@code{2/3}, but they are immediately coerced to inexact real
numbers (except when it represents a whole integer).
And if you divided an exact integer by another exact integer,
the result could be coerced to an inexact real if the result
wasn't a whole integer.
@c JP
リリース 0.8.7 までは、Gauche は正確な有理数をサポートしていませんでし
た。@code{2/3}のような有理数リテラルを読み込むことはできていましたが、
約分して整数になる場合をのぞいては、その場で不正確な実数に変換されてい
ました。正確な整数を正確な整数で割った場合も約分して整数になる場合をの
ぞき、結果は不正確な実数になりました。
@c COMMON

@c EN
As of 0.8.8, this is not the case anymore.  Exact division
always yields exact result, except when the divisor is zero.
@c JP
リリース 0.8.8 ではもうこのようなことはありません。正確な数同士の割り
算の結果は常に正確な数になります。ゼロで割ったときはもちろん例外です。
@c COMMON
@example
(/ 2 3)  @result{} 2/3
(/ 5)    @result{} 1/5
(/ 4 2)  @result{} 2
@end example

@c EN
This is more precise, but has one drawback: exact rational
arithmetic is much slower than the integer and inexact real
arithmetic.  If you inadvertently produce
a rational number in the early stage of calculation, and
continue to apply exact arithmetic, performance would be
degraded miserably.
@c JP
計算は正確な値でできますが、ひとつ欠点もあります。正確有理数演算は整
数演算や不正確実数同士の演算にくらべてはるかに遅いのです。意図せず、計
算の初期段階で有理数を生成してしまうとその後の計算にはすべて正確な演算
が適用されてしまい性能は悲惨なことになります。
@c COMMON

@c EN
The proper way to solve this is to insert @code{exact->inexact}
to appropriate places.  However, to ease the transition, you can
just import this module and the division @code{/} behaves
in the way it used to.
@c JP
この問題を解決する適切は方法は適切な場所に@code{exact->inexact}を挿入
することです。しかし、この変換を簡単におこなうには、このモジュールをイ
ンポートし、割り算に@code{/}を使うだけですみます。
@c COMMON

@example
(use compat.norational)

(/ 2 3)  @result{} 0.6666666666666666
(/ 5)    @result{} 0.2
(/ 4 2)  @result{} 2
@end example

@c EN
The effect is not global, but only to the modules you explicitly
import @code{compat.norational}.
@c JP
効果はグローバルには起こらず、明示的に@code{compat.norational}をインポー
トしたモジュールでのみ有効です。
@c COMMON

@c EN
This module only redefines @code{/}.  So if your code has
exact rational literals, they are treated as exact rationals
rather than coerced to inexact reals.  You should prefix
rational literals with @code{#i} to force Gauche to coerce
them to inexact reals:
@c JP
このモジュールは@code{/}を再定義しているだけです。したがって、コードに
正確な有理数のリテラルが含まれていても、それは不正確な実数に変換される
ことはなく、正確な有理数としてあつかわれます。Gaucheに不正確な実数とし
て有理数リテラルを扱わせるには、@code{#i}という接頭辞を追加しなければ
なりません。
@c COMMON
@example
gosh> 1/3
1/3
gosh> #i1/3
0.3333333333333333
@end example
@end deftp

@c ----------------------------------------------------------------------
@node A common job descriptor for control modules, Thread pools, Rational-less arithmetic, Library modules - Utilities
@section @code{control.job} - A common job descriptor for control modules
@c NODE 制御モジュールのための汎用ジョブ記述子, @code{control.job} - 制御モジュールのための汎用ジョブ記述子

@deftp {Module} control.job
@mdindex control.job
@c EN
This module provides a @code{job} record type, a lightweight
structure to be used in the control flow subsystems
(@code{control.*} modules).
Currently the only user is @code{control.thread-pool}, but
some other modules are planned to use @code{job} records.
@c JP
このモジュールは、制御フローサブシステム(@code{control.*}モジュール)
の中で使う軽量な構造である @code{job} レコード型を提供します。
現在のところ、これを使っているのは@code{control.thread-pool}だけですが、
他にもいくつかのモジュールが@code{job}レコードを使う予定です。
@c COMMON

@c EN
A @code{job} record may be returned to an application
by other @code{control.*} modules so that the application
can keep track of the job.  It's not meant for
general use, however.   An application isn't supposed to
create a new job, or to modify its content; it can just query
the job's properties.
@c JP
@code{control.*}モジュールは、アプリケーションがジョブを追跡できるように
@code{job}レコードを返すことができます。ただし、
これは、アプリケーションが普通に使用するための
ものではありません。アプリケーションが新しいジョブを
作成したり、その内容を変更したりすることは想定されていません;
できるのは、そのジョブの属性について問い合わせることだけです。
@c COMMON

@c EN
In this section we only describe procedures an application
needs to know.  The interface for control subsystems is still
fluid and may be changed as more subsystems are developed.
@c JP
この節では、アプリケーションが知るべき手続きだけを説明します。
制御サブシステムのためのインタフェースは未だ流動的であり、
さらなるサブシステムの開発が進むにつれて、変更されるかもしれません。
@c COMMON

@c EN
Different control flow subsystems may use job structure differently.
This section only describes the common properties.  Check the
individual control flow module to know how to handle returned job
objects.
@c JP
異なる制御フローサブシステムは、ジョブ構造の使い方が異なる
かもしれません。この節では、共通する属性のみを説明します。
返されたジョブオブジェクトの扱い方については、個々の制御フロー
モジュールを調べて下さい。
@c COMMON
@end deftp

@deftp {Record type} job
@c MOD control.job
@c EN
A record type denotes the job.  Applications should treat it
as an opaque structure.
@c JP
ジョブを表すレコード型です。アプリケーションはこれを、不透明(opaque)な
構造として扱うべきです。
@c COMMON
@end deftp

@defun job? obj
@c MOD control.job
@c EN
Returns @code{#t} iff @var{obj} is a job record, @code{#f} otherwise.
@c JP
@var{obj}がジョブレコードだったら@code{#t}を、そうでなければ@code{#f}を返します。
@c COMMON
@end defun

@defun job-status job
@c MOD control.job
@c EN
Returns the status of the job.  It may be either one of the followings.
@c JP
ジョブの状態を返します。ジョブの状態は以下のいずれかになります。
@c COMMON
@table @code
@item #f
@c EN
Newborn or orphaned job.  Usually an application won't see a job
in this status.
@c JP
作成したてか、孤児のジョブです。通常、アプリケーションがジョブの
この状態に遭遇することはありません。
@c COMMON
@item acknowledged
@c EN
A job is recognized by a control flow library, but haven't yet
been run.
@c JP
ジョブは制御フローライブラリによって認識されていますが、まだ
実行されてはいません。
@c COMMON
@item running
@c EN
A job is being processed.
@c JP
ジョブは実行中です。
@c COMMON
@item done
@c EN
A job is finished.  An application can retrieve its result
by @code{job-result}.
@c JP
ジョブは完了しています。アプリケーションはその処理の結果を、
@code{job-result}を使って受け取ることができます。
@c COMMON
@item error
@c EN
A job is terminated by an error.  An application can retrieve the
error causing condition by @code{job-result}.
@c JP
ジョブはエラーで終了しています。アプリケーションはエラーの原因となった
コンディションを、@code{job-result}を使って受け取ることができます。
@c COMMON
@item killed
@c EN
A job is killed by external force.  An application can retrieve the
reason of kill (which is specific to a particular control flow
subsystem) by @code{job-result}.
@c JP
ジョブは外部から殺されています。アプリケーションは殺された理由を、
@code{job-result}を使って受け取ることができます。
どのような理由でジョブが殺されるかは制御フローサブシステムによります。
@c COMMON
@end table
@end defun

@defun job-result job
@c MOD control.job
@c EN
If the job is in @code{done} status, it returns the result of the job.
If the job is in @code{error} status, it returns the condition object
that describes the error.
If the job is in @code{killed} status, it returns an object describing
the reason of kill.  The details of the object depends on a particular
control flow library.
Calling @code{job-result} on a job in any other status may return
anything; you can't rely on the result.
@c JP
与えられたジョブが@code{done}状態だったら、そのジョブの処理結果を返します。
与えられたジョブが@code{error}状態だったら、そのエラーを説明する
コンディションオブジェクトを返します。そのジョブが@code{killed}状態だったら、
殺された理由を説明するオブジェクトを返します。このオブジェクトの詳細は、
実際の制御フローライブラリに依存することになります。これら以外の状態の
ジョブに対して@code{job-result}を読んだ場合、何が返るかはわかりません;
その結果を当てにすることはできません。
@c COMMON
@end defun

@defun job-wait job :optional timeout timeout-val
@c MOD control.job
@c EN
Suspends the calling thread until the job becomes either
@code{done}, @code{error} or @code{killed} status.  If the job
is already in one of those status, it returns immediately.
Returns job's status.
@c JP
与えられたジョブが@code{done}、@code{error}もしくは@code{killed}
状態になるまで、呼び出したスレッドの実行をサスペンドします。
ジョブがすでにこれらの状態であった時は、ただちに制御を戻します。
ジョブの状態が返ります。
@c COMMON

@c EN
If @var{timeout} is given and not @code{#f}, it must be
a valid timeout spec (a @code{<time>} object that represents
an absolute time point, or a real number that represents a
relative time in seconds.)  The meaning of @var{timeout} is
the same as in @code{mutex-unlock!} (@pxref{Synchronization primitives}).
Once the timeout reaches, @code{job-wait} returns no matter
how the job's status is, and returns the value specified
to @var{timeout-val}, which defaults to @code{#f}.
@c JP
@var{timeout}が与えられ、それが@code{#f}ではない場合は、
タイムアウトのスペックとして有効なもの(時間の絶対値を表す
@code{<time>}か、現時点からの相対的な秒数を表す実数)で
なければなりません。@var{timeout}の意味は、@code{mutex-unlock!}
(@pxref{Synchronization primitives})のそれと同じです。
タイムアウトすると、そのジョブの状態が何であれ、
@code{job-wait}は引数@var{timeout-val}として指定された
値を返します。デフォルト値は@code{#f}です。
@c COMMON

@c EN
Depending on the control flow subsystem, jobs created by it
may not be waitable; check out each subsystem's documentation for the details.
@c JP
そのジョブを作成する制御フローサブシステムによっては、
待ち受けできないかもしれません。それぞれのサブシステムの
ドキュメントを調べて詳細を確認してください。
@c COMMON
@end defun

@defun job-acknowledge-time job
@defunx job-start-time job
@defunx job-finish-time job
@c MOD control.job
@c EN
If the control flow subsystem keeps track of timestamps,
these procedure returns the time (in @code{<time>} objects)
when the job is acknowledged, started and finished (either normally,
or abnormally by an error or by being killed).  If the job hasn't
reached to certain status, @code{#f} is returned instead.
@c JP
制御フローサブシステムがジョブのタイムスタンプを記録する場合、
これらの手続きは、そのジョブがサブシステムによって認識された時刻、
開始された時刻、(正常に、あるいはエラーや殺されるなど異常に)
終了した時刻を(@code{<time>}オブジェクトとして)返します。
ジョブがそうした状態に達していない場合は@code{#f}を返します。
@c COMMON

@c EN
If the subsystem does not track timestamps, these procedures
always returns @code{#f}.
@c JP
そのサブシステムがタイムスタンプを記録しない場合、これらの
手続きは常に@code{#f}を返します。
@c COMMON
@end defun

@c ----------------------------------------------------------------------
@node Thread pools, Password hashing, A common job descriptor for control modules, Library modules - Utilities
@section @code{control.thread-pool} - Thread pools
@c NODE スレッドプール, @code{control.thread-pool} - スレッドプール

@deftp {Module} control.thread-pool
@mdindex control.thread-pool
@c EN
Provides thread pools.  Only available when Gauche is compiled
with pthreads support.
@c JP
スレッドプールを提供します。Gaucheがpthreadサポート付きでコンパイルされている
場合にのみ利用可能です。
@c COMMON
@end deftp

@deftp {Class} <thread-pool>
@clindex thread-pool
@c MOD control.thread-pool
@c EN
A class for thread pool objects.   It maintains a set of worker threads, and
let them work on the jobs you ask to do asynchronously.

Currently the size of pool (number of threads) is fixed
and you have to specify it when creating a pool.
In future we might add a feature to grow or shrink the pool.

You can also set maximum backlog of the job queue.  You cannot
put a job when the queue already reaches the max length (see
@code{add-job!} below).
@c JP
スレッドプールオブジェクトのクラスです。ワーカースレッドのセットを保持し、
投入されたジョブを非同期に実行します。

現在の実装では、プールのサイズ (スレッド数) は固定で、プール作成時に
指定しなければなりません。いずれスレッド数を動的に増減させる機能を
追加する予定です。

また、ジョブのキューの最大長を指定することもできます。ジョブのキューが
一杯になると、空きができるまでは新たなジョブを投入することができなくなります
(下記の@code{add-job!}参照)。
@c COMMON
@end deftp


@deftp {Condition type} <thread-pool-shut-down>
@c MOD control.thread-pool
@c EN
A condition indicating that a thread pool is already shut down
by @code{terminate-all!} and no longer accepting new jobs.
Inherits @code{<error>}.  The following slot is provided.
@c JP
スレッドプールが@code{terminate-all!}によって停止され、
新規のジョブを受け付けていないことを示すコンディションです。
@code{<error>}を継承します。次のスロットが提供されます。
@c COMMON

@defivar <thread-pool-shut-down> pool
@c EN
The thread pool object that caused the condition.
@c JP
例外の原因となったスレッドプールオブジェクト
@c COMMON
@end defivar
@end deftp

@defun make-thread-pool size :key (max-backlog 0)
@c MOD control.thread-pool
@c EN
Creates a new thread pool of size @var{size} (the number of
worker threads).  Optionally you can give a nonnegative integer
to the maximum backlog; 0 means unlimited.
@c JP
大きさ(ワーカースレッド数)@var{size}のスレッドプールを作成して返します。
省略可能引数@var{max-backlog}によってジョブのバックログの最大値を
指定することもできます。0を与えた場合(デフォルト)は無制限です。
@c COMMON
@end defun

@defun thread-pool-results pool
@c MOD control.thread-pool
@c EN
When you put a job to a thread pool, you can specify
whether you need to check its result or not.  If you say you need
a result, the terminated job is queued to a @emph{result queue},
an @code{<mt-queue>} object, in the pool.
This procedure returns the pool's result queue.
@xref{Queue}, for the details of @code{<mt-queue>}.
@c JP
ジョブをスレッドプールに投入する際に、ジョブの結果を知る必要があるかどうかを
指定することができます。結果を要求した場合は、終了したジョブレコードが
プール中の結果キュー(@code{<mt-queue>}オブジェクト)にエンキューされます。
この手続きは、プールの結果キューを返します。
@code{<mt-queue>}の詳細については@ref{Queue}を参照してください。
@c COMMON
@end defun

@defun thread-pool-shut-down? pool
@c MOD control.thread-pool
@c EN
Returns @code{#t} if the thread pool is shut down and no longer
accepting new jobs, or @code{#f} otherwise.
@c JP
スレッドプールが停止され、新規のジョブを受け付けていない場合に@code{#t}を、
そうでなければ@code{#f}を返します。
@c COMMON
@end defun

@defun add-job! pool thunk :optional (need-result #f) (timeout #f)
@c MOD control.thread-pool
@c EN
Add a @var{thunk} to be executed in the thread pool @var{pool}.
Returns a @code{job} record (@pxref{A common job descriptor for control modules}).
@c JP
@var{thunk}がスレッドプール@var{pool}のスレッドにより実行されるように設定します。
@code{job}レコードを返します。
(@ref{A common job descriptor for control modules}参照)。
@c COMMON

@c EN
The returned job record is not waitable; if you need to track
its result, you have to give a true value to @var{need-result}
argument.  Then when the job is terminated (either normally or
abnormally) the job is queued to the @code{result-queue} of
the pool, and you can check the queue.   If you don't pass
a true value to @var{need-result}, the job won't be queued
to @code{result-queue} even it is terminated.
@c JP
返される@code{job}レコードはwaitableにはなっていません。結果を知る必要が
ある場合は、省略可能引数@var{need-result}に真の値を渡してください。
そうするとジョブが終了した時点 (正常終了でも異常終了でも) で、
@code{job}レコードがスレッドプールの@code{result-queue}に
入るので、そのキューから結果を受け取ることができます。
@var{need-result}を省略したり偽値を渡した場合は、ジョブが終了しても
@code{job}レコードは@code{result-queue}に入れられません。
@c COMMON

@c EN
The returned job is timestamped.  You can examine acknowledged
time, start time and finish time of the job (if the job hasn't
been started and/or finished, the corresponding timestamp fields
are @code{#f}.)  It's sometimes
handy to find out how long the job was waiting in the
queue and how long it took to run.
@c JP
返される@code{job}レコードにはタイムスタンプが付加され、
受付時間、実行開始時間、実行終了時間が記録されます。
(ジョブがまだ実行されていなかったり、終了されていない場合は、対応する
タイムスタンプは@code{#f}になっています)。
ジョブがどのくらいキューの中で待たされ、どのくらい実行にかかったかを
知るのに便利でしょう。
@c COMMON

@c EN
If the pool has positive @code{max-backlog} value, and it
already has that many jobs to be waiting, then @code{add-job!}
blocks until some jobs are start being executed.
You can give a real number in seconds, or a @code{<time>} object
as an absolute point of time, to the @var{timeout} argument
to set the time limit of blocking.  If timeout is reached,
@code{add-job!} returns @code{#f} without creating any job.
Omitting @var{timeout}
or giving @code{#f} to it sets no timeout.
@c JP
スレッドプールが非負の@code{max-backlog}値を持ち、
既にその数だけジョブが待ち行列に入っている場合は、
@code{add-job!}は待ち行列に空きができるまでブロックします。
@var{timeout}引数に、実数値の秒数、あるいは絶対時刻を指定する@code{<time>}
オブジェクトを渡すことでタイムアウトを指定できます。タイムアウトに
達した場合は、@code{add-job!}はジョブを作らずに@code{#f}を返します。
@var{timeout}引数を省略するか、@code{#f}を渡した場合はタイムアウトが設定されません。
@c COMMON

@c EN
(Note: This behavior is different from 0.9.1, in which @code{add-job!}
didn't take the timeout argument and always behaved as if zero
timeout value was given.  To achieve the same behavior, you have
to give 0 to the @var{timeout} argument explicitly.)
@c JP
(註: この動作は0.9.1から変更されました。0.9.1では、@code{add-job!}は
タイムアウト引数を取らず、常にタイムアウトに0秒が指定されたかのように
振る舞っていました。現在のバージョンで同じ動作をさせるには、@var{timeout}引数
に0を明示的に渡します。)
@c COMMON

@c EN
If the thread pool is shut down, this procedure
raises @code{<thread-pool-shut-down>} condition.
@c JP
スレッドプールが停止していた場合、この手続きは
@code{<thread-pool-shut-down>}コンディションを投げます。
@c COMMON
@end defun

@defun wait-all pool :optional (timeout #f) (check-interval #e5e8)
@c MOD control.thread-pool
@c EN
Wait for the job queue to be empty and
all worker threads to finish.  It is done by polling the
pool's status in every @var{check-interval} nanoseconds.
Returns @code{#t} if all jobs are finished.

You can give a real number in seconds, or a @code{<time>} object
as an absolute point of time, in @var{timeout} optional argument.
When timeout is reached, @code{wait-all} returns @code{#f}.
@c JP
ジョブ待ち行列が空になり、すべての実行中のジョブも終了するまで待ちます。
終了待ちは@var{check-interval}にナノ秒で指定される間隔でスレッドプールを
ポールすることで行われます。すべてのジョブが終了したら@code{#t}を返します。

秒数を表す実数か、絶対時刻を表す@code{<time>}オブジェクトを@var{timeout}
引数に渡すことで、タイムアウトを指定できます。タイムアウトに達した場合は、
@code{wait-all}は@code{#f}を返します。
@c COMMON
@end defun

@defun terminate-all! pool :key (force-timeout #f) (cancel-queued-jobs #f)
@c MOD control.thread-pool
@c EN
Wait for all the queued jobs to be finished, then ask all threads
to terminate.  After calling this procedure, the pool no longer
accepts new jobs.  Calling @code{add-job!} on this module would
raise a @code{<thread-pool-shut-down>} condition.
This is intended to be called when shutting down the application.

By default, this procedure first waits for all queued jobs
to be handled, then tries to terminate threads gracefully.

Giving a true value to the @var{cancel-queued-jobs} argument
immediately cancels queued but not started jobs; the status
of such jobs is set @code{killed}.
It does not cancels already started jobs, though.

If you want to cancel already started jobs,
you can give a timeout value (either @code{<time>} object to
specify absolute point of time, or a real number indicating
relative time in seconds) to the @var{force-timeout} argument.
Once timeout is reached, it forcefully terminates the threads
and the jobs handled at that time are also killed.

Forcing termination of threads is an extreme measure; the terminated
thread may not have a chance to clean up properly.  So it is usually
better to give some time for the thread to finish the executing jobs.
@c JP
投入されたジョブがすべて終了するのを待ち、すべてのスレッドを終了させます。
ひとたびこの手続きを呼ぶと、スレッドプール@var{pool}は新規のジョブを受けつけ
ません。この状態のスレッドプールに対して@code{add-job!}を呼ぶと
@code{<thread-pool-shut-down>}コンディションが投げられます。
この手続きはアプリケーションのシャットダウン時などに呼ばれることを意図しています。

デフォルトでは、この手続きはまずキューに既に投入されたジョブが全て処理されるのを
待ち、それからスレッドを穏やかに終了させます。

真の値を@var{cancel-queued-jobs}引数に与えると、キューに入っているが
まだ開始されていないジョブは直ちにキャンセルされます。それらのジョブの
ステータスには@code{killed}がセットされます。
ただし、既に開始されたジョブについてはキャンセルされません。

既に開始されたジョブも中断したい場合は、
タイムアウト値(秒数を表す実数か、絶対時刻を表す@code{<time>}オブジェクト)を
@var{force-timeout}引数に渡します。
タイムアウトに達した時点で残っているスレッドは強制終了され、実行中のジョブも
キャンセルされます。

スレッドの強制終了は極端な処置です。終了されるスレッドは、適切なクリーンアップを
行う機会も与えられないかもしれません。したがって通常は、
スレッドが処理中のジョブを終わらせるための適切な時間的猶予を与えるのが良いでしょう。
@c COMMON
@end defun

@c ----------------------------------------------------------------------
@node Password hashing, Cache, Thread pools, Library modules - Utilities
@section @code{crypt.bcrypt} - Password hashing
@c NODE パスワードハッシュ, @code{crypt.bcrypt} - パスワードハッシュ

@deftp {Module} crypt.bcrypt
@mdindex crypt.bcrypt
@c EN
This module implements a password hashing algorithm using blowfish,
and compatible to OpenBSD's bcrypt algorithm (version 2a, 2b).
@c JP
このモジュールは、blowfishを使ったパスワードハッシュアルゴリズムを実装します。
OpenBSDのbcryptアルゴリズム(version 2a, 2b)と互換です。
@c COMMON

@c EN
Don't use version ``2a'' for new code. It's vulnerable.
Use version ``2b''.
@c JP
version 2a は脆弱性が発見されているので、新規のコードでは使用しないで
ください。代わりに version 2b を使用して下さい。
@c COMMON

@c EN
The typical usage of this module is simple enough.
To get a new password hash value (e.g. for a new user), pass the
password string to @code{bcrypt-hashpw} as the only argument:
@c JP
典型的な使い方は非常にシンプルです。新しいパスワードハッシュ値を
得たい場合 (例えば新しいユーザのために、など) は、パスワード文字列を
唯一の引数として@code{bcrypt-hashpw}を呼び出してください。
@c COMMON

@example
(bcrypt-hashpw @var{password})
  @result{} @r{hashed-string}
@end example

@c EN
The routine automatically adds a salt value.  The returned hash
string can be stored in the user database.  To check if the given
password matches the stored one, pass the
hashed string as the second argument of @code{bcrypt-hashpw} to
check the password.
@c JP
このルーチンは自動的にソルト値を付加します。戻り値の文字列はそのままユーザ
データベースに格納できます。与えられたパスワードがハッシュ値に一致するか
どうかを調べるには、ハッシュ値そのものを第二引数として@code{bcrypt-hashpw}に
渡します。
@c COMMON

@example
(bcrypt-hashpw @var{password} @var{hashed-string})
  @result{} @r{hashed-string}
@end example

@c EN
If the given password is correct, the returned value should
exactly matches @var{hash-string}.
@c JP
パスワードが正しければ、戻り値は@var{hashed-string}と完全に一致するはずです。
@c COMMON
@end deftp

@defun bcrypt-hashpw password :optional setting
@c MOD crypt.bcrypt
@c EN
Calculates a hash value of @var{password}, using the salt value
and parameters included in @var{setting}.  If @var{setting} is
omitted, a suitable default settings and random salt value is
chosen automatically.

The returned hash value contains the salt value and parameters,
and can be used as @var{setting}.  So, to check the password
against existing hash value, just pass the hash value to
@var{setting}; if the password is correct, the returned hash value
should match the one you passed in.

The bcrypt algorithm supports up to 72 octets for the password.

To tweak parameters when you calculate a new hash value,
use @code{bcrypt-gensalt} below to get the initial @var{setting}
value.
@c JP
@var{password}のハッシュ値を計算します。@var{setting}は
ソルト値とパラメータを指定する文字列です。@var{setting}が
省略された場合は、適切なデフォルトのパラメータとランダムなソルト値が
自動的に選択されます。

戻り値のハッシュ値文字列にはソルト値とパラメータが含まれているので、
それを再び@var{setting}に渡すことができます。したがって、パスワードを
既存のハッシュ値に一致するかチェックしたい場合は、ハッシュ値を@var{setting}に渡し、
戻ってきた文字列が渡したハッシュ値と一致するかを見れば良いことになります。

bcryptアルゴリズムは最大72オクテットまでのパスワードを使えます。

新しいハッシュ値を計算する際にパラメータを指定したい場合は、次に説明する
@code{bcrypt-gensalt}を使うと@var{setting}に使える文字列を得ることができます。
@c COMMON
@end defun

@defun bcrypt-gensalt :key prefix count entropy-source
@c MOD crypt.bcrypt
@c EN
Returns a string that contains given parameters and suitable to
pass to the @var{setting} argument of @code{bcrypt-hashpw}.

The @var{prefix} argument specifies the version/scheme of
password hashing.  Currently @code{$2a$} and @code{$2b$} are supported,
which means the blowfish algorithm compatible to bcrypt.
But @code{$2a$} is vulnerable. Use @code{$2b$} for new code.
If you omit @var{prefix}, use @code{$2b$} for default value.

The @var{count} argument specifies the amount of iterations;
the larger the value is, the more time is required to calculate
the hash value.  Note that for the password hashing, taking more
time is actually a good thing, for it works against the dictionary attack.
For normal password checking you need to run the hash routine only
once per login, so it doesn't matter if the calculation takes a fraction
of second.
The bcrypt algorithm iterates @code{(expt 2 @var{count})} times.

The @var{entropy-source} argument is a @code{u8vector} to feed
a random bytes.  For bcrypt algorithm it must be at least 16 octet long.
@c JP
与えられたパラメータを折り込んだ、
@code{bcrypt-hashpw}の@var{setting}引数に使える文字列を返します。

@var{prefix}引数はハッシュ関数およびそのバージョンを指定する文字列です。
現在のところ、@code{bcrypt}互換である@code{$2a$}と@code{$2b$}がサポート
されています。
ただし、@code{$2a$}には脆弱性が発見されていますので、
新規のコードには@code{$2b$}を使用して下さい。
@var{perfix}引数を省略した場合は@code{$2b$}が用いられます。

@var{count}引数はハッシュの繰り返し回数に関係します。大きな値を指定すれば、
ハッシュ値の計算により長い時間がかかります。パスワードハッシュにおいては、
時間をかけた方が良いことに注意してください。一回のハッシュの時間が長くなれば
辞書攻撃への防御になります。一方で、通常のパスワードチェックでは
ログインの度にたかだか一回しはハッシュ関数を呼ばないので、それがたとえコンマ数秒
かかったとしてもたいした負荷ではありません。
bcryptアルゴリズムでは、@code{(expt 2 @var{count})}回ハッシュが繰り返されます。

@var{entropy-source}引数はランダムなバイト列を格納した@code{u8vector}です。
bcryptアルゴリズムでは少なくとも16バイトの長さが必要です。
@c COMMON
@end defun

@c ----------------------------------------------------------------------
@node Cache, Heap, Password hashing, Library modules - Utilities
@section @code{data.cache} - Cache
@c NODE キャッシュ, @code{data.cache} - キャッシュ

@deftp {Module} data.cache
@mdindex data.cache
@c EN
A cache works similarly as a dictionary, associating keys to values,
but its entries may disappear according to the policy of the cache
algorithm.  This module defines
a common protocol for cache datatypes, and also provides several
typical cache implementations.
@c JP
キャッシュは、キーと値を結びつけるという点では辞書と似たように動作しますが、
キャッシュアルゴリズムの方針によってエントリが消去されることがあります。
このモジュールは、キャッシュについて共通のプロトコルを定義し、
またいくつかの典型的なキャッシュの実装を提供します。
@c COMMON
@end deftp

@c EN
@subheading Examples
@c JP
@subheading 例
@c COMMON

@c EN
Let's start from simple examples to get the idea.
@c JP
まず簡単な例によって、どんな具合かを示しましょう。
@c COMMON

@c EN
Suppose you want to read given files and you want to
cache the frequently read ones.  The following code defines
a cached version of @code{file->string}:
@c JP
指定されたファイルを読み込むルーチンに、
頻繁に読むファイルをキャッシュする機能をつけたいとします。
次のコードは@code{file->string}にキャッシュ機能を持たせたものです。
@c COMMON

@example
(use data.cache)
(use file.util)

(define file->string/cached
  (let1 file-cache (make-lru-cache 10 :comparator string-comparator)
    (^[path] (cache-through! file-cache path file->string))))
@end example

@c EN
The procedure closes a variable @code{file-cache},
which is an LRU (least recently used) cache that associates
string pathnames to the file contents.
The actual logic is in @code{cache-through!}, which first consults the
cache if it has an entry for the @code{path}.  If the cache has
the entry, its value (the file content) is returned.  If not,
it calls @code{file->string} with the @var{path} to fetch the file content,
register it to the cache, and return it.  The capacity of cache is
set to 10 (the first argument of @code{make-lru-cache}), so when the
11th file is read, the least recently used file will be purged from the
cache.
@c JP
この手続きは@code{file-cache}変数をクロージャの中に綴じ込んでいます。
その値は文字列のパス名とファイルの中身を結びつけるLRU(least recently used)キャッシュです。
キャッシュの動作は@code{cache-through!}で実現されています。
この手続きは、
まず@var{path}をキーとして持つエントリが@code{file-cache}にあるかどうか調べます。
そのキーを持つエントリがキャッシュ中にあればその値(ファイルの中身)が返されます。
キャッシュ中に無ければ、@code{file->string}が@var{path}を引数として呼ばれ、
それが返したファイルの中身がキャッシュに登録され、返されます。
キャッシュの容量は@code{make-lru-cache}の第1引数で指定され、ここでは10になっています。
つまり、11個目のファイルが読まれた時に、一番長く使われていない
(least recently used)ファイルがキャッシュから消去されます。
@c COMMON

@c EN
The effect of cache isn't very visible in the above example.  You
can insert some print stubs to see the cache is actually in action,
as the following example.
Try read various files using @code{file->string/cached}.
@c JP
上の例そのままではキャッシュの効果が見え辛いです。
次の例の通り、printスタブをいれて、いろいろなファイルを
@code{file->string/cached}で読んでみて下さい。
いつキャッシュが実際にファイルの中身を取りにゆくかわかるでしょう。
@c COMMON

@example
(define file->string/cached
  (let1 file-cache (make-lru-cache 10 :comparator string-comparator)
    (^[path]
      (print #"file->string/cached called on ~path")
      (cache-through! file-cache path
                      (^[path]
                        (print #"cache miss.  fetching ~path")
                        (file->string path))))))
@end example

@c EN
Caveat: A cache itself isn't MT-safe.  If you are using it in
multithreaded programs, you have to wrap it with an atom
(@pxref{Synchronization primitives}):
@c JP
注意: キャッシュ自身はスレッドセーフではありません。
マルチスレッドプログラムでキャッシュを使う場合は、キャッシュをatomでラップしてください。
@c COMMON

@example
(use data.cache)
(use file.util)
(use gauche.threads)

(define file->string/cached
  (let1 file-cache (atom (make-lru-cache 10 :comparator string-comparator))
    (^[path]
      (atomic file-cache (cut cache-through! <> path file->string)))))
@end example

@c EN
@subheading Common properties of caches
@c JP
@subheading キャッシュに共通の性質
@c COMMON

@c EN
A cache of any kind has a comparator and a storage.
The comparator is used to compare keys; in the example above,
we use @code{string-comparator} to compare string pathnames
(@pxref{Basic comparators}, for more about comparators).
@c JP
どんなキャッシュにも、比較器とストレージがあります。
比較器はキーを比較するのに使われます。上の例ではパス名を比較するために
@code{string-comparator}を渡しています
比較器について詳しくは@ref{Basic comparators}を参照してください。
@c COMMON

@c EN
The storage is a dictionary that maps keys to internal
structures of the cache.  By default, a hashtable is
created automatically using the given comparator (or,
if a comparator is omitted, using @code{default-comparator}).
The comparator must have hash function.
@c JP
ストレージは、キーとキャッシュ内部の構造とをマッピングする辞書です。
デフォルトでは与えられた比較器を使うハッシュテーブルが使われるので、
比較器はハッシュ関数を持っていなければなりません。
比較器が省略された場合は@code{default-comparator}が使われます。
@c COMMON

@c EN
Alternatively, you can give a pre-filled dictionary
(copied from another instance of the same kind of cache) 
to start cache with some data already in it.  Note that
what the cache keeps in the dictionary totally depends on the
cache algorithm, so you can't just pass a random dictionary;
it has to be created by the same kind of cache.
If you pass in the storage, the comparator is taken from it.
@c JP
あるいは、
(同じ種類のキャッシュからコピーされた)辞書をストレージとして渡すことで、
既にエントリがある状態のキャッシュを作ることもできます。
キャッシュが辞書に登録している構造はキャッシュアルゴリズムごとに異なるので、
何でも辞書を渡せるわけではないことに注意してください。
同じ種類のキャッシュによって作られた辞書しか渡せません。
ストレージとなる辞書を渡した場合、比較器はその辞書から取られます。
@c COMMON

@c EN
Thus, the cache constructors uniformly take keyword arguments
@var{comparator} and @var{storage}; you can specify either one,
or omit both to use the defaults.
@c JP
従ってキャッシュのコンストラクタは共通して@var{comparator}と@var{storage}の
キーワード引数を取ります。デフォルトの動作で良ければ、
どちらかひとつ、あるいは両方とも省略することができます。
@c COMMON

@c EN
@subheading Predefined caches
@c JP
@subheading 定義済みのキャッシュ
@c COMMON

@c EN
For the @var{storage} and @var{comparator} keyword arguments, see above.
@c JP
@var{storage}と@var{comparator}キーワード引数については上の節を参照してください。
@c COMMON

@defun make-fifo-cache capacity :key storage comparator
@c MOD data.cache
@c EN
Creates and returns a FIFO (first-in, first-out) cache that can
hold up to @var{capacity} entries.
If the number of entries exceeds @var{capacity}, the oldest entry
is removed.
@c JP
@var{capacity}個までのエントリを保持できる、FIFO(先入れ先出し)キャッシュを作って返します。
エントリ数が@var{capacity}を越えそうになった場合、一番古いものから削除されます。
@c COMMON
@end defun

@defun make-lru-cache capacity :key storage comparator
@c MOD data.cache
@c EN
Creates and returns an LRU (least recently used) cache that can
hold up to @var{capacity} entries.
If the number of entries exceeds @var{capacity}, the least recently used
entry is removed.
@c JP
@var{capacity}個までのエントリを保持できる、
LRU(least recently used)キャッシュを作って返します。
エントリ数が@var{capacity}を越えそうになった場合、一番長く使われなかったものから削除されます。
@c COMMON
@end defun

@defun make-ttl-cache timeout :key storage comparator timestamper
@c MOD data.cache
@c EN
Creates and returns a TTL (time to live) cache with the timeout value
@var{timeout}.
Each entry is timestamped when it's inserted, and it is removed
when the current time passes @var{timeout} unit from the timestamp.
The actual entry removal is done when the cache is accessed.
@c JP
タイムアウト値@var{timeout}を持つTTL(生存時間)キャッシュを作って返します。
各エントリには、挿入された時間が記録されます。@var{timeout}を経過したエントリは削除されます。
実際の削除は、キャッシュがアクセスされた時に行われます。
@c COMMON

@c EN
By default, the Unix system time (seconds from Epoch) is used
as a timestamp, and @var{timeout} is in seconds.  It may not be
fine-grained enough if you add multiple entries in shorter intervals
than seconds.   You can customize
it by giving a thunk to @var{timestamper}; the thunk is called to
obtain a timestamp, which can be any monotonically increasing real number
(it doesn't need to be associated with physical time).
If you give @var{timestamper}, the unit of @var{timeout} value should
be the same as whatever @var{timestamper} returns.
@c JP
デフォルトではUnixシステム時間(Epochからの秒数)がタイムスタンプに使われます。
1秒より短い間隔でたくさんのエントリが追加される場合にはこれでは分解能が足りないかもしれません。
@var{timestamper}にサンクを与えることで、タイムスタンプをカスタマイズすることができます。
キャッシュは時刻が必要になる度に@var{timestamper}を引数無しで呼び出します。
@var{timestamper}は単調非減少な実数を返さねばなりません(物理的な時間と結びついている必要は
ありません)。
@var{timestamper}を与えた場合、@var{timeout}引数の単位は
@var{timestamper}が返す値の単位と同じでなければなりません。
@c COMMON
@end defun

@defun make-ttlr-cache timeout :key storage comparator timestamper
@c MOD data.cache
@c EN
A variation of TTL cache, but the entry's timestamp is updated
(refreshed) whenever the entry is read.  Hence we call it TTL with refresh
(TTLR).  But you can also think it as a variation of LRU cache with
timeout.
@c JP
TTLキャッシュのバリエーションで、エントリは書き込まれた時だけでなく、
読み出された時にもタイムスタンプが更新されます。
手続きの名前TTLRは、リフレッシュ付きTTL(TTL with refresh)という意味です。
ただ、これをタイムアウト付きLRUキャッシュと見ることもできます。
@c COMMON

@c EN
The unit of timeout, and the role of @var{timestamper} argument, are
the same as @code{make-ttl-cache}.
@c JP
タイムアウトの単位および@var{timestamper}引数の役割については、
@code{make-ttl-cache}と同じです。
@c COMMON
@end defun

@c EN
@subheading Common operations of caches
@c JP
@subheading キャッシュに共通の操作
@c COMMON

@c EN
The following APIs are for the users of a cache.
@c JP
以下のAPIはキャッシュのユーザに向けたものです。
@c COMMON

@defun cache-lookup! cache key :optional default
@c MOD data.cache
@c EN
Look for an entry with @var{key} in @var{cache}, and returns its
value if it exists.  If there's no entry, the procedure returns @var{default}
if it is provided, or throws an error otherwise.

Some types of cache algorithms update @var{cache} by this operation, hence
the bang is in the name.
@c JP
@var{cache}から@var{key}に結びつけられたエントリを探し、見つかれば返します。
エントリが無い場合は、@var{default}が与えられていればそれを返し、
与えられていなければエラーを投げます。

キャッシュアルゴリズムによってはこの操作で@var{cache}がアップデートされる場合があるため、
名前にエクスクラメーションマークがついています。
@c COMMON
@end defun

@defun cache-through! cache key value-fn
@c MOD data.cache
@c EN
Look for an entry with @var{key} in @var{cache}, and returns its
value if it exists.  If there's no entry, a procedure @var{value-fn}
is called with @var{key} as the argument, and its return value
is inserted into @var{cache} and also returned.
@c JP
@var{cache}から@var{key}に結びつけられたエントリを探し、見つかれば返します。
見つからなかった場合、@var{value-fn}が@var{key}を引数として呼び出され、
その結果が@var{cache}に新たなエントリとして追加され、また@code{cache-through!}の
戻り値として返されます。
@c COMMON
@end defun

@deffn {Generic function} cache-write! cache key value
@c MOD data.cache
@c EN
This inserts association of @var{key} and @var{value} into @var{cache}.
If there's already an entry with @var{key}, it is overwritten.
Otherwise a new entry is created.

The same effect can be achieved by calling @code{cache-evict!} then
@code{cache-through!}, but cache algorithms may provide efficient
way through this method.
@c JP
@var{cache}に、@var{key}と@var{value}の関係を追加します。既に@var{key}に
結びつけられたエントリがあった場合は上書きされ、そうでなければ新たなエントリが作られます。

同じ効果は、@code{cache-evict!}を呼んでから@code{cache-through!}を呼ぶことでも
達成できますが、アルゴリズムによっては@code{cache-write!}に対して効率のよい
実装を提供しているかもしれません。
@c COMMON
@end deffn

@deffn {Generic function} cache-evict! cache key
@c MOD data.cache
@c EN
Removes an entry with @var{key} from @var{cache}, if it exists.
@c JP
@var{cache}から@var{key}に結びついたエントリを(もしあれば)削除します。
@c COMMON
@end deffn

@deffn {Generic function} cache-clear! cache
@c MOD data.cache
@c EN
Removes all entries from @var{cache}.
@c JP
@var{cache}内のエントリを全て取り除きます。
@c COMMON
@end deffn

@c EN
@subheading Implementing a cache algorithm
@c JP
@subheading キャッシュアルゴリズムの実装
@c COMMON

@c EN
Each cache algorithm must define a class inheriting @code{<cache>},
and implement the following two essential methods.
The higher-level API calls them.
@c JP
新たなキャッシュアルゴリズムを提供するには、@code{<cache>}を継承したクラスを定義し、
次の二つの必須メソッドを実装します。高レベルAPIはこれらの必須メソッドを呼び出します。
@c COMMON

@deffn {Generic function} cache-check! cache key
@c MOD data.cache
@c EN
Looks for an entry with @var{key} in @var{cache}.
If it exists, returns a pair of @var{key} and the associated value.
Otherwise, returns @code{#f}.  It may update the cache,
for example, the timestamp of the entry for being read.
@c JP
@var{cache}から@var{key}に結びついたエントリを探します。
見つかれば、@var{key}とその値とのペアを、見つからなければ@code{#f}を返します。
この時、必要ならばキャッシュを更新して構いません。
例えば読み出されたエントリのタイムスタンプを更新するなどです。
@c COMMON
@end deffn

@deffn {Generic function} cache-register! cache key value
@c MOD data.cache
@c EN
Add an entry with @var{key} and associated @var{value} into @var{cache}.
This is called after @var{key} is confirmed not being in @var{cache}.
@c JP
@var{cache}に、@var{key}と対応する@var{value}を追加します。
このメソッドは、@var{cache}に@var{key}に対応するエントリが無いことが確認された後で
呼び出されます。
@c COMMON
@end deffn

@c EN
Additionally, the implementation should consider the following points.
@c JP
アルゴリズムの実装は、また以下の点を考慮しなければなりません。
@c COMMON

@itemize @bullet
@item
The initialize method must call @code{next-method} first, which sets up
the @code{comparator} and @code{storage} slots.  You should check
if @code{storage} has pre-filled entries, and if so, set up other
internal structures appropriately.
@item
The default methods of @code{cache-evict!} and @code{cache-clear!} only
takes care of the storage of the cache.  You should implement them
if your auxiliary structure needs to be taken care of.
@item
The default method of @code{cache-write!} is just @code{cache-evict!}
followed by @code{cache-register!}.  You may provide alternative method
if you can do it more efficiently, which is often the case.
@end itemize

There are several procedures that help implementing cache subclasses:

@defun cache-comparator cache
@defunx cache-storage cache
@c MOD data.cache
Returns the comparator and the storage of the cache, respectively.
@end defun

Typical caches may be constructed with a storage (dictionary) and
a queue, where the storage maps keys to @code{(<n> . <value>)},
and queues holds @code{(<key> . <n>)}, @code{<n>} being a number
(timestamp, counter, etc.)  Here are some common operations work
on this queue-and-dictionary scheme:

@defun cache-populate-queue! queue storage
@c MOD data.cache
You can call this in the @code{initialize} method to set up the
queue.  This procedure walks storage to construct @code{(<key> . <n>)}
pairs, sorts it in increasing order of @code{<n>}, and pushes them
into the queue.
@end defun

@defun cache-compact-queue! queue storage
@c MOD data.cache
The queue may contain multiple pairs with the same key.  Sometimes the
queue gets to have too many duplicated entries (e.g. the same entry
is read repeatedly).  This scans the queue and removes duplicated entries
but the up-to-date one.  After this operation, the length of the queue
and the number of entries in the storage should match.
@end defun

@defun cache-renumber-entries! queue storage
@c MOD data.cache
This procedure renumbers @code{<n>}s in the queue and the storage
starting from 0, without changing their order, and returns the
maximum @code{<n>}.  The duplicated entries in the queue is removed
as in @code{cache-compact-queue!}.

When you're using monotonically increasing counter for @code{<n>} and
you don't want @code{<n>} to get too big (i.e. bignums), you can
call this procedure occasionally to keep @code{<n>}'s in reasonable
range.
@end defun


@c ----------------------------------------------------------------------
@node Heap, Immutable deques, Cache, Library modules - Utilities
@section @code{data.heap} - Heap
@c NODE ヒープ, @code{data.heap} - ヒープ

@deftp {Module} data.heap
@mdindex data.heap
@c EN
A heap is a data container that allows efficient retrieval of
the minimum or maximum entry.  Unlike a @code{<tree-map>}
(@pxref{Treemaps}), which always keeps all entries in order,
a heap only cares the minimum or the maximum of the current set;
the other entries are only partially ordered, and reordered
when the minimu/maximum entry is removed.  Hence it is more
efficient than a treemap if all you need is minimum/maximum value.
Besides binary heaps can store entries in packed, memory-efficient way.
@c JP
ヒープは最小値また最大値を効率よく取り出せるデータコンテナです。
@code{<tree-map>}は全てのエントリの順序を常に保っていますが (@ref{Treemaps}参照)、
ヒープは最小値/最大値以外については部分的にしか順序を保持していません。
最小値/最大値が取り除かれる時点で内部を再構成して、次の最小値/最大値を見つけます。
したがって、最小値/最大値のみが必要な場合、treemapより効率が良いです。
さらに、バイナリヒープでは値をメモリ効率の良い詰められた形で保持できます。
@c COMMON
@end deftp

@deftp {Class} <binary-heap>
@clindex binary-heap
@c MOD data.heap
@c EN
An implementation of a binary heap.  Internally it uses min-max heap,
so that you can find both minimum and maximum value in O(1).
Pushing a new value and popping the minimum/maximum value are both O(log n).

It also stores its values in a flat vector, a lot more compact
than a general tree structure that needs a few pointers per node.
By default it uses a sparse vector for the backing storage, allowing
virtually unlimited capacity (@pxref{Sparse vectors}).
But you can use an ordinal vector
or a uniform vector as a backing storage instead.
@c JP
バイナリヒープの実装です。内部的にmin-maxヒープを使っており、
最大値と最小値のどちらにもO(1)でアクセスできます。新たな値をpushしたり、
最大最小値をpopするのはO(log n)です。

バイナリヒープはまた、値をフラットなベクタに格納します。一般的なツリー構造が
ノードあたりいくつかのポインタを必要とするのに比べずっとコンパクトです。
デフォルトでは疎なベクタ (@ref{Sparse vectors}) がバッキングストレージとして使われ、
事実上上限なしでデータを格納できますが、通常のベクタやユニフォームベクタを
バッキングストレージとして指定することもできます。
@c COMMON

@c EN
A binary heap isn't MT-safe structure; you must put it in atom
or use mutexes if multiple threads can access to it
(@pxref{Synchronization primitives}).
@c JP
バイナリヒープはスレッドセーフではありません。複数のスレッドでアクセスする
可能性がある場合は、atomに入れるか、mutexを適切に使ってください(@ref{Synchronization primitives}参照)。
@c COMMON
@end deftp

@defun make-binary-heap :key comparator storage key
@c MOD data.heap
@c EN
Creates and returns a new binary heap.

The @var{comparator} keyword argument specifies how to compare the
entries.  It must have comparison procedure or ordering predicate.
The default is @code{default-comparator}.
@xref{Basic comparators}, for the details of comparators.

The @var{storage} keyword argument gives alternative
backing storage.  It must be either a vector, a uniform vector,
or an instance of a sparse vector (@pxref{Sparse vectors}).
The default is an instance of @code{<sparse-vector>}.
If you pass a vector or a uniform vector, it determines
the maximum number of elements the heap can hold.
The heap won't be extend the storage once it gets full.

The @var{key} keyword argument must be a procedure; it is applied
on each entry before comparison.  Using key procedure allows you to
store auxiliary data other than the actual value to be compared.
The following example shows the entries are compared by their @code{car}'s:
@c JP
新しいバイナリヒープを作って返します。

@var{comparator}キーワード引数は、エントリの比較方法を指定する比較器です。
比較手続きを持っていなければなりません。省略時は@code{default-comparator}が
使われます。比較器について詳しくは@ref{Basic comparators}を参照してください。

@var{storage}キーワード引数には、データの格納に使うデータ構造を渡します。引数は
ベクタ、ユニフォームベクタ、あるいは疎ベクタ(@ref{Sparse vectors}参照)の
インスタンスでなければなりません。省略時は@code{<sparse-vector>}の
インスタンスが使われます。

ベクタまたはユニフォームベクタを渡した場合、そのベクタの大きさが
ヒープが格納できる要素の最大数を決めます。
それが一杯になった時に自動的に拡張されることはありません。

@var{key}キーワード引数は手続きでなければならず、要素の比較の前に各要素に適用されます。
この手続きを使って、実際に比較される値に付随するデータを格納しておくことができます。
次の例では、データの@code{car}を使って比較しています。
@c COMMON

@example
(define *heap* (make-binary-heap :key car))
(binary-heap-push! *heap* (cons 1 'a))
(binary-heap-push! *heap* (cons 3 'b))
(binary-heap-push! *heap* (cons 1 'c))

(binary-heap-find-min *heap*) @result{} (1 . c)
(binary-heap-find-max *heap*) @result{} (3 . b)
@end example
@end defun

@defun build-binary-heap storage :key comparator key num-entries
@c MOD data.heap
@c EN
Create a heap from the data in @var{storage}, and returns it.
(Sometimes this operation is called @emph{heapify}.)
This allows you to create a heap without allocating a new storage.
The @var{comparator} and @var{key} arguments are the same as
@code{make-binary-heap}.

@var{Storage} must be either a vector, a uniform vector,
or an instance of a sparse vector.  The storage is modified
to satisfy the heap property, and will be used as the backing
storage of the created heap.  Since the storage will be owned
by the heap, you shouldn't modify the storage later.

The storage supposed to have keys from index 0 below
@var{num-entries}.
If @var{num-entries} is omitted or @code{#f}, entire vector or
uniform vector, or up to @code{sparse-vector-num-entries} on
the sparse vector, is heapified.
@c JP
@var{storage}に入っているデータを使ってヒープを作り返します。
(この操作はしばしばヒープ化(@emph{heapify})と呼ばれます。)
データ格納場所を新たにアロケートせずにヒープを作ることが可能です。
@var{comparator}および@var{key}引数は@code{make-binary-heap}と同じです。

@var{storage}はベクタ、ユニフォームベクタ、疎ベクタのインスタンスでなければ
なりません。このデータはヒープの属性を満たすために変更され、さらには
作られたヒープのデータ格納場所となります。ヒープの一部になるので、
@var{storage}を後から変更してはなりません。

@var{storage}の要素のうち、先頭から@var{num-entries}までの要素が
有効であるとしてヒープ化されます。@var{num-entries}が省略されるか
@code{#f}であれば、ベクタおよびユニフォームベクタはその全てが、
疎ベクタは@code{sparse-vector-num-entries}までの要素がヒープ化されます。
@c COMMON
@end defun

@defun binary-heap-copy heap
@c MOD data.heap
@c EN
Copy the heap.  The backing storage is also copied.
@c JP
ヒープをコピーして返します。データ格納場所も全てコピーされます。
@c COMMON
@end defun

@defun binary-heap-clear! heap
@c MOD data.heap
@c EN
Empty the heap.
@c JP
ヒープを空にします。
@c COMMON
@end defun

@defun binary-heap-num-entries heap
@c MOD data.heap
@c EN
Returns the current number of entries in the heap.
@c JP
ヒープ中の要素数を返します。
@c COMMON
@end defun

@defun binary-heap-empty? heap
@c MOD data.heap
@c EN
Returns @code{#t} if the heap is empty, @code{#f} otherwise.
@c JP
ヒープが空なら@code{#t}を、そうでなければ@code{#f}を返します。
@c COMMON
@end defun

@defun binary-heap-push! heap item
@c MOD data.heap
@c EN
Insert @var{item} into the @var{heap}.  This is O(log n) operation.
If the heap is already full, an error is raised.
@c JP
@var{item}を@var{heap}に挿入します。O(log n)の操作です。
ヒープが既に一杯であった場合はエラーが通知されます。
@c COMMON
@end defun

@defun binary-heap-find-min heap :optional fallback
@defunx binary-heap-find-max heap :optional fallback
@c MOD data.heap
@c EN
Returns the minimum and maximum entry of the heap, respectively.
The heap will be unmodified.  This is O(1) operation.

If the heap is empty, @var{fallback} is returned when it is provided,
or an error is signaled.
@c JP
それぞれヒープ中の最小および最大の要素を返します。O(1)の操作です。
ヒープ自体は変更されません。

ヒープが空の場合、@var{fallback}が与えられればそれが返され、
そうでなければエラーが通知されます。
@c COMMON
@end defun

@defun binary-heap-pop-min! heap
@defunx binary-heap-pop-max! heap
@c MOD data.heap
@c EN
Removes the minimum and maximum entry of the heap and returns it,
respectively.  O(log n) operation.
If the heap is empty, an error is signaled.
@c JP
それぞれヒープから最小および最大の要素を取り除き、取り除いた要素を返します。
O(log n)の操作です。
ヒープが空ならエラーが通知されます。
@c COMMON
@end defun

@c EN
The following procedures are not heap operations, but provided
for the convenience.
@c JP
以下の手続きは一般的なデータ構造としてのヒープの操作には含まれませんが、
便利なので用意してあります。
@c COMMON

@defun binary-heap-swap-min! heap item
@defunx binary-heap-swap-max! heap item
@c MOD data.heap
@c EN
These are operationally equivalent to the followings, respectively:
@c JP
これらはそれぞれ以下のコードと操作的には等価です。
@c COMMON

@example
(begin0 (binary-heap-pop-min! heap)
  (binary-heap-push! heap item))

(begin0 (binary-heap-pop-max! heap)
  (binary-heap-push! heap item))
@end example

@c EN
However, those procedures are slightly efficient, 
using heap property maintaining procedure only once per function call.
@c JP
ただしこれらの手続きは、
ヒープ特性を維持するための手続きを呼び出し毎に1回しか行わないので、
やや効率的です。
@c COMMON
@end defun



@defun binary-heap-find heap pred
@c MOD data.heap
@c EN
Returns an item in the heap that satisfies @var{pred}.
If there are more than one item that satisfy @var{pred},
any one of them can be returned.  If no item satisfy @var{pred},
@code{#f} is returned.  This is O(n) operation.
@c JP
ヒープの中で、述語@var{pred}を満たす要素を返します。@var{pred}を満たす要素が
複数ある場合にどれが返るかは不定です。@var{pred}を満たす要素が無ければ
@code{#f}が返ります。O(n)の操作です。
@c COMMON
@end defun

@defun binary-heap-remove! heap pred
@c MOD data.heap
@c EN
Remove all items in the heap that satisfy @var{pred}.  This is O(n) operation.
@c JP
@var{pred}を満たす要素を全てヒープから取り除きます。O(n)の操作です。
@c COMMON
@end defun

@defun binary-heap-delete! heap item
@c MOD data.heap
@c EN
Delete all items in the heap that are equal to @var{item},
in terms of the heap's comparator and key procedure.  This is O(n) operation.

Note that the key procedure is applied to @var{item} as well
before comparison.
@c JP
@var{item}に等しい要素を全てヒープから取り除きます。「等しい」の判定には
ヒープの比較器およびキー手続きが使われます。O(n)の操作です。

キー手続きは、比較の前に@var{item}にも適用されます。
@c COMMON
@end defun

@c ----------------------------------------------------------------------
@node Immutable deques, Immutable map, Heap, Library modules - Utilities
@section @code{data.ideque} - Immutable deques
@c NODE 変更不可な両端キュー, @code{data.ideque} - 変更不可な両端キュー

@deftp {Module} data.ideque
@mdindex data.ideque
This module provides a functional double-ended queue (deque, 
pronounced as ``deck'').

Almost all procedures in this module are now a part of R7RS large.
@xref{R7RS immutable deques}, for description of the following
procedures:

@example
ideque               ideque-unfold        ideque-unfold-right
ideque-tabulate      ideque?              ideque-empty?
ideque-add-front     ideque-add-back
ideque-remove-front  ideque-remove-back
ideque-front         ideque-back
ideque-reverse       ideque=              ideque-ref
ideque-take          ideque-drop
ideque-take-right    ideque-drop-right
ideque-split-at      ideque-append        ideque-zip
ideque-map           ideque-for-each      ideque-for-each-right
ideque-fold          ideque-fold-right    ideque-append-map
ideque-filter        ideque-remove
ideque-find          ideque-find-right
ideque-take-while    ideque-take-while-right
ideque-drop-while    ideque-drop-while-right
ideque-span          ideque-break
ideque-any           ideque-every
ideque->list         list->ideque
ideque->generator    generator->ideque
@end example
@end deftp

@defun make-ideque n :optional init
@c MOD data.ideque
Creates an ideque of length @var{n} with all the elements being
@var{init}.  If @var{init} is omitted, @code{#f} is used.

This is provided just for the symmetry with other container data
structures; it's not in srfi-134, and the portable code can use
@code{ideque-tabulate}.
@end defun


@c ----------------------------------------------------------------------
@node Immutable map, Priority map, Immutable deques, Library modules - Utilities
@section @code{data.imap} - Immutable map
@c NODE 変更不可なマップ, @code{data.imap} - 変更不可なマップ

@deftp {Module} data.imap
@mdindex data.imap
@c EN
This module provides a immutable data structure with O(log n)
access and update operations (here, update means to return a
new structure with requested changes).
The current implementation is
based on the functional red-black tree.
@c JP
このモジュールは、O(log n)でアクセスと更新が可能な、変更不可のデータ構造を
提供します(ここでの「更新」とは、要求された変更を取り込んだ新たな構造を
作って返すことです)。
現在の実装は関数的な赤黒木に基づいています。
@c COMMON
@end deftp

@c EN
Although lists and alists are useful for stack-like immutable
operations, where you can add and remove items to the head of
existing data without modifying them, they require O(n) access time
and sometimes you need better one.  The @code{<imap>} object
provides O(log n) access, in exchange of O(log n) insertion and
deletion.
@c JP
リストや連想リストは、スタック風の変更不可なデータ構造として使えます。
つまり既存のデータ構造自体に変更を加えることなく、その先頭に要素を追加したり、
先頭から要素を取り除いたりできるということです。一方で、リストや連想リストは
任意の要素にアクセスするにはO(n)の時間を必要としますが、もっと速いアクセスが必要な
場合もあります。@code{<imap>}オブジェクトはO(log n)のアクセスを可能にします。
そのかわり、要素の追加や削除にもO(log n)を必要とします。
@c COMMON

@deftp {Class} <imap-meta>
@c MOD data.imap
@c EN
Metaclass of @code{<imap>}.
@c JP
@code{<imap>}のメタクラスです。
@c COMMON
@end deftp

@deftp {Class} <imap>
@c MOD data.imap
@c EN
Immutable map class.  An instance of @code{<imap-meta>}.

Inherits @code{<ordered-dictionary>}, conforms dictionary protocol
except mutating operators (@pxref{Dictionary framework}).
As a sequence, you can access key-value
pairs in increasing order of keys.
@c JP
変更不可なマップのクラスです。@code{<imap-meta>}をメタクラスとします。

@code{<ordered-dictionary>}を継承し、変更操作を除くディクショナリプロトコル
を実装します(@ref{Dictionary framework}参照)。
シーケンスとしてアクセスした場合は、キーと値のペアをキーの昇順に取り出すことができます。
@c COMMON
@end deftp

@defun make-imap
@defunx make-imap comparator
@defunx make-imap key=? key<?
@c MOD data.imap
@c EN
Creates a new empty immutable map.  Without arguments,
@code{default-comparator} is used to compare keys.  To give a
specific comparator, use the second form; the @var{comparator}
argument should have comparison procedure.
For the details of comparators, @pxref{Basic comparators}.
The third form creates a key comparator from a equality
predicate @var{key=?} and less-than predicate @code{key<?},
both must accept two keys.  This interface is consistent with
@code{tree-map} (@pxref{Treemaps}).
@c JP
空の変更不可なマップを新たに作って返します。
引数無しの場合は、キーの比較には@code{default-comparator}が使われます。
キーの比較方法を指定したい場合は、比較手続きを持つ比較器@var{comparator}を
引数に渡してください。比較器については@ref{Basic comparators}を参照。
3番目の呼び出し形式は、キーの等価性を調べる述語@var{key=?}と
大小比較の述語@var{key<?}から比較器を作ります。どちらの述語も
ふたつの引数をとらなければなりません。このインタフェースは
@code{tree-map}との一貫性のためにサポートされています (@ref{Treemaps}参照)。
@c COMMON
@end defun

@defun alist->imap alist
@defunx alist->imap alist comparator
@defunx alist->imap alist key=? key<?
@c MOD data.imap
Creates a new empty immutable map, populates it with
key-value association list @var{alist}, and returns it.
This may be a bit more efficient than creating an empty map with
@code{make-imap} and populates it with @code{imap-put}
one by one.

The @var{comparator} argument specifies how to compare the keys.
It must have comparison procedure.  If omitted, @code{default-comparator}
is used.  @xref{Basic comparators}, for the details.

The third form creates a key comparator from a equality
predicate @var{key=?} and less-than predicate @code{key<=?},
both must accept two keys.

@example
(define m (alist->imap '((a . 1) (b . 2))))

(imap-get m 'a) @result{} 1
(imap-get m 'b) @result{} 2
@end example
@end defun

@defun tree-map->imap tree-map
@c MOD data.imap
Returns a new immutable map with the same content (and the same comparator)
as @var{tree-map}.
@end defun

@defun imap? obj
@c MOD data.imap
Returns @code{#t} if @var{obj} is an immutable map,
@code{#f} otherwise.
@end defun

@defun imap-empty? immap
@c MOD data.imap
Returns @code{#t} if an immutable map @var{immap} is empty,
@code{#f} otherwise.
@end defun

@defun imap-exists? immap key
@c MOD data.imap
Returns @code{#t} if @var{key} exists in an immutable map @var{immap}.
@end defun

@defun imap-get immap key :optional default
@c MOD data.imap
Returns the value associated with @var{key} in an immutable map @var{immap}.
If @var{immap} doesn't have @var{key}, @var{default} is returned
when provided, otherwise an error is signalled.
@end defun

@defun imap-put immap key val
@c MOD data.imap
Returns a new immutable map where association of @var{key} to @var{val}
is added to (or replaced in) an immutable map @var{immap}.
This operation is O(log n).

@example
(define m1 (alist->imap '((a . 1) (b . 2))))

(define m2 (imap-put m1 'a 3))

(imap-get m2 'a)  @result{} 3
(imap-get m1 'a)  @result{} 1  ; not affected
@end example
@end defun

@defun imap-delete immap key
@c MOD data.imap
Returns a new immutable map where @var{key} is removed from
@var{immap}.   If @var{immap} doesn't have @var{key}, returned
map has the same content as @var{immap}.

@example
(define m1 (alist->imap '((a . 1) (b . 2))))

(define m2 (imap-delete m1 'a))

(imap-get m2 'a #f)  @result{} #f
(imap-get m1 'a)     @result{} 1  ; not affected
@end example
@end defun

@defun imap-min immap
@defunx imap-max immap
@c MOD data.imap
Returns a pair of key and value with the minimum or maximum
key in @var{immap}, respectively.  If @var{immap} is empty,
@code{#f} is returned.
@end defun

@c ----------------------------------------------------------------------
@node Priority map, Queue, Immutable map, Library modules - Utilities
@section @code{data.priority-map} - Priority map
@c NODE プライオリティマップ, @code{data.priority-map} - プライオリティマップ

@deftp {Module} data.priority-map
@mdindex data.priority-map
Priority map is a dictionary that can map keys to values, while
the entires are sorted by their @emph{values}.
(If the entires are sorted by keys, it's a treemap--@pxref{Treemaps}).

It is useful when you wanted a sorted sequence, with quick access by
keys that are associated to each value.

Note: If what you need is just a priority queue, you can use
@code{data.heap} (@pxref{Heap}).
@end deftp

@deftp {Class} <priority-map>
@cindex priority-map
@c MOD data.priority-map
Priority map class.  It has no public slots.
Instances of priority maps must be created by
@code{make-priority-map} procedure instead of @code{make} method on
the class.

Inherits @code{<ordered-dictionary>}, and implements dictionary protocol.
Operations concerning
associations of keys and values are done through dictionary generic
functions (@pxref{Generic functions for dictionaries}).

When iterated, it iterates increasing order of values.
@end deftp

@defun make-priority-map :key key-comparator value-comparator
@c MOD data.priority-map
Creates and returns an empty priority map.
It can take @var{key-comparator}, which must have a hash procedure
and is used to hash keys, and
@var{value-comparator}, which must have ordering predicate
and is used to order values.
When omitted, @code{default-comparator} is assumed.
@end defun

@defun priority-map-min pmap
@defunx priority-map-max pmap
@c MOD data.priority-map
Return a pair of a key and a value, where the value is smallest or
largest in the priority map @var{pmap}, respectively.

If @var{pmap} is empty, @code{#f} is returned.

If @var{pmap} has more than one value that are equal to each other
(w.r.t. @var{value-comparator} given to the constructor),
either one of them is picked.
@end defun

@defun priority-map-pop-min! pmap
@defunx priority-map-pop-max! pmap
@c MOD data.priority-map
Remove one entry with the smallest or largest value, respectively,
and returns a pair of the key and the value of removed entry.

If @var{pmap} is empty, @var{#f} is returned.

If @var{pmap} has more than one value that are equal to each other
(w.r.t. @var{value-comparator} given to the constructor),
either one of them is picked.
@end defun

@c ----------------------------------------------------------------------
@node Queue, Random data generators, Priority map, Library modules - Utilities
@section @code{data.queue} - Queue
@c NODE キュー, @code{data.queue} - キュー

@deftp {Module} data.queue
@mdindex data.queue
@c EN
Provides a queue (FIFO).  You can create a simple queue,
which is lightweight but not thread-safe, or an MTqueue,
a thread-safe queue.  Basic queue operations work on
both type of queues.  When an mtqueue is passed to the
procedures listed in this section, each operation is
done in atomic way, unless otherwise noted.

There are also a set of procedures for mtqueues that
can be used for thread synchronization; for example,
you can let the consumer thread block if an
mtqueue is empty, and/or the producer thread block if the number
of items in the mtqueue reaches a specified limit.
Using these procedures allows the program to use an mtqueue
as a @emph{channel}.

The simple queue API is a superset of SLIB's queue implementation,
which supports not only @code{enqueue!} (add item to the end of the sequence)
and @code{dequeue!} (take item from the front of the sequence), but also
@code{queue-push!} (add item to the front of the sequence), so that
it can be used as a stack as well.

If you also want to take item from the end of the sequence in O(1),
you need a deque (double-ended queue).
@xref{Ring buffer}, which works as an efficient (both speed and space)
dequeue on top of vectors.  Or you can use immutable deques
provided by @code{data.ideque} (@pxref{Immutable deques}).

See also @code{scheme.list-queue} (@ref{R7RS list queues}), which defines a
portable API for list-based queue.
@c JP
キュー(FIFO)機能を提供します。
極めて軽量ですがスレッドセーフでないシンプルなキューと、
スレッドセーフなmtqueueがあります。基本的なキュー操作手続きは
どちらのキューに対しても使うことができます。本節で説明されている
手続きをmtqueueに適用した場合、特に断りが無い限り、操作は
アトミックに行われます。

また、スレッド間同期に使えるmtqueue用の手続きも用意されています。
例えばキューが空の時に読み出しスレッドをブロックさせたり
キューの長さが指定値に達した場合に書き込みスレッドをブロックさせることができ、
いわゆる「チャネル」としてキューを使うことができます。

シンプルキューのAPIはSLIBのキュー実装の上位互換になっています。
要素を並びの末尾に追加する@code{enqueue!}と、要素を並びの先頭から取り除く
@code{dequeue!}だけでなく、要素を並びの先頭に追加する@code{queue-push!}も
提供されているので、スタックとしても使えます。

要素を並びの末尾からO(1)で取り除くAPIも欲しい場合は、
deque (double-ended queue)が必要です。@code{data.ring-buffer}モジュール
は、ベクタの上に実装された(空間的にも時間的にも)効率の良いdequeを提供しています
(@ref{Ring buffer}参照)。また、変更不可な両端キュー@code{data.ideque}
もあります(@ref{Immutable deques}参照)。

また、@code{scheme.list-queue}はポータブルなリストベースのキューのAPIを提供しています
(@ref{R7RS list queues})。
@c COMMON
@end deftp

@deftp {Class} <queue>
@clindex queue
@c MOD data.queue
@c EN
A class of simple queue.
@c JP
シンプルなキューのクラスです。
@c COMMON

@defivar {<queue>} length
@c EN
A read-only slot that returns the number of items in the queue.
@c JP
キュー中の要素の数を返す、読み取り専用のスロットです。
@c COMMON
@end defivar
@end deftp

@deftp {Class} <mtqueue>
@c MOD data.queue
@clindex mtqueue
@c EN
A class of mtqueue.  Inherits @code{<queue>}.
@c JP
mtqueueのクラスです。@code{<queue>}を継承しています。
@c COMMON

@defivar {<mtqueue>} max-length
@c EN
The upper bound of the number of items in the queue.
@c JP
キュー中の要素数の上限を示します。
@c COMMON

@c EN
If this slot is zero, the queue cannot hold any items, but
works as a synchronization device.
A writer will block until a reader appears to take the item;
a reader will block until a writer appears to give the item.
@c JP
このスロットが0の場合、キューは要素を中に持つことはできませんが、同期デバイスとして動作します。
書き込みスレッドは、その要素を受け取る読み出しスレッドが現れるまでブロックし、
読み出しスレッドは、要素を渡してくれる書き込みスレッドが現れるまでブロックします。
@c COMMON
@end defivar
@end deftp

@defun make-queue
@c MOD data.queue
@c EN
Creates and returns an empty simple queue.
@c JP
空のシンプルなキューを作って返します。
@c COMMON
@end defun

@defun make-mtqueue :key max-length
@c MOD data.queue
@c EN
Creates and returns an empty mtqueue.  When an integer is given
to the keyword argument @var{max-length}, it is used to
initialize the @code{max-length} slot.
@c JP
空のmtqueueを作って返します。整数が@var{max-length}に与えられた場合は、
それが@code{max-length}スロットの値となります。
@c COMMON
@end defun

@defun queue? obj
@c MOD data.queue
@c EN
Returns @code{#t} if @var{obj} is a queue (either a simple queue
or an mtqueue).
@c JP
@var{obj}がキューであれば(シンプルなキューでもmtqueueでも)@code{#t}を返します。
@c COMMON
@end defun

@defun mtqueue? obj
@c MOD data.queue
@c EN
Returns @code{#t} if @var{obj} is an mtqueue.
@c JP
@var{obj}がmtqueueであれば@code{#t}を返します。
@c COMMON
@end defun

@defun queue-empty? queue
@c MOD data.queue
@c EN
Returns @code{#t} if @var{obj} is an empty queue.
@c JP
@var{obj}が空のキューであれば@code{#t}を返します。
@c COMMON
@end defun

@defun queue-length queue
@c MOD data.queue
@c EN
Returns the number of the items in the queue.
@c JP
キューの中にある要素の数を返します。
@c COMMON
@end defun

@defun mtqueue-max-length mtqueue
@c MOD data.queue
@c EN
Returns the maximum number of items the mtqueue can hold.
If the queue doesn't have a limit, @code{#f} is returned.
@c JP
キューが保持できる要素の最大数を返します。限度がない場合は@code{#f}が返ります。
@c COMMON
@end defun

@defun mtqueue-room mtqueue
@c MOD data.queue
@c EN
Returns the number of elements the mtqueue can accept at this moment
before it hits its maximum length.   For example, if the queue
already has the maximum number of elements, 0 is returned.
If the queue doesn't have the limit, @code{+inf.0} is returned.
@c JP
保持できる最大容量に達するまであといくつ要素を受け入れることができるかを
示す整数を返します。例えば、既にキューがいっぱいであれば0が返ります。
キューに最大容量が設定されていなければ@code{+inf.0}が返ります。
@c COMMON

@c EN
Note that even if this returns a non-zero finite value, subsequent 
@code{enqueue!} may throw an error because of the queue being full.
It's because another thread may put an item to the queue
between this procedure call and @code{enqueue!}.  To avoid
this situation, use @code{enqueue/wait!} to insert item
to mtqueue with finite max-length.
@c JP
この手続きが0以外有限値を返した場合でも、続く@code{enqueue!}の呼び出し時点で
キューがいっぱいになっている可能性があることに注意してください。
この手続きの呼び出しと@code{enqueue!}の
呼び出しの間に、他のスレッドがキューに要素を入れるかもしれないからです。
有限長のmtqueueに確実に要素を挿入したい場合は@code{enqueue/wait!}を使ってください。
@c COMMON
@end defun

@defun mtqueue-num-waiting-readers mtqueue
@c MOD data.queue
@c EN
Returns the number of threads waiting on the mtqueue to read
at this moment. 
The return value is always a nonnegative exact integer.

Note that the value might change between this procedure's returning
the value and your checking it, if some other thread inserts
an element into the queue.  To use the value reliably, you need
another mutex to restrict putting items in the queue.
@c JP
@var{mtqueue}からの読み出しで待っているスレッドの数を返します。
返り値は常に非負の正確な整数です。

この手続きが値を返してからその値を使うまでの間に、別のスレッドが
キューに要素を挿入したら、待っているスレッドの数は変わってしまうことに
注意してください。この手続きの返り値を安全に使うには、
キューに値を挿入する部分を別に排他制御する必要があります。
@c COMMON

@example
(define q (make-mtqueue))

(thread-start! (make-thread (^[] (dequeue/wait! q))))

(mtqueue-num-waiting-readers q) @result{} 1

(enqueue! q 'a)

(mtqueue-num-waiting-readers q) @result{} 0
@end example
@end defun

@defun copy-queue queue
@c MOD data.queue
@c EN
Returns a copy of the queue.
@c JP
キューqueueのコピーを返します。
@c COMMON
@end defun

@defun enqueue! queue obj :optional more-objs @dots{}
@c MOD data.queue
@c EN
Add @var{obj} to the end of @var{queue}.  You may give more than
one object, and each of them are enqueued in order.
@c JP
@var{obj}をキュー@var{queue}の末尾に追加します。
一つ以上の@var{obj}を与えることができ、その場合はそれらが順にenqueueされます。
@c COMMON

@c EN
If @var{queue} is an mtqueue, all the objects are enqueued
atomically; no other objects from other threads can be inserted
between the objects given to a single @code{enqueue!} call.
Besides, if the value of its @code{max-length} slot
has a positive finite value, and adding @var{obj}s makes the number of
elements in @var{queue} exceeds @code{max-length},
an error is signaled and @var{queue} won't be modified.
(If @code{max-length} is zero, this procedure always fail.
Use @code{enqueue/wait!} below.)
@c JP
@var{queue}がmtqueueの場合、渡されたオブジェクト全ての追加は
アトミックに行われます。すなわち、途中に別スレッドが要素を挿入する
ことはありません。さらに、@code{max-length}スロットが正の有限値を
持っており、この@code{enqueue!}の実行によってキューの要素数が
@code{max-length}を越えることになる場合は、@var{queue}は
変更されずエラーとなります。
(@code{max-length}がゼロの場合、この手続きは常にエラーとなります。
下に説明する@code{enqueue/wait!}を使ってください。)
@c COMMON
@end defun

@defun queue-push! queue obj :optional more-objs @dots{}
@c MOD data.queue
@c EN
Add @var{obj} in front of @var{queue}.  You may give more than
one object, and each of them are pushed in order.

Like @code{enqueue!}, when @var{queue} is an mtqueue,
all objects are added atomically, and the value of
@code{max-length} slot is checked.  See @code{enqueue!} above
for the details.
@c JP
@var{obj}をキュー@var{queue}の先頭に追加します。
一つ以上の@var{obj}を与えることができ、その場合はそれらが順にpushされます。

@code{enqueue!}と同様に、@var{queue}がmtqueueの場合は
全てのオブジェクトはアトミックに追加され、また@code{max-length}の値も
チェックされます。詳しくは上の@code{enqueue!}の説明を参照してください。
@c COMMON
@end defun

@defun enqueue-unique! queue eq-proc obj :optional more-objs @dots{}
@defunx queue-push-unique! queue eq-proc obj :optional more-objs @dots{}
@c MOD data.queue
@c EN
Like @code{enqueue!} and @code{queue-push!}, respectively, except that these
don't modify @var{queue} if it already contains @var{obj}
(elements are compared by two-argument procedure @var{eq-proc}).

When @var{queue} is an mtqueue, all objects are added atomically,
and the value of
@code{max-length} slot is checked.  See @code{enqueue!} above
for the details.
@c JP
@var{obj}が既に@var{queue}の中に含まれている場合には@var{queue}を
変更しないことを以外には、@code{enqueue!}および@code{queue-push!}と同じ
動作をします。@var{obj}が含まれているかどうかの検査は
2引数の関数@var{eq-proc}で行います。

@var{queue}がmtqueueの場合は
全てのオブジェクトはアトミックに追加され、また@code{max-length}の値も
チェックされます。詳しくは上の@code{enqueue!}の説明を参照してください。
@c COMMON
@end defun

@defun dequeue! queue :optional fallback
@defunx queue-pop! queue :optional fallback
@c MOD data.queue
@c EN
Take one object from the front of the queue @var{queue} and returns it.
Both function works the same, but @code{queue-pop!} may be used to
emphasize it works with @code{queue-push!}.

If @var{queue} is empty, @var{fallback} is returned if given,
otherwise an error is signaled.

If @var{queue} is an mtqueue and its @code{max-length} is zero,
the queue is always empty.  Use @code{dequeue/wait!} to use
such a queue as an synchronization device.
@c JP
キュー@var{queue}の先頭からひとつ要素を取って返します。
二つの手続きは全く同じ動作をします。@code{queue-pop!}は@code{queue-push!}と
ペアで使われていることを強調したいときに使うと良いでしょう。

キューが空の場合は、@var{fallback}が与えられていればそれが返され、
そうでなければエラーが報告されます。

キューがmtqueueでその@code{max-length}がゼロの場合、
キューは常に空であるとみなされます。ゼロ長のキューを同期デバイスとして
使う場合は@code{dequeue/wait!}を使ってください。
@c COMMON
@end defun

@defun dequeue-all! queue
@c MOD data.queue
@c EN
Returns the whole content of the queue by a list, with emptying
@var{queue}.   If @var{queue} is already empty, returns an empty list.
See also @code{queue->list} below.
@c JP
キューの全ての内容をリストにして返します。キューそのものは空になります。
キューが既に空の場合は空リストが返されます。
下の@code{queue->list}も参照してください。
@c COMMON
@end defun

@defun queue-front queue :optional fallback
@defunx queue-rear queue :optional fallback
@c MOD data.queue
@c EN
Peek the head or the tail of the queue and returns the object, respectively.
The queue itself is not modified.
If @var{queue} is empty, @var{fallback} is returned if it is given,
otherwise an error is signaled.
@c JP
キュー@var{queue}の先頭もしくは末尾の要素を返します。キューそのものは変更されません。
キューが空の場合、@var{fallback}が与えられていればその値を返し、
そうでなければエラーを報告します。
@c COMMON
@end defun

@defun list->queue list :optional class :rest initargs
@c MOD data.queue
@c EN
Returns a new queue whose content is the elements in @var{list},
in the given order.

By default the created queue is a simple queue, but you
can create mtqueue or instances of other subclasses of @code{<queue>}
by giving the class to the optional @var{class} arguments.
The optional @var{initargs} arguments are passed to the constructor
of @var{class}.
@c JP
与えられたリスト@var{list}の各要素をその順で持つようなキューを作成して返します。

デフォルトではシンプルキューが作られますが、@var{class}に@code{<class>}の
サブクラスを渡すことで他のキュークラスのインスタンスを作ることができます。
@var{initargs}は@var{class}のコンストラクタに渡されます。
@c COMMON
@end defun

@defun queue->list queue
@c MOD data.queue
@c EN
Returns a list whose content is the items in the queue in order.
Unlike @code{dequeue-all!}, the content of @var{queue} remains intact.

In Gauche, @code{queue->list} copies the content of the queue to a
freshly allocated list, while @code{dequeue-all!} doesn't copy but
directly returns the queue's internal list.   There are some Scheme
systems that has @code{queue->list} but doesn't guarantee the content
is copied, so if you're planning to share the code among these
implementations, it's better not to rely on the fact that
@code{queue->list} copies the content.
@c JP
キュー@var{queue}の内容をリストにして返します。
@code{dequeue-all!}と異なり、キューそのものの内容は変化しません。

Gaucheでは@code{queue->list}は新しいリストをアロケートしてキューの
内容をコピーします (@code{dequeue-all!}はコピーをせずにキューの内部の
リストをそのまま返します)。組込みで@code{queue->list}を持っているScheme
実装がいくつかありますが、その中には@code{queue->list}がキューの
内容をコピーすることを保証していないものがあるので、それらの処理系と
共有するコードでは@code{queue->list}がリストをコピーすることを
あてにしない方が良いでしょう。
@c COMMON
@end defun

@defun queue-internal-list queue
@c MOD data.queue
@c EN
Like @code{queue->list}, returns a list whose content is the items
in the queue in order, but the returned list @emph{may} share the
internal storage of @var{queue}.  The returned list can be modified
by subsequent operations of @var{queue}, and any modification on the
list can make @var{queue} inconsistent.

Because of this danger, we don't allow @code{<mtqueue>} to be
passed to this procedure; it would signal an error if you do so.

If you just want to extract the accumulated result in @var{queue} without
copying, consider @code{dequeue-all!}, which is safe because it atomically
resets the queue.  Use this procedure only when you absolutely need
to access the contents of the queue without taking them out.
@c JP
@code{queue->list}と同じように、@var{queue}の内容をリストとして返しますが、
そのリストは@var{queue}の内部構造と共有されているかもしれません。
つまり、返されたリストは続く@var{queue}への操作によって変更される可能性があり、
また返されたリストを変更すると@var{queue}の一貫性は失われるでしょう。

この危険性のため、@code{<mtqueue>}をこの手続きに渡すことは禁じられています。
もしそうしたらエラーとなります。

@var{queue}に蓄積されたデータをコピーせずに取り出したいというだけなら、
@code{dequeue-all!}を使ってください。それは取り出すのとキューを空にする
操作をアトミックに行うので安全です。この手続きは、キューの中身を取り出すこと無く
内部にアクセスしたいという場合にだけ使って下さい。
@c COMMON
@end defun

@defun find-in-queue pred queue
@c MOD data.queue
@c EN
Returns the first item in @var{queue} that satisfies a
predicate @var{pred}.  The order of arguments follows
@code{find} (@pxref{Other list procedures}).
@c JP
キュー内の要素のうち述語@var{pred}を満たす最初の要素を返します。
引数の順序は@code{find}に揃えました (@ref{Other list procedures}参照)。
@c COMMON
@end defun

@defun any-in-queue pred queue
@c MOD data.queue
@c EN
Like @code{any} in SRFI-1, apply @var{pred} on each item
in @var{queue} until it evaluates true, and returns that
true value (doesn't necessarily be @code{#t}).  If no
items in the queue satisfies @var{pred}, @code{#f} is returned.
@c JP
SRFI-1の@code{any}のように、@var{queue}中の各要素に
順に@var{pred}を適用し、それが真の値 (@code{#t}である必要はありません) に
評価されたらその値を返します。@var{pred}を満たす要素が無ければ@code{#f}が
返ります。
@c COMMON
@end defun

@defun every-in-queue pred queue
@c MOD data.queue
@c EN
Like @code{every} in SRFI-1, apply @var{pred} on each item
in @var{queue}.  If @var{pred} returns @code{#f}, stops
iteration and returns @code{#f} immediately.
Otherwise, returns the result of the application of
@var{pred} on the last item of the queue.  If the queue
is empty, @code{#t} is returned.
@c JP
SRFI-1の@code{every}のように、@var{queue}中の各要素に
順に@var{pred}を適用し、それが@code{#f}を返したらすぐ@code{#f}を返します。
@var{pred}に対し@code{#f}を返す要素が無ければ、最後の要素に@var{pred}を
適用した結果が返ります。キューが空なら@code{#f}が返ります。
@c COMMON
@end defun

@defun remove-from-queue! pred queue
@c MOD data.queue
@c EN
Removes all items in the queue that satisfies @var{pred}.
Returns @code{#t} if any item is removed.  Otherwise returns @code{#f}.
The order of arguments follows
@code{remove} in @code{scheme.list}
(@pxref{R7RS lists}).
@c JP
キューから、述語@var{pred}を満たす要素を全て取り除きます。
要素が削除された場合は@code{#t}が、そうでなければ@code{#f}が返されます。
引数の順序は@code{scheme.list}
の@code{remove}に揃えました (@ref{R7RS lists}参照)。
@c COMMON
@end defun

@c EN
Note on portability:
Scheme48 has @code{delete-from-queue!}, which takes object to remove
rather than predicate, and also takes arguments in reversed order
(i.e. queue comes first).   Avoid conflicting with that I intentionally
left out @code{delete-from-queue!}; it's easy to write one in either
Scheme48 compatible way or consistent to SRFI-1 argument order.
@c JP
移植性に関する註：Scheme48には、述語ではなく削除するオブジェクトそのものを取る
@code{delete-from-queue!}がありますが、引数の順序が逆(キューが先)になっています。
まぎらわしい衝突を避けるため、敢えて@code{delete-from-queue!}は
提供しませんでした。@code{remove-from-queue!}を使えば、Scheme48互換の方法でも、
あるいはSRFI-1と一貫性のある方法でも@code{delete-from-queue!}を簡単に書けるでしょう。
@c COMMON

@defun enqueue/wait! mtqueue obj :optional timeout timeout-val
@defunx queue-push/wait! mtqueue obj :optional timeout timeout-val
@defunx dequeue/wait! mtqueue :optional timeout timeout-val
@defunx queue-pop/wait! mtqueue :optional timeout timeout-val
@c MOD data.queue
@c EN
These synchronizing variants work on an mtqueue and
make the caller thread block when the mtqueue has reached
its maximum length (for @code{enqueue/wait!} and @code{queue-push/wait!}),
or the mtqueue is empty (for @code{dequeue/wait!} and
@code{queue-pop/wait!}).   The blocked caller thread is unblocked
either when the blocking condition is resolved, or the timeout
condition is met.

The optional @var{timeout} argument specifies the timeout condition.
If it is @code{#f}, those procedures wait indefinitely.
If it is a real number, they wait at least the given number of
seconds.  If it is a @code{<time>} object (@pxref{Time}),
they wait until the absolute point of time the argument specifies.

In case the call is blocked then timed out, the value of
@var{timeout-val} is returned, which defaults to @code{#f}.

When @code{enqueue/wait!} and @code{queue-push/wait!} succeeds
without hitting timeout, they return @code{#t}.
@c JP
これらの手続きは@var{mtqueue}に対して使うことができ、
スレッド間同期を実現できます。
@code{enqueue/wait!}と@code{queue-push/wait!}は、
キューの要素数が@var{max-length}を越える場合に、キューに空きができるまで、
@code{dequeue/wait!}と@code{queue-pop/wait!}は、
キューが空の場合に、キューに要素が追加されるまで、
呼び出しスレッドをブロックします。

@var{timeout}引数で、ブロックされたスレッドのタイムアウトを指定することができます。
@code{#f}は指定しなかった場合と同じで、キューの状態が変化するまで
無期限に待ちます。実数が渡された場合はそれが秒数と解釈され、最低限
その時間経過するまでは待ちます。渡されたのが@code{<time>}オブジェクト
(@ref{Time}参照)である場合は、そのオブジェクトが指定する絶対時刻を
経過するまで待ちます。

タイムアウトによりブロックが解かれた場合は、@var{timeout-val}で
指定した値が返されます。@var{timeout-val}の省略時値は@code{#f}です。

@code{enqueue/wait!}と@code{queue-push/wait!}は、
タイムアウトせずに操作が成功した場合は@code{#t}を返します。
@c COMMON
@end defun



@c ----------------------------------------------------------------------
@node Random data generators, Ring buffer, Queue, Library modules - Utilities
@section @code{data.random} - Random data generators
@c NODE ランダムデータの生成, @code{data.random} - ランダムデータの生成

@deftp {Module} data.random
@mdindex data.random
@c EN
This module defines a set of generators and generator makers
that yield random data of specific type and distribution.
@c JP
このモジュールは、特定のデータ型や、特定の値の分布を持つランダムなデータを
生成するジェネレータ、およびそういったジェネレータを作り出すジェネレータ構築器を
提供します。
@c COMMON
@end deftp

@c EN
A naming convention: Procedures that takes parameters and returns
a generator is suffixed by @code{$} (e.g. @code{integer$}).
Procedures that are generators themselves are not (e.g. @code{fixnums}).
Procedures that are combinators, that is, the ones that take
one or more generators and returns a generator, generally ends
with a preposition (e.g. @code{list-of}).
@c JP
名前付けの規則：パラメータを受け取り、それにそったジェネレータを返す
手続きにはサフィックス@code{$}がついています (例: @code{integer$})。
それ自体がジェネレータである手続きにはサフィックスがつきません (例: @code{fixnums})。
コンビネータ、つまり複数のジェネレータを取ってジェネレータを返す手続きの名前は、
通常前置詞で終わります (例: @code{list-of})。
@c COMMON

@c EN
@subheading Global state
@c JP
@subheading グローバルな状態
@c COMMON

@c EN
All the generators in this module shares a global random state.
The random seed is initialized by a fixed value when the module
is loaded.
You can get and set the random seed by
the following procedure.
@c JP
このモジュールのジェネレータはすべて一つのグローバルな乱数状態を共有します。
モジュールがロードされた時点で、固定のシードによりこの状態は初期化されます。
次の手続きでグローバルな乱数状態のシードを読み出したり、新たな値に
設定することができます。
@c COMMON

@defun random-data-seed
@defunx {(setter random-data-seed)} seed-value
@c MOD data.random
@c EN
Calling @code{random-data-seed} (without arguments)
returns the random seed value used to initialize the current random state.

It can be used with generic setter, to reinitialize the random state
with @var{seed-value}.

Random seed value must be an exact integer.  Its lower 32bits are used.
@c JP
引数無しで@code{random-data-seed}を呼ぶと、現在の乱数状態を初期化した
シード値が返されます。

ジェネリックなセッターと一緒に使えば、乱数状態を@var{seed-value}をシードとして
再初期化することができます。

ランダムシード値は正確な整数でなければなりません。その下位32ビットが使われます。
@c COMMON

@example
; @r{reinitialize the random state with a new random seed.}
(set! (random-data-seed) 1)

(random-data-seed) @result{} 1
@end example

@c EN
Note: This procedure doesn't have parameter interface (alter the global
value by giving the new value as an argument), since it doesn't work
like a parameter (@pxref{Parameters}).
You can get the random seed value, but you can't
get the current random state itself---if you restore the
random seed value again, the internal state is reset, instead
of restoring the state at the time you called @code{random-data-seed}.
@c JP
註: この手続きはパラメータインタフェース (引数として値を与えるとそれを新たな
値に設定し、以前の値を返す) にはなっていません。本質的に、パラメータとは
相容れないからです (@ref{Parameters}参照)。
得られるのは現在の乱数状態の出発点となるシード値であって、
現在の乱数状態そのものではありません。一旦別のシード値に切り替えて、
その後元のシード値に戻した場合、乱数状態は切り替えた時点に戻るのではなく、
あらためて初期化されます。
@c COMMON

@c EN
If you want to use different random state temporarily, and ensure to
restore original state afterwards, use @code{with-random-data-seed} below.
@c JP
乱数状態を一時的に切り替えて、その後で切り替えた時点の状態を確実に回復したい場合は、
次に示す@code{with-random-data-seed}を使ってください。
@c COMMON
@end defun

@defun with-random-data-seed seed thunk
@c MOD data.random
@c EN
Saves the current global random state, initializes the random state with
@var{seed}, then executes @var{thunk}.  If @var{thunk} returns or
the control exits out of @var{thunk}, the state at the time
@code{with-random-data-seed} was called is restored.
@c JP
現在のグローバルな乱数状態を保存し、乱数状態を@var{seed}で初期化して
@var{thunk}を実行します。@var{thunk}から帰ってくるか、
制御が@var{thunk}を抜け出した場合、乱数状態は@code{with-random-data-seed}が
呼び出された時点の状態に戻されます。
@c COMMON
@end defun

@c EN
Since the default random seed value is fixed, you can get deterministic
output when you call the random data generators below without altering
the random seed explicitly.
@c JP
デフォルトのランダムシードが固定なのは、何もしなければ再現可能な振る舞いが得られる
からです。
@c COMMON

@c EN
@subheading Generators of primitive data types
@c JP
@subheading プリミティブデータ型のジェネレータ
@c COMMON

@c EN
Those generators generate uniformly distributed data.
@c JP
以下のジェネレータは特に断りが無い限り、一様分布するデータを生成します。
@c COMMON

@c EN
In the following examples, we use @code{generator->list} to show
some concrete data from the generators.  It is provided
in @code{gauche.generator} module.  @xref{Generators}, for more
utilities work on generators.
@c JP
例の中では、生成された値を具体的に示すために
@code{gauche.generator}モジュールの@code{generator->list}を
使っています。ジェネレータを扱うユーティリティについては
@ref{Generators}を参照してください。
@c COMMON

@defun integers$ size :optional (start 0)
@defunx integers-between$ lower-bound upper-bound
@c MOD data.random
@c EN
Create exact integer generators.  The first one, @code{integers$}, creates
a generator that generates integers from start (inclusive) below
start+size (exclusive) uniformly.  The second one, @code{integers-between$},
creates a generator that generates integers between
@var{lower-bound} and @var{upper-bound} (both inclusive) uniformly.
@c JP
正確な整数のジェネレータを作成します。
@code{integer$}が返すジェネレータは、
@var{start} 以上 @var{start} + @var{size} 未満の整数を一様に発生させます。
@code{integers-between$}はが返すジェネレータは、@var{lower-bound}以上、
@var{upper-bound}以下の整数を一様に発生させます。
@c COMMON

@example
@c EN
;; A dice roller
@c JP
;; サイコロ
@c COMMON
(define dice (integers$ 6 1))

@c EN
;; Roll the dice 10 times
@c JP
;; サイコロを10回振ってみる
@c COMMON
(generator->list dice 10)
 @result{} (6 6 2 4 2 5 5 1 2 2)
@end example
@end defun

@defun fixnums
@defunx int8s
@defunx uint8s
@defunx int16s
@defunx uint16s
@defunx int32s
@defunx uint32s
@defunx int64s
@defunx uint64s
@c MOD data.random
@c EN
Uniform integer generators.  Generate integers in fixnum range, and
8/16/32/64bit signed and unsigned integers, respectively.
@c JP
固定範囲の一様整数ジェネレータです。
それぞれ、fixnumおよび8/16/32/64ビットの符号つき/符号無し整数を生成します。
@c COMMON

@example
(generator->list int8s 10)
 @result{} (20 -101 50 -99 -111 -28 -19 -61 39 110)
@end example
@end defun

@defun booleans
@c MOD data.random
@c EN
Generates boolean values (@code{#f} and @code{#t}) in equal probability.
@c JP
真偽値(@code{#f}と@code{#t})を等確率で生成します。
@c COMMON

@example
(generator->list booleans 10)
 @result{} (#f #f #t #f #f #t #f #f #f #f)
@end example
@end defun

@defun chars$ :optional char-set
@c MOD data.random
@c EN
Creates a generator that generates characters in @var{char-set} uniformly.
The default @var{char-set} is @code{#[A-Za-z0-9]}.
@c JP
@var{char-set}にある文字を一様分布で生成するジェネレータを作ります。
@var{char-set}が省略された場合は@code{#[A-Za-z0-9]}が使われます。
@c COMMON

@example
(define alphanumeric-chars (chars$))

(generator->list alphanumeric-chars 10)
 @result{} (#\f #\m #\3 #\S #\z #\m #\x #\S #\l #\y)
@end example
@end defun

@defun reals$ :optional size start
@defunx reals-between$ lower-bound upper-bound
@c MOD data.random
@c EN
Create a generator that generates real numbers uniformly with given range.
The first procedure, @code{reals$}, returns reals between start
and start+size, inclusively.  The default of size is 1.0 and start is 0.0.
The second procedure, @code{reals-between$}, returns reals between
lower-bound and upper-bound, inclusively.
@c JP
与えられた範囲の実数値を一様に生成するジェネレータを返します。
@code{reals$}の返すジェネレータは、
@var{start} 以上 @var{start} + @var{size} 以下の実数値を生成します。
@var{size}のデフォルト値は@code{1.0}、@var{start}のデフォルト値は@code{0.0}です。
@code{reals-between$}の返すジェネレータは、
@var{lower-bound}以上@var{upper-bound}以下の実数値を生成します。
@c COMMON

@example
(define uniform-100 (reals$ 100))

(generator->list uniform-100 10)
 @result{} (81.67965004942268 81.84927577572596 53.02443813660833)
@end example

@c EN
Note that a generator from @code{reals$} can generate the upper-bound
value start+size, as opposed to @code{integers$}.  If you need to exclude
the bound value, just discard the bound value; @code{gfilter} may come
handy.
@c JP
@code{reals$}の返すジェネレータは、@code{integer$}と違って
上限の値を生成し得ることに注意してください。限界値を除外したい場合は、
@code{gfilter}等を使ってその値を棄却します。
@c COMMON

@example
(define generate-from-0-below-1
  (gfilter (^r (not (= r 1.0))) (reals$ 1.0 0.0)))
@end example
@end defun

@defun samples$ collection
@c MOD data.random
@c EN
Creates a generator that returns randomly chosen item in @var{collection}
at a time.

Do not confuse this with @code{samples-from} below, which is to combine
multiple generators for sampling.
@c JP
コレクション@var{collection}から毎回ランダムにひとつ要素を選んで返すジェネレータを
作成します。

下で説明する@code{samples-from}と混同しないようにしてください。@code{samples-from}
は複数のジェネレータを組み合わせてサンプリングするものです。
@c COMMON

@example
(define coin-toss (samples$ '(head tail)))

(generator->list coin-toss 5)
 @result{} (head tail tail head tail)
@end example
@end defun

@defun regular-string$ regexp
@c MOD data.random
@c EN
Creates an infinite
generator that generates random strings each of which matches the given
@var{regexp}.  The @var{regexp} shouldn't include conditional patterns
and lookahead/behind assertions.

Note: It is hard to define how the distribution of the generated strings
should look like.  For now, we build an NFA from regexp and put the
same probability when there are multiple choices, but that may not be
really useful for typical use cases (e.g. generate test data).
Please assume the current implementation strategy a provisional one.
@c JP
与えられた@var{regexp}にマッチするランダムな文字列を生成し続けるジェネレータを
作って返します。@var{regexp}には条件付きパターン、lookahead/lookbehindアサーションを
含めないでください。

註: 生成される文字列の分布をどうすべきかというのは難しい問題です。
現在の実装は単純に、内部で正規表現からNFAを生成し、複数の選択肢がある場合は
等しい重みでランダムに選択していますが、それが目的(例えばテストデータの生成)に
ふさわしいかどうかはまだわかりません。
現在の実装は暫定的なものと考えてください。
@c COMMON
@end defun

@c EN
@subheading Nonuniform distributions
@c JP
@subheading 非一様分布
@c COMMON

@defun reals-normal$ :optional mean deviation
@c MOD data.random
@c EN
Creates a generator that yields real numbers from normal distribution
with @var{mean} and @var{deviation}.  The default of @var{mean} is 0.0
and @var{deviation} is 1.0.
@c JP
期待値@var{mean}、標準偏差@var{deviation}の正規分布に従って実数値を生成する
ジェネレータを作ります。省略時は@var{mean}が0.0、@var{deviation}が
1.0になります。
@c COMMON
@end defun

@defun reals-exponential$ mean
@c MOD data.random
@c EN
Creates a generator that yields real numbers from exponential distribution
with @var{mean}.
@c JP
期待値@var{mean}の指数分布に従って実数値を生成するジェネレータを作ります。
@c COMMON
@end defun

@defun integers-geometric$ p
@c MOD data.random
@c EN
Creates a generator that yields integers from geometric distribution
with success probability @var{p} (0 <= p <= 1).  The mean is @code{1/p} and
variance is @code{(1-p)/p^2}.
@c JP
成功確率@var{p} (0 ≦ p ≦ 1) である幾何分布に従って
非負整数値を生成するジェネレータを作ります。
期待値は@code{1/p}、分散は@code{(1-p)/p^2}になります。
@c COMMON
@end defun

@defun integers-poisson$ L
@c MOD data.random
@c EN
Creates a generator that yields integers from poisson distribution with
mean @var{L}, variance @var{L}.
@c JP
期待値@var{L}のポアソン分布に従う非負整数値を生成するジェネレータを作ります。
分散も@var{L}になります。
@c COMMON
@end defun

@c EN
@subheading Aggregate data generators
@c JP
@subheading 複合データ型のジェネレータ
@c COMMON

@defun samples-from generators
@c MOD data.random
@c EN
Takes a finite sequence of generators
(sequence in the sense of @code{gauche.sequence}),
and returns a generator.  Every time the resulting generator is called,
it picks one of the input generators in equal probability, then
calls it to get a value.
@c JP
ジェネレータの有限シーケンス (ここでは@code{gauche.sequence}がシーケンスとして
扱うもの) を取り、新たなジェネレータを返します。
返されたジェネレータは、値を必要とする度に、
入力となるジェネレータのどれかを等確率で選んで、その入力ジェネレータから値を取ります。
@c COMMON

@example
(define g (samples-from (list uint8s (chars$ #[a-z]))))

(generator->list g 10)
 @result{} (207 107 #\m #\f 199 #\o #\b 57 #\j #\e)
@end example

@c EN
NB: To create a generator that samples from a fixed collection of items,
use @code{samples$} described above.
@c JP
註: 固定した要素の集まりからサンプルするジェネレータを作るには、
上の方で説明した@code{samples$}を使ってください。
@c COMMON
@end defun

@defun weighted-samples-from weight&gens
@c MOD data.random
@c EN
The argument is a list of pairs of a nonnegative real number and a generator.
The real number determines the weight, or the relative probability
that the generator is chosen.  The sum of weight doesn't need to
be 1.0.
@c JP
引数は、非負の実数値とジェネレータのペアのリストです。
実数値が「重み」、すなわちペアとなっているジェネレータが選ばれる相対確率を決定します。
重みの総和が1.0である必要はありません。
@c COMMON

@c EN
The following example chooses the uint8 generator four times frequently
than the character generator.
@c JP
次の例では、@code{uint8}ジェネレータは文字ジェネレータより4倍頻繁に使われます。
@c COMMON

@example
(define g (weighted-samples-from
           `((4.0 . ,uint8s)
             (1.0 . ,(chars$)))))

(generator->list g 10)
 @result{} (195 97 #\j #\W #\5 72 49 143 19 164)
@end example
@end defun

@defun pairs-of car-gen cdr-gen
@c MOD data.random
@c EN
Returns a generator that yields pairs,
whose car is generated from @var{car-gen}
and whose cdr is generated from @var{cdr-gen}.
@c JP
ペアを生成するジェネレータを作ります。
各ペアのcarはジェネレータ@var{car-gen}、
cdrはジェネレータ@var{cdr-gen}によって生成されます。
@c COMMON

@example
(define g (pairs-of int8s booleans))

(generator->list g 10)
 @result{} ((113 . #t) (101 . #f) (12 . #t) (68 . #f) (-55 . #f))
@end example
@end defun

@defun tuples-of gen @dots{}
@c MOD data.random
@c EN
Returns a generator that yields lists, 
whose i-th element is generated from the i-th argument.
@c JP
リストを生成するジェネレータを作ります。
各リストのi番目の要素はi番目の引数のジェネレータによって生成されます。
@c COMMON

@example
(define g (tuples-of int8s booleans (char$)))

(generator->list g 3)
 @result{} ((-43 #f #\8) (53 #f #\1) (-114 #f #\i))
@end example
@end defun

@defun permutations-of seq
@c MOD data.random
@c EN
Returns a generator that yields a random permutations of @var{seq}.

The type of @var{seq} should be a sequence with a builder
(@pxref{Sequence framework}).  The type of generated objects
will be the same as @var{seq}.
@c JP
シーケンス@var{seq}の要素をランダムに並べ替えたシーケンスを生成する
ジェネレータを作ります。

@var{seq}の型は、ビルダーを持つシーケンスである必要があります
(@ref{Sequence framework}参照)。生成されるオブジェクトは
@var{seq}と同じ型になります。
@c COMMON

@example
(generator->list (permutations-of '(1 2 3)) 3)
 @result{} ((1 2 3) (2 3 1) (3 2 1))

(generator->list (permutations-of "abc") 3)
 @result{} ("cba" "cba" "cab")
@end example
@end defun

@defun combinations-of size seq
@c MOD data.random
@c EN
Returns a generator that yields a sequence of @var{size} elements
randomly picked from @var{seq}.

The type of @var{seq} should be a sequence with a builder
(@pxref{Sequence framework}).  The type of generated objects
will be the same as @var{seq}.
@c JP
シーケンス@var{seq}からランダムに@var{size}個の要素を取り出して
並べたシーケンスを生成するジェネレータを作ります。

@var{seq}の型は、ビルダーを持つシーケンスである必要があります
(@ref{Sequence framework}参照)。生成されるオブジェクトは
@var{seq}と同じ型になります。
@c COMMON

@example
(generator->list (combinations-of 2 '(a b c)) 5)
 @result{} ((a c) (a b) (a c) (b a) (a c))

(generator->list (combinations-of 2 '#(a b c)) 5)
 @result{} (#(a c) #(b c) #(c b) #(b a) #(b c))
@end example
@end defun

@c EN
The following procedures takes optional @var{sizer} argument, which can
be either a nonnegative integer or a generator of nonnegative integers.
The value of the sizer determines the length of the result data.
@c JP
以下の手続きは、省略可能な@var{sizer}引数を取ります。
@var{sizer}引数は非負整数か、非負整数を生成するジェネレータで、
その値(もしくは生成された値)が、最終的に生成されるデータの長さを決定します。
@c COMMON

@c EN
Unlike most of Gauche procedures, @var{sizer} argument comes before
the last argument when it is not omitted.
We couldn't resist the temptation to
write something like @code{(lists-of 3 booleans)}.
@c JP
Gaucheの他のほとんどの手続きと違って、@var{sizer}引数は省略されない時は
最後の引数よりも前に来ます。これは統一性を損ないますが、
@code{(lists-of 3 booleans)} のように書ける、という誘惑に勝てませんでした。
@c COMMON

@c EN
If @var{sizer} is omitted, the default value is taken from
the parameter @code{default-sizer}.  The default of @code{default-sizer}
is @code{(integers-poisson$ 4)}.
@c JP
@var{sizer}引数が省略された場合、パラメータ@code{default-sizer}の値が
使われます。@code{default-sizer}のデフォルトは
@code{(integers-poisson$ 4)}で作られるジェネレータです。
@c COMMON

@defun lists-of item-gen
@defunx lists-of sizer item-gen
@defunx vectors-of item-gen
@defunx vectors-of sizer item-gen
@defunx strings-of
@defunx strings-of item-gen
@defunx strings-of sizer item-gen
@c MOD data.random
@c EN
Creates a generator that generates lists, vectors or strings of values from @var{item-gen}, respectively.  The size of each datum is determined by
@var{sizer}.
@c JP
それぞれ、リスト、ベクタ、文字列を生成するジェネレータを作ります。
作られるデータの各要素はジェネレータ@var{item-gen}から取られます。
各データの長さは@var{sizer}により決定されます。
@c COMMON

@c EN
You can also omit @var{item-gen} for @code{strings-of}.  In that case,
a generator created by @code{(chars$)} is used.
@c JP
@code{strings-of}の場合は@var{item-gen}も省略することができます。
その場合は、@code{(chars$)}で作られるジェネレータが使われます。
@c COMMON

@example
(generator->list (lists-of 3 uint8s) 4)
 @result{} ((254 46 0) (77 158 46) (1 134 156) (74 5 110))

@c EN
;; using the default sizer
@c JP
;; デフォルトのsizerを使う
@c COMMON
(generator->list (lists-of uint8s) 4)
 @result{} ((93 249) (131 97) (98 206 144 247 241) (126 156 31))

@c EN
;; using a generator for the sizer
@c JP
;; sizerにジェネレータを使う
@c COMMON
(generator->list (strings-of (integers$ 8) (chars$)) 5)
 @result{} ("dTJYVhu" "F" "PXkC" "w" "")
@end example
@end defun

@defun sequences-of class item-gen
@defunx sequences-of class sizer item-gen
@c MOD data.random
@c EN
Creates a generator that yields sequences of class @var{class},
whose items are generated by @var{item-gen}.  The size of each
sequence is determined by @var{sizer}, or the value of @code{default-sizer}
if omitted; the sizer can be a nonnegative integer, or a generator
that yields nonnegative integers.

The class @var{class} must be a subclass of @code{<sequence>} and
implement the builder interface.
@c JP
クラス@var{class}のインスタンスであるシーケンスを生成するジェネレータを作ります。
シーケンスの要素は@var{item-gen}により生成されます。
各シーケンスの長さは@var{sizer}引数 (省略時は@code{default-sizer}の値)
によって決められます。@var{sizer}は非負整数か、非負整数を生成するジェネレータです。

@var{class}は@code{<sequence>}のサブクラスであり、
ビルダーインタフェースを実装していなければなりません。
@c COMMON

@example
(generator->list (sequences-of <u8vector> 4 uint8s) 3)
 @result{} (#u8(95 203 243 46) #u8(187 199 153 152) #u8(39 114 39 25))
@end example
@end defun


@deffn {Parameter} default-sizer
@c MOD data.random
@c EN
The sizer used by @code{lists-of}, @code{vectors-of} and @code{strings-of}
when @var{sizer} argument is omitted.

The value must be either an nonnegative integer, or a generator
of nonnegative integers.
@c JP
@code{lists-of}、@code{vectors-of}、@code{strings-of}で
@var{sizer}引数が省略された場合に使われるsizerです。

値は、非負整数か、非負整数を生成するジェネレータでなければなりません。
@c COMMON
@end deffn

@c ----------------------------------------------------------------------
@node Ring buffer, Skew binary random-access lists, Random data generators, Library modules - Utilities
@section @code{data.ring-buffer} - Ring buffer
@c NODE リングバッファ, @code{data.ring-buffer} - リングバッファ

@deftp {Module} data.ring-buffer
@mdindex data.ring-buffer
@c EN
A ring buffer is an array with two fill pointers; in a typical usage,
a producer adds new data to one end while a consumer removes data
from the other end; if fill pointer reaches at the end of the array,
it wraps around to the beginning, hence the name.
@c JP
リングバッファは、両端を指す二つのポインタを持つ配列と考えられます。良くある使い方は、
生産者が配列の一方の端にデータを追加してゆき、消費者がもう一方の端から
データを取り出してゆくというものです。もし端を示すポインタが配列の
終端に達したら、それはもう一方の端につながっているように振る舞います。
「リング」バッファと呼ばれるのはそのためです。
@c COMMON

@c EN
The ring buffer of this module allows adding and removing elements
from both ends, hence functionally it is a double-ended queue,
or deque.  It also allows O(1) indexed access to the contents,
and customized handling for the case when the buffer gets full.
@c JP
このモジュールの提供するリングバッファは、どちらの端にもデータを追加し、
どちらの端からもデータを取り出すことができます。したがって機能的には
両端キュー(double-ended queue, deque)の一種とも考えられます。
また、O(1)で要素にアクセス可能で、
さらにバッファが一杯になった時の振る舞いをカスタマイズできます。
@c COMMON

@c EN
You can use an ordinary vector or a uniform vector as the backing
storage of a ring buffer.
@c JP
リングバッファがデータを格納するバッキングストレージとして、
通常のベクタかユニフォームベクタを使えます。
@c COMMON
@end deftp

@defun make-ring-buffer :optional initial-storage :key overflow-handler
@c MOD data.ring-buffer
@c EN
Creates a ring buffer.  By default, a fresh vector is allocated
for the backing storage.  You can pass a vector or a uvector to
@var{initial-storage} to be used instead.  The passed storage must
be mutable, and will
be modified by the ring buffer; the caller shouldn't modify it,
nor make assumption about its content.
@c JP
リングバッファを作成します。デフォルトでは、データ格納のための領域として
新たなベクタがアロケートされます。かわりに、呼び出し側でベクタかユニフォームベクタ
を用意して@var{initial-storage}に渡すこともできます。その場合、
渡すベクタやユニフォームベクタは変更可能でなければなりません。以降、
リングバッファがそのベクタを変更するので、呼び出し側でベクタを変更
したりベクタの内容が保存されることを期待してはいけません。
@c COMMON

@c EN
The @var{overflow-handler} keyword argument specifies what to do when
a new element is about to be added to the full buffer.
It must be a procedure, or a symbol @code{error}
or @code{overwrite}.
@c JP
@var{overflow-handler}キーワード引数は、バッファがフルの状態で
新たな要素が追加されようとした時の振る舞いを指定します。
引数は手続きか、シンボル@code{error}か@code{overwrite}のいずれかでなければなりません。
@c COMMON

@c EN
If it is a procedure, it will be called with a ring buffer and
a backing storage (vector or uvector) when it is filled.  The procedure
must either (1) allocate and return a larger vector/uvector of the same
type of the passed backing storage, (2) return a symbol @code{error},
or (3) return a symbol @code{overwrite}.  If it returns a vector/uvector,
it will be used as the new backing storage.  The returned vector doesn't need
to be initialized; the ring buffer routine takes care of copying the
necessary data.
If it returns @code{error},
an error (``buffer is full'') is thrown.  If it returns @code{overwrite},
the new element overwrites the existing element (as if one element
from the other end is popped and discarded.)
@c JP
引数が手続きの場合、リングバッファと(一杯になった)バッキングストレージ
が引数として渡されます。この手続きは以下の3つのアクションのうちひとつを
実行しなければなりません。(1)渡されたバッキングストレージ(ベクタか
ユニフォームベクタ)と同じ型で、より大きなベクタまたはユニフォームベクタをアロケートして
返す。(2)シンボル@code{error}を返す。(3)シンボル@code{overwrite}を返す。
手続きがベクタもしくはユニフォームベクタを返した場合は、それが
新たなバッキングストレージとして使われます。
返すベクタの内容を設定する必要はありません。リングバッファが適切に内容のコピーや
必要な初期化を行います。手続きが@code{error}を返した場合は、
``buffer is full''のエラーが投げられます。
手続きが@code{overwrite}を返した場合は、
新たな要素で古い要素を上書きします(つまり、
あたかも別の端から1要素がポップされて捨てられ、その後で新たな要素が
追加されたかのように振る舞います)。
@c COMMON

@c EN
Passing a symbol @code{error} or @code{overwrite} to @var{overflow-handler}
is a shorthand of passing a procedure that unconditionally returns
@code{error} or @code{overwrite}, respectively.
@c JP
@var{overflow-handler}引数にシンボル@code{error}か@code{overwrite}
を渡した場合は、あたかもそれらのシンボルを無条件に返すoverflow handlerが
指定されたかのように振る舞います。
@c COMMON

@c EN
The default behavior on overflow is to double the size of backing
storage.  You can use @code{make-overflow-doubler} below to create
the customized overflow handler easily.
@c JP
@var{overflow-handler}が指定されない場合のデフォルトの動作は、
元のバッキングストレージの倍の容量をアロケートして返すことです。
下の@code{make-overflow-doubler}を使うと、カスタマイズした
オーバフローハンドラを簡単に作ることができます。
@c COMMON
@end defun

@defun make-overflow-doubler :key max-increase max-capacity
@c MOD data.ring-buffer
@c EN
Returns a procedure suitable to be passed to the @var{overflow-handler}
keyword argument of @code{make-ring-buffer}.

The returned procedure takes a ring buffer and its backing storage,
and behaves as follows.
@c JP
@code{make-ring-buffer}の@var{overflow-handler}キーワード引数に
渡せる手続きを作って返します。

返される手続きは、リングバッファとバッキングストレージを引数に取り、
以下のとおり振る舞います。
@c COMMON

@itemize
@item
@c EN
If the size of current backing storage is equal to or greater than
@var{max-capacity}, returns @code{error}.
@c JP
現在のバッキングストレージの大きさが@var{max-capacity}以上であれば、
@code{error}を返す。
@c COMMON
@item
@c EN
Otherwise, if the size of current backing storage is equal to or
greater than @var{max-increase}, allocates a vector/uvector of
the same type of the current backing storage, with the size
@code{(+ max-increase size-of-current-storage)}.
@c JP
そうではなく、現在のバッキングストレージの大きさが@var{max-increase}以上で
あれば、@code{(+ max-increase 現在の大きさ)}の大きさを持つ
ベクタもしくはユニフォームベクタをアロケートして返す。
@c COMMON
@item
@c EN
Otherwise, allocates a vector/uvector of
the same type of the current backing storage with the size
@code{(* 2 size-of-current-storage)}.
@c JP
そうでない場合は、@code{(* 2 現在の大きさ)} の大きさを持つ
ベクタもしくはユニフォームベクタをアロケートして返す。
@c COMMON
@end itemize

@c EN
The default value of @var{max-increase} and @var{max-capacity} is
@code{+inf.0}.
@c JP
@var{max-increase}と@var{max-capacity}のデフォルト値はどちらも
@code{+inf.0}です。
@c COMMON
@end defun

@defun ring-buffer-empty? rb
@c MOD data.ring-buffer
@c EN
Returns @code{#t} if the ring buffer @var{rb} is empty,
@code{#f} if not.
@c JP
リングバッファ@var{rb}が空なら@code{#t}を、そうでなければ@code{#f}を返します。
@c COMMON
@end defun

@defun ring-buffer-full? rb
@c MOD data.ring-buffer
@c EN
Returns @code{#t} if the ring buffer @var{rb} is full,
@code{#f} if not.
@c JP
リングバッファ@var{rb}がフルなら@code{#t}を、そうでなければ@code{#f}を返します。
@c COMMON
@end defun

@defun ring-buffer-num-entries rb
@c MOD data.ring-buffer
@c EN
Returns the number of current elements in the ring buffer @var{rb}.
@c JP
リングバッファ@var{rb}が格納している要素数を返します。
@c COMMON
@end defun

@defun ring-buffer-capacity rb
@c MOD data.ring-buffer
@c EN
Returns the size of the current backing storage of the ring buffer @var{rb}.
@c JP
リングバッファの現在のバッキングストレージの容量(格納可能な要素数)を返します。
@c COMMON
@end defun

@defun ring-buffer-front rb
@defunx ring-buffer-back rb
@c MOD data.ring-buffer
@c EN
Returns the element in the front or back of the ring buffer @var{rb},
respectively.
If the buffer is empty, an error is signaled.
@c JP
リングバッファ@var{rb}の先頭あるいは末尾の要素をそれぞれ返します。
バッファが空の場合はエラーが投げられます。
@c COMMON
@end defun

@defun ring-buffer-add-front! rb elt
@defunx ring-buffer-add-back! rb elt
@c MOD data.ring-buffer
@c EN
Add an element to the front or back of the ring buffer @var{rb},
respectively.  If @var{rb} is full, the behavior is determined by
the buffer's overflow handler, as described in @code{make-ring-buffer}.
@c JP
リングバッファ@var{rb}の先頭もしくは末尾にそれぞれ要素を追加します。
@var{rb}がフルの場合の振る舞いは、バッファのオーバーフローハンドラによって
決定されます。詳しくは@code{make-ring-buffer}のエントリを参照してください。
@c COMMON
@end defun

@defun ring-buffer-remove-front! rb
@defunx ring-buffer-remove-back! rb
@c MOD data.ring-buffer
@c EN
Remove an element from the front or back of the ring buffer @var{rb},
and returns the removed element, respectively.
If the buffer is empty, an error is signaled.
@c JP
リングバッファ@var{rb}の先頭もしくは末尾から要素をひとつ取り、取った要素を
返します。
バッファが空の場合はエラーが投げられます。
@c COMMON
@end defun

@defun ring-buffer-ref rb index :optional fallback
@c MOD data.ring-buffer
@c EN
Returns @var{index}-th element in the ring buffer @var{rb}.
The elements are counted from the front; thus, if a new element
is added to the front, the indexes of existing elements will shift.

If the index out of bounds of the existing content,
@var{fallback} will be returned; if @var{fallback} is not
provided, an error is signaled.
@c JP
リングバッファ@var{rb}の@var{index}番目の要素を返します。
要素は先頭から数えられます。したがって、新たな要素が先頭に付け加えられた場合、
既存の要素のインデックスはひとつづつずれます。

@var{index}が@var{rb}の持つ要素の範囲外の場合、@var{fallback}が与えられていれば
それを返し、そうでなければエラーが投げられます。
@c COMMON
@end defun

@defun ring-buffer-set! rb index value
@c MOD data.ring-buffer
@c EN
Sets @var{index}-th element of the ring buffer @var{rb} to @var{value}.
The elements are counted from the front; thus, if a new element
is added to the front, the indexes of existing elements will shift.

An error is signaled if the index is out of bounds.
@c JP
リングバッファ@var{rb}の@var{index}番目の要素に@var{value}をセットします。
要素は先頭から数えられます。したがって、新たな要素が先頭に付け加えられた場合、
既存の要素のインデックスはひとつづつずれます。

@var{index}が@var{rb}の持つ要素の範囲外の場合はエラーが投げられます。
@c COMMON
@end defun


@c ----------------------------------------------------------------------
@node Skew binary random-access lists, Sparse data containers, Ring buffer, Library modules - Utilities
@section @code{data.skew-list} - Skew binary random-access lists
@c NODE Skew binary random-access lists, @code{data.sparse} - Skew binary random-access lists

@deftp {Module} data.skew-list
@mdindex data.skew-list
This module implements skew binary random-access list (we call it skew-list
for short).  It's an immutable
data structure that has properties of both list and vector; constant
time to take the first element (car) and append an element in front
of existing one (cons), O(log n) to take the rest of
the elements (cdr), and O(log n) for indexed access, wher n is
the number of elements.

A skew-list is always 'proper'; that is, it is either an empty
skew-list (@code{skew-list-null}), or an object appended in front
of a skew-list.
@end deftp

@deftp {Class} <skew-list>
@clindex skew-list
@c MOD data.skew-list
The class for skew-lists.

It inherits @code{<sequence>} and follws the sequence protocol.
@end deftp

@defun skew-list? obj
@c MOD data.skew-list
Returns @code{#t} iff @var{obj} is a skew-list.
@end defun

@defun skew-list-empty? sl
@c MOD data.skew-list
The argument must be a skew list.  Returns @code{#t} iff @var{sl}
is an empty skew list.
@end defun

@defvar skew-list-null
@c MOD data.skew-list
An empty skew list.
@end defvar

@defun skew-list-cons obj sl
@c MOD data.skew-list
Returns a new skew-list which has @var{obj} prepended to
a skew-list @var{sl}.
@end defun

@defun skew-list-car sl
@c MOD data.skew-list
Returns the first element of a skew-list @var{sl}.  An error is
raised when @var{sl} is empty.
@end defun

@defun skew-list-cdr sl
@c MOD data.skew-list
Returns a new skew-list that containts elements in @var{sl} but
the firest one.  An error is
raised when @var{sl} is empty.
@end defun

@defun skew-list-ref sl k :optional fallback
@c MOD data.skew-list
Returns the @var{k}-th element of a skew-list @var{sl}.  If @var{k}
points past the range of @var{sl}, @var{fallback} is returned if it
is given, or an error is signaled.

Sicne a skew-list is also a sequence, you can use generic @code{ref} as well
(@pxref{Sequence framework}.
@end defun

@defun skew-list-set sl k obj
@c MOD data.skew-list
Returns a new skew-list which is the same as @var{sl} except the @var{k}-th
element is replaced with @var{obj}.  The argument @var{sl} remains intact.

It is an error if @var{k} points beyond the last element of @var{sl}.
@end defun

@defun skew-list-length sl
@c MOD data.skew-list
Returns an integer length of a skew-list @var{sl}.

Sicne a skew-list is also a sequence, you can use generic @code{size-of} as well
(@pxref{Sequence framework}.
@end defun

@defun skew-list-length<=? sl n
@c MOD data.skew-list
Returns @code{#t} iff the length of a skew-list @var{sl} is less than
or equal to @var{n}.  It is more efficient than calculating
the total length and compares with @var{n}.
@end defun

@defun list->skew-list lis
@c MOD data.skew-list
Returns a new skew-list which contains elements in @var{lis}, with the
same order.  It is an error if @var{lis} is not a proper list.

Sicne a skew-list is also a sequence, you can use generic @code{coerce-to}
as well (@pxref{Sequence framework}.
@end defun

@defun list*->skew-list lis
@c MOD data.skew-list
The argument @var{lis} may be an improper list (but can't be circular).
Returns two values: a new skew-list which contains elements 
in @var{lis} except the last cdr of it, and the last cdr of @var{lis}.
@end defun

@defun skew-list->list sl
@c MOD data.skew-list
Returns a new list that contains all the elements in a skew-list @var{sl},
with the same order.

Sicne a skew-list is also a sequence, you can use generic @code{coerce-to}
as well (@pxref{Sequence framework}.
@end defun

@defun skew-list->generator sl
@c MOD data.skew-list
Returns a new generator that traverses a skew-list @var{sl}.
@end defun

@defun skew-list->lseq sl
@c MOD data.skew-list
Converts a skew-list @var{sl} to a lazy sequence.
@end defun

@defun skew-list-take sl k
@defunx skew-list-drop sl k
@c MOD data.skew-list
Returns a new skew-list of the first @var{k} elements and the elements
except the first @var{k} elements, respectively.
@end defun

@defun skew-list-split-at sl k
@c MOD data.skew-list
Returns two values, the result of @code{(skew-list-take sl k)}
and @code{(skew-list-drop sl k)}, but more efficiently.
@end defun

@defun skew-list-append sl sl2 @dots{}
@c MOD data.skew-list
Returns a skew-list which is a concatenation of all the given skew-lists.
@end defun

@defun skew-list-fold sl kons knil
@c MOD data.skew-list
Like @var{fold} on a list.

Sicne a skew-list is also a sequence, you can use generic @code{fold}
as well (@pxref{Sequence framework}.
@end defun

@defun skew-list-map sl proc
@c MOD data.skew-list
Returns a skew list, each element of which is the result of
applying @var{proc} on the element of @var{sl}.

NB: If you want ot map over multiple skew-lists, you can use generic
@code{map} (@pxref{Sequence framework}).  The @code{skew-list-map} employs
optimization that's specific to one-argument case.
@end defun


@c ----------------------------------------------------------------------
@node Sparse data containers, Trie, Skew binary random-access lists, Library modules - Utilities
@section @code{data.sparse} - Sparse data containers
@c NODE 疎なデータコンテナ, @code{data.sparse} - 疎なデータコンテナ

@deftp {Module} data.sparse
@mdindex data.sparse
@c EN
This module provides a @emph{sparse vector} and @emph{sparse matrix}, 
a space efficient data container indexed by nonnegative integer(s), and
a @emph{sparse table}, a hash table using a sparse vector
as a backing storage.
@c JP
このモジュールは、非負整数でインデックスされる空間効率の良いデータ構造である
@emph{疎ベクタ} (@emph{sparse vector})と
@emph{疎行列} (@emph{sparse matrix})、
および
疎ベクタを格納領域に用いるハッシュテーブルである@emph{疎テーブル} (@emph{sparse table})
を提供します。
@c COMMON
@end deftp

@c EN
A sparse vector associates a nonnegative integer index
to a value.  It has @emph{vector} in its name since it is indexed
by an integer, but it isn't like a flat array on contiguous memory;
it's more like an associative array.  (Internally, the current
implementation uses compact trie structure.)
It is guaranteed that you can store a value with index at least
up to @code{2^32-1}; the actual maximum bits of indexes can
be queried by @code{sparse-vector-max-index-bits}.
(We have a plan to remove the maximum bits limitation in future).
@c JP
疎ベクタは非負整数のインデックスと値を関連付けます。
整数でインデックスされるので名前に@emph{ベクタ}がついていますが、
連続するメモリに置かれる配列ではなく、むしろ連想配列のようなものです。
(内部的には、現在の実装はコンパクトなトライを使っています)。
少なくとも@code{2^32-1}までのインデックスが使えることは保証されています。
実装が許す最大のインデックスのビット長は
@code{sparse-vector-max-index-bits}で得ることができます。
(将来的にはこの制限を無くす計画です)。
@c COMMON

@c EN
Unlike ordinary vectors, you don't need to specify the size
of a sparse vector when you create one.  You can just set
a value to any index in the supported range.
@c JP
通常のベクタと違い、疎ベクタは作る時に大きさを指定する必要がありません。
サポートされている範囲内ならどんなインデックスにでも単に値を格納できます。
@c COMMON

@example
(define v (make-sparse-vector))

(sparse-vector-set! v 0 'a)
(sparse-vector-ref v 0) @result{} a

(sparse-vector-set! v 100000000 'b)
(sparse-vector-ref v 100000000) @result{} b

;; set! also work
(set! (sparse-vector-ref v 100) 'c)
(sparse-vector-ref v 100) @result{} c
@end example

@c EN
If you try to access an element that hasn't been set,
an error is signaled by default.  You can set
a default value for each vector, or give a
fallback value to @code{sparse-vector-ref}, to suppress the error.
@c JP
値がセットされていない要素にアクセスすると、デフォルトではエラーが通知されます。
ベクタごとに既定値を設定したり、
@code{sparse-vector-ref}の省略可能引数にフォールバック値を
渡すことでエラーを回避できます。
@c COMMON

@example
(sparse-vector-ref v 1)        @result{} @r{error}
(sparse-vector-ref v 1 'noval) @result{} noval

(let1 w (make-sparse-vector #f :default 'x)
  (sparse-vector-ref w 1))     @result{} x
@end example

@c EN
A sparse matrix is like a sparse vector, except it can be indexed
by a pair of integers.
@c JP
疎行列は、二つの整数でインデックスされるという点以外は疎なベクタと同じです。
@c COMMON

@c EN
A sparse table works just like a hash table, but it uses
a sparse vector to store the values using hashed number of the keys.
@c JP
疎テーブルはハッシュテーブルと同じように動作しますが、キーのハッシュ値を
インデックスとして値を疎ベクタに格納しています。
@c COMMON

@c EN
The main reason of these sparse data containers are for
memory efficiency.   If you want to store values in a vector
but knows you'll use only some entries sparsely, obviously it
is waste to allocate a large vector and to leave many entries unused.
But it is worse than that; Gauche's GC doesn't like a large
contiguous region of memory.  Using lots of large vectors adds
GC overhead quickly.  It becomes especially visible when you
store large number of entries (like >100,000) into hash tables,
since Gauche's builtin hash tables use a flat vector as a backing
storage.   You'll see the heap size grows quickly and
GC runs more frequently and longer.
On the other hand, sparse table works pretty stable with
large number of entries.
@c JP
これらの疎なデータコンテナの主な目的は、メモリ効率です。
ベクタに値を入れておきたいけれどごく一部のインデックスしか使わないことが
分かっている、と言った場合に、巨大なベクタをアロケートしてその大部分を
使わないでおくのは明らかに無駄でしょう。ただそれだけではありません。
Gaucheのガベージコレクタは、一続きの巨大なメモリ領域を確保するのとあまり
相性が良くありません。大きなベクタを大量に使うとGCのオーバヘッドが急速に増えます。
Gaucheの組み込みハッシュテーブルは
データストアに通常のベクタを使っているのですが、
大量のデータを詰め込むとその効果が目に見えてきます。ヒープサイズが急に増え、
GCはより頻繁に走り、しかも一回一回に要する時間は長くなるでしょう。
一方で、疎テーブルは大量のデータに対してもかなり安定に動作します。
@c COMMON

@c EN
Sparse data containers does have overhead on access speed.
They are a bit slower than the ordinary hash tables,
and much slower than ordinary vectors.  We should note, however,
as the number of entries grow, access time on ordinary hash
tables grows quicker than sparse tables and eventually two become
comparable.
@c JP
疎なデータコンテナは、単純なデータコンテナに比べるとアクセスにオーバヘッドはあります。
通常のハッシュテーブルより若干遅いですし、通常のベクタと比べるとかなり遅いです。
けれども、テーブル内のデータ数が大きくなる領域では、通常のハッシュテーブルの
アクセス時間の方が急速に悪化するため、いずれ二つのアクセス時間は
そこそこ同じになります。
@c COMMON

@c EN
It depends on your application which you should use, and
if you're not sure, you need to benchmark.
As a rule of thumb, if you use more than several hashtables
each of which contains more than a few tens of thousands of
entries, sparse tables may work better.
If you see GC Warnings telling ``repeated allocation of large
blocks'', you should definitely consider sparse tables.
@c JP
どちらを使うべきかはアプリケーションに依存します。良く分からないのであれば、
ベンチマークを取りましょう。簡単な基準としては、数万以上のエントリを持つ
ハッシュテーブルを数個以上作るなら、疎テーブルの方が良くなるかもしれません。
実行中に``repeated allocation of large blocks''というGCからの
警告を目にしたなら、疎テーブルへの切り替えを考えてみましょう。
@c COMMON

@menu
* Sparse vectors::
* Sparse matrixes::
* Sparse tables::
@end menu

@node Sparse vectors, Sparse matrixes, Sparse data containers, Sparse data containers
@subsection Sparse vectors
@c NODE 疎なベクタ

@deftp {Class} <sparse-vector-base>
@clindex sparse-vector-base
@c MOD data.sparse
@c EN
An abstract base class of sparse vectors.
Inherits @code{<dictionary>} and @code{<collection>}.
Note that sparse vectors are @emph{not} @code{<sequence>}; even
they can be indexable by integers, they don't have
means of @emph{ordered} access.

Sparse vector may be a general vector
that can contain any Scheme objects (like @code{<vector>}),
or a specialized vector that can contain only certain
types of numbers (like @code{<s8vector>} etc.).

All of these sparse vectors can be accessed by the same API.

Sparse vectors also implements the Collection API
(@pxref{Collection framework}) and the Dictionary API
(@pxref{Dictionary framework}).
@c JP
疎なベクタの抽象ベースクラスです。@code{<dictionary>}と@code{<collection>}を
継承しています。@code{<sequence>}は継承していないことに注意してください。
疎なベクタは整数でインデクス可能ですが、インデクスの順番に要素にアクセスする手段を
持っていません。

疎なベクタは、@code{<vector>}と同様、任意のSchemeオブジェクトを格納可能である
ものもあれば、@code{<s8vector>}等と同様に特定の範囲の数値のみ格納可能なものもあります。
全ての疎なベクタは同一セットのAPIで利用可能です。

疎なベクタはまた、コレクションAPIとディクショナリAPIを実装しています。これらについては
@ref{Collection framework}および@ref{Dictionary framework}を
参照してください。
@c COMMON
@end deftp

@deftp {Class} <sparse-vector>
@deftpx {Class} <sparse-@@vector>
@clindex sparse-vector
@clindex sparse-s8vector
@clindex sparse-u8vector
@clindex sparse-s16vector
@clindex sparse-u16vector
@clindex sparse-s32vector
@clindex sparse-u32vector
@clindex sparse-s64vector
@clindex sparse-u64vector
@clindex sparse-f16vector
@clindex sparse-f32vector
@clindex sparse-f64vector
@c MOD data.sparse
@c EN
The actual sparse vector classes.  Inherits @code{<sparse-vector-base>}.
An instance of @code{<sparse-vector>} can contain any Scheme objects.

@code{@@} is either one of @code{s8}, @code{u8},
@code{s16}, @code{u16}, @code{s32}, @code{u32},
@code{s64}, @code{u64}, @code{f16}, @code{f32}, or @code{f64}.
The range of values an instance of those classes can hold
is the same as the corresponding @code{<@@vector>} class
in @code{gauche.uvector} (@pxref{Uniform vectors}).  That is,
@code{<sparse-u8vector>} can have exact integer values
between 0 and 255.
@c JP
疎なベクタの具体クラスです。それぞれ@code{<sparse-vector-base>}を継承します。

@code{<sparse-vector>}のインスタンスは任意のSchemeオブジェクトを格納できます。

@code{@@}は @code{s8}, @code{u8},
@code{s16}, @code{u16}, @code{s32}, @code{u32},
@code{s64}, @code{u64}, @code{f16}, @code{f32}, @code{f64}のいずれかで、
それぞれの疎なベクタの格納可能な値は、@code{gauche.uvector}の
対応する@code{<@@vector>}に準じます(@ref{Uniform vectors}参照)。
つまり、@code{<sparse-u8vector>}の要素には0以上255以下の正確な整数を
格納できます。
@c COMMON
@end deftp

@defun make-sparse-vector :optional type :key default
@c MOD data.sparse
@c EN
Creates an empty sparse vector.  The @var{type} argument can be
@code{#f} (default), one of subclasses of @code{<sparse-vector-base>},
or a symbol of either one of @code{s8}, @code{u8},
@code{s16}, @code{u16}, @code{s32}, @code{u32},
@code{s64}, @code{u64}, @code{f16}, @code{f32}, or @code{f64}.

If @var{type} is omitted or @code{#f}, a @code{<sparse-vector>} is
created.  If it is a class, an instance of the class is created
(It is an error to pass a class that is not a subclass of
@code{<sparse-vector-base>}.)
If it is a symbol, an instance of corresponding @code{<sparse-@@vector>}
is created.
@c JP
空の疎なベクタを作成して返します。@var{type}引数は@code{#f}(デフォルト)か、
@code{<sparse-vector-base>}のサブクラスのどれか、
あるいはシンボル@code{s8}, @code{u8},
@code{s16}, @code{u16}, @code{s32}, @code{u32},
@code{s64}, @code{u64}, @code{f16}, @code{f32}, @code{f64}のいずれかを
指定できます。

@var{type}が省略されるか@code{#f}の場合は@code{<sparse-vector>}のインスタンスが
作られます。@var{type}がクラスであればそのインスタンスが、またシンボルであれば、
対応する@code{<sparse-@@vector>}のインスタンスが作られます。
@c COMMON

@c EN
You can specify the default value of the vector by @var{default}
keyword argument.   If given, the vector behaves as if it is filled
with the default value (but the vector iterator only picks
the values explicitly set).

Note that you have to give the optional argument as well
to specify the keyword argument.
@c JP
キーワード引数@var{default}によって、作成するベクタの要素既定値を指定できます。
この引数が与えられると、ベクタは全てあらかじめその値で埋められているかのように
振る舞います (ただしイテレータは陽にセットされた値のみ取り出します)。

キーワード引数を与える場合、それに先立って省略可能引数も与える必要が
あることに注意してください。
@c COMMON

@example
(define v (make-sparse-vector 'u8 :default 128))

(sparse-vector-ref v 0) @result{} 128
@end example
@end defun

@defun sparse-vector-max-index-bits
@c MOD data.sparse
@c EN
Returns maximum number of bits of allowed integer.  If this
returns 32, the index up to @code{(expt 2 32)} is supported.
It is guaranteed that this is at least 32.
@c JP
実装が利用できる、疎なベクタのインデックスの最大のビット数を返します。
例えばこれが32を返したなら、インデックスとして@code{(expt 2 32)}まで
使えるということです。この値は最低でも32であることが保証されています。
@c COMMON
@end defun

@c EN
In the following entries, the argument @var{sv} denotes
an instance of sparse vector; an error is signaled if other
object is passed.
@c JP
以下のエントリにおいて、引数@var{sv}は疎なベクタのインスタンスです。
他のオブジェクトが渡された場合はエラーが報告されます。
@c COMMON

@defun sparse-vector-copy sv
@c MOD data.sparse
@c EN
Returns a copy of a sparse vector @var{sv}.
@c JP
疎なベクタ@var{sv}のコピーを返します。
@c COMMON
@end defun

@defun sparse-vector-ref sv k :optional fallback
@c MOD data.sparse
@c EN
Returns @var{k}-th element of a sparse vector @var{sv}, where
@var{k} must an exact integer.

If the sparse vector doesn't have a value for @var{k}, it
behaves as follows:

@itemize @bullet
@item
If @var{fallback} is given, it is returned.
@item
Otherwise, if the vector has the default value, it is returned.
@item
Otherwise, an error is signaled.
@end itemize
@c JP
疎なベクタ@var{sv}のインデックス@var{k}にある要素を返します。
@var{k}は正確な整数でなければなりません。

@var{k}に対応する要素がない場合は、次のように振る舞います。

@itemize @bullet
@item
@var{fallback}引数が与えられていればそれを返します。
@item
そうでなく、ベクタが既定値を持っていれば、それを返します。
@item
そうでなければ、エラーが報告されます。
@end itemize
@c COMMON
@end defun

@defun sparse-vector-set! sv k value
@c MOD data.sparse
@c EN
Sets @var{value} for @var{k}-th element of a sparse vector @var{sv}.
@var{K} must be a nonnegative exact integer, and below the maximum
allowed index.

If @var{sv} is a numeric sparse vector, @var{value} must also be
within the allowed range, or an error is signaled.
@c JP
疎なベクタ@var{sv}の@var{k}番めの要素に@var{value}を設定します。
@var{k}は非負の正確な整数で、許される最大のインデックス以下でなければなりません。
@c COMMON
@end defun

@defun sparse-vector-num-entries sv
@c MOD data.sparse
@c EN
Returns the number of entries in @var{sv}.
@c JP
@var{sv}の持つ要素数を返します。
@c COMMON
@end defun

@defun sparse-vector-exists? sv k
@c MOD data.sparse
@c EN
Returns @code{#t} if @var{sv} has an entry for index @var{k},
@code{#f} otherwise.
@c JP
@var{sv}の@var{k}番目のエントリが値を持っていれば@code{#t}を、
そうでなければ@code{#f}を返します。
@code{#t}
@c COMMON
@end defun

@defun sparse-vector-delete! sv k
@c MOD data.sparse
@c EN
Deletes the @var{k}-th entry of @var{sv}.  If @var{sv} had the entry ,
returns @code{#t}.  If @var{sv} didn't have the entry, returns @code{#f}.
@c JP
@var{sv}の@var{k}番目のエントリが値を持っていれば、それを消去して
@code{#t}を返します。
そうでなければ何もせずに@code{#f}を返します。
@c COMMON
@end defun

@defun sparse-vector-clear! sv
@c MOD data.sparse
@c EN
Empties a sparse vector.
@c JP
疎なベクタを空にします。
@c COMMON
@end defun

@defun sparse-vector-inc! sv k delta :optional (fallback 0)
@c MOD data.sparse
@c EN
@c EN
This is a shortcut of the following.  It is especially efficient
for numeric sparse vectors.

@example
(sparse-vector-set! sv k (+ (sparse-vector-ref sv k fallback) delta))
@end example

If the result of addition exceeds the allowed value range of @var{sv},
an error is signaled.  In future we'll allow an option to clamp
the result value within the range.
@c JP
これは次のコードと同じ動作をしますが、数値を格納する疎ベクタでは特に
効率よく動作します。

@example
(sparse-vector-set! sv k (+ (sparse-vector-ref sv k fallback) delta))
@end example

もし加算の結果が@var{sv}に許される数値の範囲を越えた場合は、
エラーが投げられます。将来はそういった場合に値をクランプするオプションも
用意する予定です。
@c COMMON
@end defun

@defun sparse-vector-update! sv k proc :optional fallback
@defunx sparse-vector-push! sv k val
@defunx sparse-vector-pop! sv k :optional fallback
@c MOD data.sparse
@c EN
Convenience routines to fetch-and-update an entry of
a sparse vector.  Works just like @code{hash-table-update!},
@code{hash-table-push!} and @code{hash-table-pop!};
(@pxref{Hashtables}).
@c JP
疎なベクタのエントリの値を取り出してアップデートするパターンを
簡単に書くためのルーチンです。それぞれ、@code{hash-table-update!}、
@code{hash-table-push!}、@code{hash-table-pop!}と
同じように動作します。(@ref{Hashtables}参照)。
@c COMMON
@end defun

@c EN
The following procedures traverses a sparse vector.
Note that elements are not visited in the order of index;
it's just like hash table traversers.
@c JP
以下の手続きは疎なベクタの要素を横断します。
要素は必ずしもインデックスの順に訪問されるわけではないことに注意してください。
その点ではハッシュテーブルの横断と似ています。
@c COMMON

@c EN
At this moment, if you want to walk a sparse vector with
increasing/decreasing index order, you have to get a list
of keys by @code{sparse-vector-keys}, sort it, then use
it to retrieve values.
We may add an option in future to @code{make-sparse-vector} so that
those walk operation will be more convenient.
@c JP
今のところ、疎なベクタをインデックスの昇順/降順に処理したい場合は、
@code{sparse-vector-keys}で全てのキーを得て、
それをソートしたもので順に値を取り出してゆくしかありません。
将来は、@code{make-sparse-vector}にオプションをつけて
インデックスの順番による横断を簡単にするかもしれません。
@c COMMON

@defun sparse-vector-fold sv proc seed
@c MOD data.sparse
@c EN
For each entry in @var{sv}, calls @var{proc} as
@code{(proc @var{k_n} @var{v_n} @var{seed_n})}, where
@var{k_n} is an index and @var{v_n} is a value for it,
and @var{seed_n} is the returned value of the previous
call to @var{proc} if @var{n} @code{>=} 1, and @var{seed} if @var{n} = 0.
Returns the value of the last call of @var{proc}.
@c JP
@var{sv}の各エントリに対し、手続き@var{proc}を
@code{(proc @var{k_n} @var{v_n} @var{seed_n})}のように呼び出してゆきます。
ここで@var{seed_n}は@var{n} @code{>=} 1の時は直前の@var{proc}の戻り値、
@var{n} = 0の時は引数@var{seed}です。
最後の@var{proc}の戻り値を返します。
@c COMMON
@end defun

@defun sparse-vector-for-each sv proc
@defunx sparse-vector-map sv proc
@c MOD data.sparse
Calls @code{proc} with index and value, e.g. @code{(proc k value)},
for each element of @var{sv}.

The results of @var{proc} are discarded by @code{sparse-vector-for-each},
and gathered to a list and returned by @code{sparse-vector-map}.
@end defun

@defun sparse-vector-keys sv
@defunx sparse-vector-values sv
@c MOD data.sparse
@c EN
Returns a list of all keys and all values in @var{sv}, respectively.
@c JP
それぞれ、@var{sv}中の全てのキー、または全ての値をリストにして返します。
@c COMMON
@end defun

@node Sparse matrixes, Sparse tables, Sparse vectors, Sparse data containers
@subsection Sparse matrixes
@c NODE 疎行列

@c EN
A sparse matrix is like a sparse vector, except it can be indexed
by two nonnegative integers.
@c JP
疎行列は要素が2つの非負整数でインデックスされること以外は疎なベクタと同じです。
@c COMMON

@c EN
Note: This implementation of sparse matrixes aims at a reasonable
space efficiency for sparse matrixes without knowing its structure
beforehand (imagine, for example, a 2D map with some scattered landmarks).
If what you want is a sparse matrix implementation for efficient numeric
calculations, with certain particular structures,
probably the access speed of this module isn't suitable.
@c JP
註：この疎行列の実装は、事前に構造が分かっていない疎な行列をそれなりに空間効率良く
扱うことを目的としています(例えば、2Dのマップにランドマークを記録してゆく、
といったイメージです)。もし探しているものが、数値計算用に特定の構造を持つ疎行列の
実装でしたら、このモジュールは速度的に十分ではないでしょう。
@c COMMON

@c EN
Currently, each index can have half of bits of
@code{sparse-vector-max-index-bits}.  We'll remove
this limitation in future.
@c JP
現在の実装では、それぞれのインデックスの最大ビット数が
@code{sparse-vector-max-index-bits}の半分までという制限があります。
将来はこの制限をなくす予定です。
@c COMMON


@deftp {Class} <sparse-matrix-base>
@clindex sparse-matrix-base
@c MOD data.sparse
An abstract base class of sparse matrixes.  Inherits @code{<collection>}.

Like sparse vectors, a sparse matrix can be of type that
can store any Scheme objects, or that can store only
certain types of numbers.

All of these sparse matrix subtypes can be accessed by the same API.
@end deftp

@deftp {Class} <sparse-matrix>
@deftpx {Class} <sparse-@@matrix>
@clindex sparse-matrix
@clindex sparse-s8matrix
@clindex sparse-u8matrix
@clindex sparse-s16matrix
@clindex sparse-u16matrix
@clindex sparse-s32matrix
@clindex sparse-u32matrix
@clindex sparse-s64matrix
@clindex sparse-u64matrix
@clindex sparse-f16matrix
@clindex sparse-f32matrix
@clindex sparse-f64matrix
@c MOD data.sparse
The actual sparse matrix classes.  Inherits @code{<sparse-matrix-base>}.
An instance of @code{<sparse-matrix>} can contain any Scheme objects.

@code{@@} is either one of @code{s8}, @code{u8},
@code{s16}, @code{u16}, @code{s32}, @code{u32},
@code{s64}, @code{u64}, @code{f16}, @code{f32}, or @code{f64}.
The range of values an instance of those classes can hold
is the same as the corresponding @code{<@@vector>} class
in @code{gauche.uvector} (@pxref{Uniform vectors}).  That is,
@code{<sparse-u8matrix>} can have exact integer values
between 0 and 255.
@end deftp

@defun make-sparse-matrix :optional type :key default
@c MOD data.sparse
Creates an empty sparse matrix.  The @var{type} argument can be
@code{#f} (default), one of subclasses of @code{<sparse-matrix-base>},
or a symbol of either one of @code{s8}, @code{u8},
@code{s16}, @code{u16}, @code{s32}, @code{u32},
@code{s64}, @code{u64}, @code{f16}, @code{f32}, or @code{f64}.

If @var{type} is omitted or @code{#f}, a @code{<sparse-matrix>} is
created.  If it is a class, an instance of the class is created
(It is an error to pass a class that is not a subclass of
@code{<sparse-matrix-base>}.)
If it is a symbol, an instance of corresponding @code{<sparse-@@matrix>}
is created.

You can specify the default value of the matrix by @var{default}
keyword argument.   If given, the vector behaves as if it is filled
with the default value (but the matrix iterator only picks
the values explicitly set).

Note that you have to give the optional argument as well
to specify the keyword argument.
@end defun

@defun sparse-matrix-num-entries mat
@c MOD data.sparse
Returns the number of entries explicitly set in a sparse matrix @var{mat}.
@end defun

@defun sparse-matrix-ref mat x y :optional fallback
@c MOD data.sparse
Returns an element indexed by (@var{x}, @var{y}) in a sparse matrix @var{mat}.
If the indexed element isn't set, @var{fallback} is returned if provided;
otherwise, if the matrix has the default value, it is returned; otherwise,
an error is raised.
@end defun

@defun sparse-matrix-set! mat x y value
@c MOD data.sparse
Set @var{value} to the sparse matrix @var{mat} at the location
(@var{x}, @var{y}).
@end defun

@defun sparse-matrix-exists? mat x y
@c MOD data.sparse
Returns @code{#t} iff the sparse matrix @var{mat} has a value at
(@var{x}, @var{y}).
@end defun

@defun sparse-matrix-clear! mat
@c MOD data.sparse
Empties the sparse matrix @var{mat}.
@end defun

@defun sparse-matrix-delete! mat x y
@c MOD data.sparse
Remove the value at (@var{x}, @var{y}) from the sparse matrix @var{mat}.
@end defun

@defun sparse-matrix-copy mat
@c MOD data.sparse
Returns a fresh copy of @var{mat}.
@end defun

@defun sparse-matrix-update! mat x y proc :optional fallback
@c MOD data.sparse
Call @var{proc} with the value at (@var{x}, @var{y}) of the sparse matrix,
and sets the result of @var{proc} as the new value of the location.

The optional @var{fallback} argument works just like @code{sparse-matrix-ref};
if provided, it is passed to @var{proc} in case the
matrix doesn't have a value at (@var{x}, @var{y}).
If @var{fallback} isn't provided and the matrix doesn't have a value
at the location, the default value of the matrix is used if it has one.
Otherwise, an error is signalled.
@end defun

@defun sparse-matrix-inc! mat x y delta :optional fallback
@c MOD data.sparse
@example
(sparse-matrix-update! mat x y (cut + <> delta) fallback)
@end example
@end defun

@defun sparse-matrix-push! mat x y val
@c MOD data.sparse
@example
(sparse-matrix-update! mat x y (cut cons val <>) '())
@end example
@end defun

@defun sparse-matrix-pop! mat x y
@c MOD data.sparse
@example
(rlet1 r #f
  (sparse-matrix-update! mat x y (^p (set! r (car p)) (cdr p))))
@end example
@end defun

@defun sparse-matrix-fold mat proc seed
@c MOD data.sparse
Loop over values in the sparse matrix @var{mat}.  The procedure
@var{proc} is called with four arguments, @var{x}, @var{y}, @var{val}
and @var{seed}, for each index (@var{x}, @var{y}) which has the value
@var{val}.  The initial value of @var{seed} is the one given to
@code{sparse-matrix-fold}, and the result of @var{proc} is passed
as the next seed value.  The last result of @var{proc} is returned
from @code{sparse-matrix-fold}.

The procedure @var{proc} is only called on the entries that's actually
has a value, and the order of which the procedure is called is undefined.
@end defun

@defun sparse-matrix-map mat proc
@c MOD data.sparse
@example
(sparse-matrix-fold sv (^[x y v s] (cons (proc x y v) s)) '()))
@end example
@end defun

@defun sparse-matrix-for-each mat proc
@c MOD data.sparse
@example
(sparse-matrix-fold sv (^[x y v _] (proc x y v)) #f))
@end example
@end defun

@defun sparse-matrix-keys mat
@c MOD data.sparse
@example
(sparse-matrix-fold sv (^[x y _ s] (cons (list x y) s)) '())
@end example
@end defun

@defun sparse-matrix-values mat
@c MOD data.sparse
@example
(sparse-matrix-fold sv (^[x y v s] (cons v s)) '())
@end example
@end defun

@node Sparse tables,  , Sparse matrixes, Sparse data containers
@subsection Sparse tables
@c NODE 疎なテーブル

@deftp {Class} <sparse-table>
@clindex sparse-table
@c MOD data.sparse
A class for sparse table.  Inherits @code{<dictionary>} and
@code{<collection>}.

Operationally sparse tables are the same as hash tables, but
the former consumes less memory in trade of slight slower access.
(Roughly x1.5 to x2 access time when the table is small.
As the table gets larger the difference becomes smaller.)
@end deftp

@defun make-sparse-table comparator
@c MOD data.sparse
Creates and returns an empty sparse table.
The @var{comparator} argument specifies how to compare and hash keys;
it must be either a comparator (@pxref{Basic comparators}),
or one of the symbols @code{eq?}, @code{eqv?}, @code{equal?} and
@code{string=?}, like hash tables (@pxref{Hashtables}).   If it is a symbol,
@code{eq-comparator}, @code{eqv-comparator}, @code{equal-comparator} or
@code{string-comparator} are used, respectively.
@end defun

@defun sparse-table-comparator st
@c MOD data.sparse
Returns the comparator used in the sparse table @var{st}.
@end defun

@defun sparse-table-copy st
@c MOD data.sparse
Returns a copy of a sparse table @var{st}.
@end defun

@defun sparse-table-num-entries st
@c MOD data.sparse
Returns the number of entries in a sparse table @var{st}.
@end defun

@defun sparse-table-ref st key :optional fallback
@c MOD data.sparse
Retrieves a value associated to the @var{key} in @var{st}.
If no entry with @var{key} exists, @var{fallback} is returned
when it is provided, or an error is signaled otherwise.
@end defun

@defun sparse-table-set! st key value
@c MOD data.sparse
Sets @var{value} with @var{key} in @var{st}.
@end defun

@defun sparse-table-exists? st key
@c MOD data.sparse
Returns @code{#t} if an entry with @var{key} exists in @var{st},
@code{#f} otherwise.
@end defun

@defun sparse-table-delete! st key
@c MOD data.sparse
Deletes an entry with @var{key} in @var{st} if it exists.
Returns @code{#t} if an entry is actually deleted, or @code{#f}
if there hasn't been an entry with @var{key}.
@end defun

@defun sparse-table-clear! st
@c MOD data.sparse
Empties @var{st}.
@end defun

@defun sparse-table-update! st key proc :optional fallback
@defunx sparse-table-push! st key val
@defunx sparse-table-pop! st key :optional fallback
@c MOD data.sparse
@end defun

@defun sparse-table-fold st proc seed
@defunx sparse-table-for-each st proc
@defunx sparse-table-map st proc
@c MOD data.sparse
@end defun

@defun sparse-table-keys st
@defunx sparse-table-values st
@c MOD data.sparse
@end defun

@c ----------------------------------------------------------------------
@node Trie, Database independent access layer, Sparse data containers, Library modules - Utilities
@section @code{data.trie} - Trie
@c NODE Trie, @code{data.trie} - Trie

@deftp {Module} data.trie
@mdindex data.trie
@c EN
This module provides @emph{Trie}, a dictionary-like data
structure that maps keys to values, where a key is an arbitrary sequence.
Internally it stores the data as a tree where each node corresponds
to each element in the key sequence.
Key lookup is O(n) where n is the length of the key, and not affected
much by the number of total entries.
Also it is easy to find a set of values whose keys share a common prefix.
@c JP
このモジュールは@emph{Trie}を提供します。@emph{Trie}はディレクトリに似
たデータ構造で、キーを値に写像します。また、キーは任意のシーケンスです。
内部的にはデータはツリーとして保持されます。このとき各ノードがキーシー
ケンスの各要素に対応します。キーの検索は O(n) で、n はキーの長さです。
したがって、全体のエントリ数には余り影響を受けません。また、キーが共通
の接頭辞をもつような値の集合を簡単にみつけられます。
@c COMMON

@c EN
The following example may give you the idea.
@c JP
以下のサンプルを見れば考え方が理解できると思います。
@c COMMON

@example
(define t (make-trie))   ;; create a trie

(trie-put! t "pho" 3)    ;; populate the trie
(trie-put! t "phone" 5)
(trie-put! t "phrase" 6)

(trie-get t "phone")  @result{} 5  ;; lookup

(trie-common-prefix t "pho")       ;; common prefix search
  @result{} (("phone" . 5) ("pho" . 3))
(trie-common-prefix-keys t "ph")
  @result{} ("phone" "pho" "phrase")
@end example

@c EN
Tries are frequently used with string keys, but you are not
limited to do so; any sequence (@pxref{Sequence framework}) can be
a key.  If the types of keys differ, they are treated as different
keys:
@c JP
Trieでは文字列キーを使うことが多いですが、それに限定される必要はありま
せん。あらゆるシーケンス(@pxref{Sequence framework})をキーにすることが
できます。キーの型が違えば、別のキーとして扱われます。
@c COMMON

@example
(trie-put! t '(#\p #\h #\o) 8)  ;; different key from "pho"
@end example

@c EN
Trie inherits @code{<collection>} and implements collection framework
including the builder. So you can apply generic collection
operations on a trie (@pxref{Collection framework}).
When iterated, each element of a trie appears as a pair of a key
and a value.
@c JP
Trieは@code{<collection>}を継承しており、コレクションフレームワークを
ビルダも含めて実装しています。それゆえ、ジェネリックなコレクション操作
をTrieに適用することが可能です(@ref{Collection framework}参照)。
反復するとTrieの各要素がキーと値の対として現れます。
@c COMMON
@end deftp

@deftp {Class} <trie>
@clindex trie
@c MOD data.trie
@c EN
A class for Trie.  No slots are intended for public.
Use the following procedures to operate on tries.
@c JP
Trieクラス。パブリックなスロットはありません。trieを操作するには以下の
手続きを使ってください。
@c COMMON

@c EN
This class also implements the dictionary interface
(@pxref{Generic functions for dictionaries}).
@c JP
このクラスはまた、ディクショナリインタフェースを実装しています
(@ref{Generic functions for dictionaries}参照)。
@c COMMON
@end deftp

@defun make-trie :optional tab-make tab-get tab-put! tab-fold tab-empty?
@c MOD data.trie
@c EN
Creates and returns an empty trie.  The optional arguments
are procedures to customize how the nodes of the internal
tree are managed.
@c JP
空のtrieを生成し返します。オプション引数は、
内部木のノードをどのようにマージするかをカスタマイズする手続きです。
@c COMMON

@c EN
Each node can have a table to store its child nodes, indexed
by an element of the key sequence (e.g. if the trie uses strings
as keys, a node's table is indexed by characters).
@c JP
それぞれのノードは子のノードを格納するテーブルを持つことができます。
キーシーケンスの要素でインデックスできます。(たとえば、trieがキーとし
え文字列を使っているとすると、ノードのテーブルは文字でインデックスされ
ています。)
@c COMMON

@c EN
@table @code
@item tab-make
A procedure with no arguments.  When called, creates and
returns an empty table for a node.
@item tab-get @var{tab} @var{elt}
Returns a child node indexed by @var{elt}, or returns @code{#f}
if the table doesn't have a child for @var{elt}.
@item tab-put! @var{tab} @var{elt} @var{child-node}
If @var{child-node} isn't @code{#f},
stores a @var{child-node} with index @var{elt}.
If @var{child-node} is @code{#f},
removes the entry with index @var{elt}.
In both cases, this procedure should return the updated table.
@item tab-fold @var{tab} @var{proc} @var{seed}
Calls @var{proc} for every index and node in @var{tab}, while
passing a seed value, whose initial value is @var{seed}.
That is, @var{proc} has a type of @code{(index, node, seed) -> seed}.
Should return the last result of @var{proc}.
@item tab-empty? @var{tab}
Returns @code{#t} if @var{tab} is empty, @code{#f} otherwise.
You can omit or pass @code{#f} to this procedure; then we use
@code{tab-fold} to check if @var{tab} is empty, which can be expensive.
@end table
@c JP
@table @code
@item tab-make
引数なしの手続き。呼ばれるとノード用の空テーブルを生成し返します。
@item tab-get @var{tab} @var{elt}
@var{elt}でインデックスされた子ノードを返すか、あるいは@var{elt}に対応
する子がテーブルにない場合には @code{#f}を返します。
@item tab-put! @var{tab} @var{elt} @var{child-node}
@var{child-node}が@code{#f}でなければ、@var{child-node}に@var{elt}とい
うインデックスをつけて保存します。@var{child-node}が@code{#f}なら
@var{elt}のインデックスをもつエントリを削除します。どちらの場合にも
この手続きは更新されたテーブルを返します。
@item tab-fold @var{tab} @var{proc} @var{seed}
@var{tab}内の各インデックスと要素ごとに@var{proc}を呼びます。シード値
が順に渡されていきます。シード値の初期値は@var{seed}です。すなわち、
@var{proc}の型は@code{(index, node, seed) -> seed} のような型というこ
とになります。返り値は最後の@var{proc}の適用結果です。
@item tab-empty? @var{tab}
@var{tab}が空なら@code{#t}を、そうでなければ@code{#f}を返す手続きです。
この手続きは省略するか@code{#f}を渡すことができます。その場合は空かどうかを
チェックするのに@code{tab-fold}手続きが使われますが、少々重くなるかもしれません。
@end table
@c COMMON

@c EN
The default assumes @code{eqv?}-hashtables, i.e. the
following procedures are used.
@c JP
デフォルトでは@code{eqv?}-ハッシュ可能であることが仮定されます。すなわ
ち、以下の手続きが使われます。
@c COMMON

@example
tab-make: (lambda () (make-hash-table 'eqv?))

tab-get:  (lambda (tab k) (hash-table-get tab k #f))

tab-put!: (lambda (tab k v)
            (if v
              (hash-table-put! tab k v)
              (hash-table-delete! tab k))
            tab)

tab-fold: hash-table-fold

tab-empty?: (lambda (tab) (zero? (hash-table-num-entries tab)))
@end example

@c EN
The following example creates a trie using
assoc list to manage children, while comparing
string keys with case-insensitive way:
@c JP
以下の例では子を管理するのに連想リストを用いるtrieを作成しています。
文字列キーの比較は大文字小文字を無視する方法で行っています。
@c COMMON

@example
(make-trie list
           (cut assoc-ref <> <> #f char-ci=?)
           (lambda (t k v)
             (if v
               (assoc-set! t k v char-ci=?)
               (alist-delete! k t char-ci=?)))
           (lambda (t f s) (fold f s t))
           null?)
@end example

@c EN
It is important that @code{tab-put!} must return an updated
table---by that, you can replace the table structure on the fly.
For example, you may design a table which uses assoc list when
the number of children are small, and then switches to a vector
(indexed by character code) once the number of children grows over
a certain threshold.
@c JP
@code{tab-put!}が更新されたテーブルを返すというのは重要で、これのおか
げで、テーブル構造を実行中に置き換えることができます。たとえば、
子の数が少い場合にはテーブルに連想リストを使い、いったん子の数がある閾
値を越えたら、(文字コードでインデックスされた)ベクタを使うように設計す
ることができます。
@c COMMON
@end defun

@defun trie params kv @dots{}
@c MOD data.trie
@c EN
Construct a trie with the initial contents
@var{kv} @dots{}, where each @var{kv} is a pair of a key and a value.
@var{Params} are a list of arguments
which will be given to @code{make-trie} to create the trie.
The following example creates a trie with two entries
and the default table procedures.
@c JP
初期の内容が@var{kv} @dots{} であるようなtrieを構成します。ここで、
@var{kv}はキーと値の対です。@var{params}はtrieを生成するときに
@code{make-trie}に渡される引数のリストです。以下の例は2つのエントリ
とデフォルトのテーブル手続をもつtrieを生成します。
@c COMMON

@example
(trie '() '("foo" . a) '("bar" . b))
@end example
@end defun

@defun trie-with-keys params key @dots{}
@c MOD data.trie
@c EN
A convenient version of @code{trie} when you only concern
the keys.  Each value is the same as its key.
The following example creates a trie with two entries
and the default table procedures.
@c JP
キーにだけ関心がある場合には便利な@code{trie}。各値はキーと同じ。以下
の例では2つのエントリとデフォルトのテーブル手続をもつtrieを生成します。
@c COMMON

@example
(trie-with-keys '() "foo" "bar")
@end example
@end defun

@defun trie? obj
@c MOD data.trie
@c EN
Returns @code{#t} if @var{obj} is a trie, or @code{#f} otherwise.
@c JP
@var{obj}がtrieなら@code{#t}を返し、さもなければ@code{#f}を返します。
@c COMMON
@end defun

@defun trie-num-entries trie
@c MOD data.trie
@c EN
Returns the number of entries in @var{trie}.
@c JP
@var{trie}中のエントリの数を返します。
@c COMMON
@end defun

@defun trie-exists? trie key
@c MOD data.trie
@c EN
Returns @code{#t} if @var{trie} contains an entry with @var{key},
or returns @code{#f} otherwise.
@c JP
@var{trie}が@var{key}というキーのエントリを含む場合には@code{#t}を返し、
さもなければ、@code{#f}を返します。
@c COMMON

@example
(let1 t (trie '() '("foo" . ok))
  (list (trie-exists? t "foo")
        (trie-exists? t "fo")
        (trie-exists? t "bar")))
  @result{} '(#t #f #f)
@end example
@end defun

@defun trie-partial-key? trie seq
@c MOD data.trie
@c EN
Returns @code{#t} if there's at least one key in @var{trie} that is
not equal to @var{seq} but @var{seq} matches its prefix.   Note that
@var{seq} may or may not a key of @var{trie}; see the example below.
@c JP
@var{trie}の中に少なくともひとつ、@var{seq}と同じではないが@var{seq}を
プリフィクスとするようなキーがあれば@code{#t}を返します。
@var{seq}と一致するキーが他にあるかないかは結果には影響を及ぼしません。
下の例を見てください。
@c COMMON

@example
(define t (trie '() '("foo" . ok) '("fo" . ok)))

(trie-partial-key? t "f")    @result{} #t
(trie-partial-key? t "fo")   @result{} #t
(trie-partial-key? t "foo")  @result{} #f
(trie-partial-key? t "bar")  @result{} #f
@end example
@end defun


@defun trie-get trie key :optional fallback
@c MOD data.trie
@c EN
Returns the value associated with @var{key} in @var{trie}, if
such an entry exists.  When there's no entry for @var{key},
if @var{fallback} is given, it is returned; otherwise,
an error is signaled.
@c JP
@var{trie}中の@var{key}をもつエントリがあれば、それにむすびついている
値を返します。そのようなエントリがない場合、@var{fallback}が与えられて
いればそれを返し、さもなければ、エラーシグナルがあがります。
@c COMMON
@end defun

@defun trie-put! trie key value
@c MOD data.trie
@c EN
Puts @var{value} associated to @var{key} into @var{trie}.
@c JP
@var{key}に結びついた@var{value}を@var{trie}に挿入します。
@c COMMON
@end defun

@defun trie-update! trie key proc :optional fallback
@c MOD data.trie
@c EN
Works like the following code, except that the
lookup of entry in @var{trie} is done only once.
@c JP
@var{trie}中のエントリの検索が一度きりしか起らないことをのぞけば以下の
コードのように動きます。
@c COMMON

@example
(let ((val (trie-get trie key fallback)))
  (trie-put! trie key (proc val)))
@end example
@end defun

@defun trie-delete! trie key
@c MOD data.trie
@c EN
Removes an entry associated with @var{key} from @var{trie}.
If there's no such entry, this procedure does nothing.
@c JP
@var{trie}から@var{key}に関連するエントリを削除します。
そのようなエントリがない場合にはこの手続きはなにもしません。
@c COMMON
@end defun

@defun trie->list trie
@c MOD data.trie
@c EN
Makes each entry in @var{trie} to a pair @code{(@var{key} . @var{value})}
and returns a list of pairs of all entries.  The order of entries
are undefined.
@c JP
@var{trie}の各エントリを@code{(@var{key} . @var{value})}という対にして
すべてのエントリの対のリストを返します。エントリの順序は未定義です。
@c COMMON
@end defun

@defun trie-keys trie
@defunx trie-values trie
@c MOD data.trie
@c EN
Returns a list of all keys and values in @var{trie}, respectively.
The order of keys/values are undefined.
@c JP
それぞれ、@var{trie}のすべてのキーのリスト、すべての値のリストを返しま
す。順序は未定義です。
@c COMMON
@end defun

@defun trie->hash-table trie ht-type
@c MOD data.trie
@c EN
Creates a hash table with type @var{ht-type} (see @ref{Hashtables},
about hash table types), and populates it with every key and value
pair in @var{trie}.
@c JP
@var{ht-type}タイプのハッシュテーブル(ハッシュテーブルのタイプについて
は@ref{Hashtables}を参照)を作成し、@var{trie}のすべてのキーと値の対を
セットします。
@c COMMON
@end defun

@defun trie-longest-match trie seq :optional fallback
@c MOD data.trie
@c EN
Returns a pair of the key and its value, where the key is the
longest prefix of @var{seq}.   If no such key is found, @var{fallback}
is returned if it is provided, or an error is thrown.

Do not confuse this with @code{trie-common-prefix-*} procedures below;
In this procedure, the key is the prefix of the given argument.
In @code{trie-common-prefix-*} procedures, the given argument is
the prefix of the keys.
@c JP
@var{seq}のプレフィクスになっているキーのうちもっとも長いものを見つけて、
そのキーと値のペアを返します。そういったキーが見つからなかった場合は、
@var{fallback}が与えられればそれを返し、なければエラーが通知されます。

この手続きと以下の@code{trie-common-prefix-*}手続きを混同しないようにしてください。
この手続きでは、キーが引数のプレフィクスです。
@code{trie-common-prefix-*}手続きでは、引数がキーのプレフィクスです。
@c COMMON

@example
(let1 t (make-trie)
  (trie-put! t "a"  'a)
  (trie-put! t "ab" 'ab)

  (trie-longest-match t "abc")  @result{} ("ab" . ab)
  (trie-longest-match t "acd")  @result{} ("a"  . a)
  (trie-longest-match t "ab")   @result{} ("ab" . ab)
  (trie-longest-match t "zy")   @result{} error
  )
@end example
@end defun


@defun trie-common-prefix trie prefix
@defunx trie-common-prefix-keys trie prefix
@defunx trie-common-prefix-values trie prefix
@c MOD data.trie
@c EN
Gathers all entries whose keys begin with @var{prefix};
@code{trie-common-prefix} returns those entries in a list of
pairs @code{(key . value)}; @code{trie-common-prefix-keys} returns
a list of keys; and @code{trie-common-prefix-values} returns a list
of values.   The order of entries in a returned list is undefined.
If @var{trie} contains no entry whose key has @var{prefix}, an
empty list is returned.
@c JP
@var{prefix}ではじまるキーをもつエントリをすべて集め、
@code{trie-common-prefix}はその各エントリを@code{(key . value)}の対にし
たリストを返します。@code{trie-common-prefix-keys}は、キーのリストを
@code{trie-common-prefix-values}は値のリストを返します。返されるリスト
のエントリの順序は未定義です。
@var{trie}に指定した@var{prefix}をもつキーのエントリがなければ、
空リストが返されます。
@c COMMON

@c EN
Note that prefix matching doesn't consider the type of sequence;
if @var{trie} has entries for @code{"foo"} and @code{(#\f #\o #\o)},
@code{(trie-common-prefix trie "foo")} will return both entries.
@c JP
接頭辞照合ではシーケンスの型を考慮しないことに注意してください。
@var{trie}のなかに@code{"foo"}と@code{(#\f #\o #\o)}に対応するエントリ
があれば、@code{(trie-common-prefix trie "foo")}はその両方を返します。
@c COMMON
@end defun

@defun trie-common-prefix-fold trie prefix proc seed
@c MOD data.trie
@c EN
For each entry whose key begins with @var{prefix},
calls @var{proc} with three arguments, the entry's key,
its value, and the current seed value.  @var{Seed} is
used for the first seed value, and the value @var{proc}
returns is used for the seed value of the next call of @var{proc}.
The last returned value from @var{proc} is returned from
@code{trie-common-prefix-fold}.
The order of entries on which @var{proc} is called is undefined.
If @var{trie} contains no entry whose key has @var{prefix},
@var{proc} is never called and @var{seed} is returned.
@c JP
@var{prefix}ではじまるキーをもつ各エントリに対して、@var{proc}を3つの
引数、エントリのキー、値、現在のシード値で呼びます。@var{seed}は最初の
シード値として使われ、@var{proc}が返す値は次の@var{proc}の呼び出しのシー
ド値として使われます。@var{proc}が返した最後の値が
@code{trie-common-prefix-fold}から返ります。
@var{proc}が適用される順序は未定義です。@var{trie}が@var{prefix}を持つ
キーのエントリを含まない場合には@var{proc}が呼ばれることはなく、
@var{seed}が返ります。
@c COMMON
@end defun

@defun trie-common-prefix-map trie prefix proc
@defunx trie-common-prefix-for-each trie prefix proc
@c MOD data.trie
@c EN
These are to @var{trie-common-prefix-fold} as @code{map} and @code{for-each}
are to @code{fold}; @code{trie-common-prefix-map} calls
@var{proc} with key and value for matching entries and
gathers its result to a list; @code{trie-common-prefix-for-each}
also applies @var{proc}, but discards its results.
@c JP
@code{map}や@code{for-each}を@code{fold}を合せたのと同じように、
@var{trie-common-prefix-fold}に合せたものです。
@code{trie-common-prefix-map}は@var{proc}をマッチするエントリのキーと
値に適用し結果をリストにあつめます。
@code{trie-common-prefix-for-each}も同じく@var{proc}を適用しますが
結果は捨てます。
@c COMMON
@end defun

@defun trie-fold trie proc seed
@defunx trie-map trie proc
@defunx trie-for-each trie proc
@c MOD data.trie
@c EN
These procedures are like their common-prefix versions, but
traverse entire @var{trie} instead.
@c JP
これらの手続きはcommon-prefix版とおなじような働きをしますが、
@var{trie}全体をトラバースします。
@c COMMON
@end defun




@c ----------------------------------------------------------------------

@node Database independent access layer, Generic DBM interface, Trie, Library modules - Utilities
@section @code{dbi} - Database independent access layer
@c NODE データベース非依存アクセス層, @code{dbi} - データベース非依存アクセス層

@deftp {Module} dbi
@mdindex dbi
@c EN
This module provides the unified interface to access various
relational database systems (RDBMS).  The operations specific
to individual database systems are packaged
in database driver (DBD) modules, which is usually loaded
implicitly by DBI layer.
@c JP
このモジュールはさまざまなリレーショナルデータベースシステム(RDBMS)に
アクセスするための統一されたインタフェースを提供します。個々のデータベー
スシステムに特有の操作についてはデータベースドライバ(DBD)モジュールに
パッケージされています。DBDのモジュールは通常暗黙裏にDBIの層からロード
されます。
@c COMMON

@c EN
The module is strongly influenced by Perl's DBI/DBD architecture.
If you have used Perl DBI, it would be easy to use this module.
@c JP
このモジュールは Perl の DBI/DBD アーキテクチャに強く影響を受けていま
す。Perl DBIを使った経験があるなら、このモジュールを使うのはたやすいで
しょう。
@c COMMON
@end deftp

@c EN
It's better to look at the example.  This is a simple outline
of accessing a database by @code{dbi} module:
@c JP
まず例を見るほうがよいでしょう。以下は@code{dbi}モジュールを使ったデー
タベースアクセス例の概要です。
@c COMMON

@example
(use dbi)
(use gauche.collection) ; to make 'map' work on the query result

(guard (e ((<dbi-error> e)
           ;; handle error
           ))
  (let* ((conn   (dbi-connect "dbi:mysql:test;host=dbhost"))
         (query  (dbi-prepare conn
                   "SELECT id, name FROM users WHERE department = ?"))
         (result (dbi-execute query "R&D"))
         (getter (relation-accessor result)))
    (map (lambda (row)
           (list (getter row "id")
                 (getter row "name")))
         result)))
@end example

@c EN
There's nothing specific to the underlying database system
except the argument @code{"dbi:mysql:test;host=dbhost"}
passed to @code{dbi-connect}, from which @code{dbi} module
figures out that it is an access to @code{mysql} database,
loads @code{dbd.mysql} module, and let it handle the mysql-specific
stuff.  If you want to use whatever database system, you can just
pass @code{"dbi:@var{whatever}:@var{parameter}"} to @code{dbi-connect}
instead, and everything stays the same as far as you have
@code{dbd.whatever} installed in your system.
@c JP
@code{dbi-connect}にわたす、@code{"dbi:mysql:test;host=dbhost"}引数以
外は使用するデータベースシステムに依存する部分はありません。この引数に
より、@code{dbi}モジュールはこのアクセスが@code{mysql}データベースに対
するものであると判断します。そして、mysql-特有の手続を扱うようにします。
別のデータベースシステムwhateverを使いたいのであれば、単に
@code{"dbi:@var{whatever}:@var{parameter}"}を@code{dbi-connect}に渡せ
ばよく、@code{dbd.whatever}がシステムにインストールされていれば同じよ
うにできます。
@c COMMON

@c EN
A query to the database can be created by @code{dbi-prepare}.
You can issue the query by @code{dbi-execute}.  This two-phase
approach allows you to create a prepared query, which is a kind of
parameterized SQL statement.  In the above example the query
takes one parameter, denoted as @code{'?'} in the SQL.
The actual value is given in @code{dbi-execute}.  When you
issue similar queries a lot, creating a prepared query and
execute it with different parameters may give you performance gain.
Also the parameter is automatically quoted.
@c JP
データベースに対するクエリは@code{dbi-prepare}を使って作成します。
クエリの発行は@code{dbi-execute}で行います。このような2つのフェーズを
使うことで、パラメータ化されたSQL文の一種であるプリペアドクエリを
作ることができます。上の例ではクエリはSQL文の中で@code{'?'}で表現され
ている部分に、ひとつの引数をわりあてます。実引数の値は
@code{dbi-execute}で設定されます。類似のクエリを大量に発行するような場
合にはプリペアドクエリをひとつ生成し、それにさまざまなパラメータを渡し
て実行するとパフォーマンスがかせげます。このパラメータは自動的にクォー
トされます。
@c COMMON

@c EN
When the query is a @code{SELECT} statement,
its result is returned as a collection that implements
the relation protocol.  See @ref{Collection framework}
and @ref{Relation framework} for the details.
@c JP
クエリが@code{SELECT}文の場合、その結果は関係プロトコルを実装するコレ
クションとして返されます。詳細は@ref{Collection framework}および
@ref{Relation framework}を見てください。
@c COMMON

@c EN
The outermost @code{guard} is to catch errors.  The @code{dbi} related
errors are supposed to inherit @code{<dbi-error>} condition.
There are a few specific errors defined in @code{dbi} module.
A specific @code{dbd} layer may define more specific errors.
@c JP
いちばん外側にある@code{guard}はエラーを捕捉するためのものです。
@code{dbi}に関連したエラーは@code{<dbi-error>}コンディションを継承して
いるものと見なされます。いくつかの特有のエラーは@code{dbi}モジュールで
定義されています。特定の@code{dbd}層はさらに固有のエラーを定義していま
す。
@c COMMON

@c EN
In the next section we describe user-level API, that is,
the procedures you need to concern when you're using @code{dbi}.
The following section is for the driver API, which you need to use
to write a specific @code{dbd} driver to make it work with @code{dbi}
framework.
@c JP
次節ではユーザレベルのAPIについて説明します。すなわち、@code{dbi}を使
う際に必要となる手続に関する説明です。そのあとのセクションではドライバ
APIを説明をします。すなわち特定の@code{dbd}ドライバを@code{dbi}フレー
ムワークで使えるようにするために使うAPIの説明です。
@c COMMON

@menu
* DBI user API::
* Writing drivers for DBI::
@end menu

@node DBI user API, Writing drivers for DBI, Database independent access layer, Database independent access layer
@subsection DBI user API
@c NODE DBIのユーザAPI

@c EN
@subsubheading DBI Conditions
@c JP
@subsubheading DBIのコンディション
@c COMMON

@c EN
There are several predefined conditions @code{dbi} API may throw.
See @ref{Exceptions} for the details of conditions.
@c JP
@code{dbi} API が投げる可能性のあるコンディションがいくつか定義されて
います。コンディションの詳細については@ref{Exceptions}を見てください。
@c COMMON

@deftp {Condition Type} <dbi-error>
@c MOD dbi
@c EN
The base class of @code{dbi}-related conditions.  Inherits @code{<error>}.
@c JP
@code{dbi}-関連のコンディションのベースクラス。@code{<error>}を継承し
ています。
@c COMMON
@end deftp

@deftp {Condition Type} <dbi-nonexistent-driver-error>
@c MOD dbi
@c EN
This condition is thrown by @code{dbi-connect} when it cannot
find the specified driver.  Inherits @code{<dbi-error>}.
@c JP
@code{dbi-connect}は指定されたドライバが見つからない場合にこのコンディ
ションを投げます。@code{<dbi-error>}を継承しています。
@c COMMON

@defivar <dbi-nonexistent-driver-error> driver-name
@c EN
Holds the requested driver name as a string.
@c JP
要求されたドライバの名前を文字列として保持している。
@c COMMON
@end defivar
@end deftp

@deftp {Condition Type} <dbi-unsupported-error>
@c MOD dbi
@c EN
This condition is thrown when the called method isn't supported
by the underlying driver.  Inherits @code{<dbi-error>}.
@c JP
呼び出されたメソッドが基盤となるドライバでサポートされていない場合、こ
のコンディションが投げられます。@code{<dbi-error>}を継承しています。
@c COMMON
@end deftp

@deftp {Condition Type} <dbi-parameter-error>
@c MOD dbi
@c EN
This condition is thrown when the number of parameters given to
the prepared query doesn't match the ones in the prepared statement.
@c JP
プリペアドクエリへ渡されたパラメータの数がプリペアドステートメントの中
のものと一致しないとき、このコンディションが投げられます。
@c COMMON
@end deftp

@c EN
Besides these errors, if a driver relies on @code{dbi} to
parse the prepared SQL statement, @code{<sql-parse-error>} may
be thrown if an invalid SQL statement is passed to @code{dbi-prepare}.
(@pxref{SQL parsing and construction}).
@c JP
上の3つのエラー以外に、@code{dbi}がプリペアドSQL文を構文解析するのにド
ライバを利用す場合、不正なSQL文が@code{dbi-prepare}に渡されると、
@code{<sql-parse-error>}が投げられます
(@ref{SQL parsing and construction}参照)。
@c COMMON

@c EN
@subsubheading Connecting to the database
@c JP
@subsubheading データベースへの接続
@c COMMON

@defun dbi-connect dsn :key username password
@c MOD dbi
@c EN
Connect to a database using a data source specified by @var{dsn}
(data source name).  @var{Dsn} is a string with the following syntax:
@c JP
@var{dsn}(データソース名)で指定されたデータソースを使ってデータベース
に接続します。@var{dsn}は以下の構文をもつ文字列です。
@c COMMON
@example
dbi:@var{driver}:@var{options}
@end example

@c EN
@var{Driver} part names a specific driver.  You need to have the
corresponding driver module, @code{dbd.@var{driver}}, installed in
your system.  For example, if @var{dsn} begins with @code{"dbi:mysql:"},
@code{dbi-connect} tries to load @code{dbd.mysql}.
@c JP
@var{driver}は特定のドライバ名です。対応するドライバモジュールがなけれ
ばなりません。すなわち、@code{dbd.@var{driver}}がシステムにインストー
ルされていなければなりません。たとえば、@var{dsn}が@code{"dbi:mysql:"}
ではじまるとすると、@code{dbi-connect}は@code{dbd.mysql}をロードしよう
とします。
@c COMMON

@c EN
Interpretation of the @var{options} part is up to the driver.
Usually it is in the form of @code{key1=value1;key2=value2;...},
but some driver may interpret it differently.  For example,
@code{mysql} driver allows you to specify a database name
at the beginning of @var{options}.   You have to check out
the document of each driver for the exact specification of
@var{options}.
@c JP
@var{options}部分の解釈はドライバに依存します。通常この部分のフォーマッ
トは@code{key1=value1;key2=value2;...}のようになっていますが、ドライバ
によっては別の解釈になります。たとえば、@code{mysql}ドライバでは、
@var{options}の最初の部分でデータベース名を指定することができます。
@var{options}の正確な仕様については各ドライバのドキュメントをチェック
してください。
@c COMMON

@c EN
The keyword arguments gives extra information required for
connection.  The @var{username} and @var{password} are commonly
supported arguments.  The driver may recognize more keyword arguments.
@c JP
接続のために必要な追加情報はキーワード引数であたえます。
@var{username}および@var{password}は共通でサポートされている引数です。
ドライバは他にもキーワード引数を認識します。
@c COMMON

@c EN
If a connection to the database is successfully established,
a connection object (an instance of a subclass of @code{<dbi-connection>})
is returned.  Otherwise, an error is signaled.
@c JP
データベースへの接続が成功したら、コネクションオブジェクト
(@code{<dbi-connection>}のサブクラスのインスタンス)が返ります。さもな
ければ、エラーがあがります。
@c COMMON
@end defun

@deftp {Class} <dbi-connection>
@clindex dbi-connection
@c MOD dbi
@c EN
The base class of a connection to a database system.
Each driver defines a subclass of this to keep information about
database-specific connections.
@c JP
データベースシステムへの接続のベースクラス。各ドライバはこのクラスのサ
ブクラスを定義し、これにデータベース特有のコネクションに関する情報を持
たせます。
@c COMMON
@end deftp

@deffn {Method} dbi-open? (c <dbi-connection>)
@c MOD dbi
@c EN
Queries whether a connection to the database is still open (active).
@c JP
データベースへの接続がオープン状態(アクティブ状態)にあるかどうかを確か
めます。
@c COMMON
@end deffn

@deffn {Method} dbi-close (c <dbi-connection>)
@c MOD dbi
@c EN
Closes a connection to the database.  This causes releasing resources
related to this connection.   Once closed, @var{c} cannot
be used for any dbi operations (except passing to @code{dbi-open?}).
Calling @code{dbi-close} on an already closed connection has no effect.
@c JP
データベースへの接続を閉じます。これによりこの接続に関連付けられたリソー
スが解放されます。いったん閉じた@var{c}に対してはどのようなdbi操作もで
きません。(@code{dbi-open?}だけは例外)。すでに閉じられたコネクションに
対して@code{dbi-close}を呼んでもなにも起りません。
@c COMMON

@c EN
Although a driver usually closes a connection when @code{<dbi-connection>}
object is garbage-collected, it is not a good idea to rely on that,
since the timing of GC is unpredictable.  The user program must make
sure that it calls @code{dbi-close} at a proper moment.
@c JP
ドライバは通常@code{<dbi-connection>}がガベージコレクションされたとき
にコネクションを閉じますが、このことを期待したコードを書くのはいただけ
ません。GCのタイミングというのは予測不可能だからです。ユーザプログラム
は適切なタイミングで@code{dbi-close}を呼ぶようにすべきです。
@c COMMON
@end deffn

@defun dbi-list-drivers
@c MOD dbi
@c EN
Returns a list of module names of known drivers.
@c JP
解っているドライバのモジュール名のリストを返します。
@c COMMON
@end defun

@deftp {Class} <dbi-driver>
@clindex dbi-driver
@c MOD dbi
@c EN
The base class of a driver.  You usually don't need to see this
as far as you're using the high-level @code{dbi} API.
@c JP
ドライバのベースクラス。高レベルの@code{dbi} APIを使うかぎり、これが必
要になることはありません。
@c COMMON
@end deftp

@defun dbi-make-driver driver-name
@c MOD dbi
@c EN
This is a low-level function called from @code{dbi-connect} method,
and usually a user doesn't need to call it.
@c JP
@code{dbi-connect}から呼ばれる低レベル関数、通常この関数を呼ぶ必要はあ
りません。
@c COMMON

@c EN
Loads a driver module specified by @var{driver-name}, and
instantiate the driver class and returns it.
@c JP
@var{driver-name}で指定されたドライバモジュールをロードし、当該のドラ
イバクラスのインスタンスを生成してそれを返します。
@c COMMON
@end defun

@c EN
@subsubheading Preparing and issuing queries
@c JP
@subsubheading クエリの準備と発行
@c COMMON

@deffn {Method} dbi-prepare conn sql :key pass-through @dots{}
@c MOD dbi
@c EN
From a string representation of SQL statement @var{sql},
creates and returns a query object (an instance of @code{<dbi-query>}
or its subclass) for the database connection @code{conn}
@c JP
SQL文の文字列表現@var{sql}からデータベースコネクション@code{conn}用の
クエリオブジェクト(@code{<dbi-query>}のインスタンスもしくはそのサブク
ラスのインスタンス)を生成してそれを返します。
@c COMMON

@c EN
@var{Sql} may contain parameter slots, denoted by @code{?}.
@c JP
@var{sql}は@code{?}であらわされているパラメータスロットを持ちます。
@c COMMON
@example
(dbi-prepare conn "insert into tab (col1, col2) values (?, ?)")

(dbi-prepare conn "select * from tab where col1 = ?")
@end example

@c EN
They will be filled when you actually issue the query by
@code{dbi-execute}.
There are some advantages of using parameter
slots: (1) The necessary quoting is done automatically.
You don't need to concern about security holes caused by
improper quoting, for example.
(2) Some drivers support a feature to send the template SQL
statement to the server at the preparation stage, and send
only the parameter values at the execution stage.  It would be
more efficient if you issue similar queries lots of time.
@c JP
これらのスロットは@code{dbi-execute}を使って実際にクエリを発行したとき
に埋められます。パラメータスロットを使うのは以下の利点があるからです。
(1) クォートが自動的にほどこされます。不適切なクォートによるセキュリティ
ホールを気にする必要はありません。
(2) いくつかのドライバでは準備の段階でサーバへテンプレートSQL文を送る
機能がサポートされていて、実行段階ではパラメータを送るだけで済みます。
これは似たようなクエリを大量に一度に発行するときには効率のよいやりかた
です。
@c COMMON

@c EN
If the backend doesn't support prepared statements (SQL templates
having @code{?} parameters), the driver may use @code{text.sql}
module to parse @var{sql}.  It may raise @code{<sql-parse-error>}
condition if the given SQL is not well formed.
@c JP
バックエンドでプリペアド文がサポートされていない場合(でSQLテンプレー
トが@code{?}パラメータを持つ場合)、ドライバは@var{sql}を解析するのに
@code{text.sql}モジュールを使います。与えられたSQL文が正しい構文でなけ
れば、@code{<sql-parse-error>}コンディションが発生します。
@c COMMON

@c EN
You may pass a true value to the keyword argument @var{pass-through}
to suppress interpretation of SQL and pass @var{sql} as-is to the
back end database system.  It is useful if the back-end supports
extension of SQL which @code{text.sql} doesn't understand.
@c JP
キーワード引数@var{pass-through}に真の値を渡して、SQLの解釈を抑制し、
@var{sql}をそのままバックエンドのデータベースシステムに渡すことができ
ます。@code{text.sql}で理解できないようなSQLの拡張をバックエンドがサポー
トしている場合に役立ちます。
@c COMMON

@c EN
If the driver lets prepared statement handled in back-end,
without using @code{text.sql}, the @code{pass-through} argument
may be ignored.
The driver may also take other keyword arguments.  Check out
the documentation of individual drivers.
@c JP
ドライバがプリペアド文を@code{text.sql}抜きでバックエンドに処理させた
場合、@code{pass-through}引数は無視されます。ドライバは他のキーワード
引数を取ることもあります。詳細はそれぞれのドライバのドキュメントを参照
してください。
@c COMMON

@c EN
@emph{Note:} Case folding of SQL statement
is implementation dependent.  Some DBMS may treat table
names and column names in case insensitive way, while
others do in case sensitive way.  To write a portable
SQL statement, make them quoted identifiers, that is,
always surround names by double quotes.
@c JP
@emph{注意}：SQL文のケース畳み込みは実装依存です。DBMSのなかにはテーブ
ル名やカラム名は大文字小文字の区別をしないものもあり、一方で区別するも
のもあります。ポータブルなSQL文を書きたいのなら、識別子をクォートしま
しょう。すなわち常に名前をダブルクォートで囲むようにします。
@c COMMON
@end deffn

@deftp {Class} <dbi-query>
@clindex dbi-query
@c MOD dbi
@c EN
Holds information about prepared query, created by @code{dbi-prepare}.
The following slots are defined.
@c JP
@code{dbi-prepare}によって作成されたプリペアドクエリに関する情報を保持
します。以下のスロットが定義されています。
@c COMMON

@defivar <dbi-query> connection
@c EN
Contains the @code{<dbi-connection>} object.
@c JP
@code{<dbi-connection>}オブジェクトを含みます。
@c COMMON
@end defivar

@defivar <dbi-query> prepared
@c EN
If the driver prepares query by itself, this slot may contain
a prepared statement.  It is up to each driver how to use
this slot, so the client shouldn't rely on its value.
@c JP
ドライバがクエリを準備する場合、このスロットがプリペアド文を保持します。
このスロットをどのように使うかはおのおののドライバによります。したがっ
て、クライアントはこの値に依存してはいけません。
@c COMMON
@end defivar

@end deftp

@deffn {Method} dbi-open? (q <dbi-query>)
@c MOD dbi
@c EN
Returns @code{#t} iff the query can still be passed to
@code{dbi-execute}.
@c JP
クエリが@code{dbi-execute}に渡せる状態になっているときにのみ、
@code{#t}を返します。
@c COMMON
@end deffn

@deffn {Method} dbi-close (q <dbi-query>)
@c MOD dbi
@c EN
Destroy the query and free resources associated to the query.
After this operation, @code{dbi-open?} returns @code{#f} for @var{q},
and the query can't be used in any other way.  Although the resource
may be freed when @var{q} is garbage-collected, it is strongly recommended
that the application closes queries explicitly.
@c JP
クエリを破棄し、当該クエリに関連づけられたリソースを解放します。この操
作を実行後は、@code{dbi-open?}は@var{q}に対して@code{#f}を返します。
そして、当該クエリは他の用途にはつかえません。@var{q}がガベージコレク
ションにより回収された場合、リソースは解放されますが、アプリケーション
が明示的にクエリを閉じるようにすることを強く勧めます。
@c COMMON
@end deffn

@deffn {Method} dbi-execute (q <dbi-query>) parameter @dots{}
@c MOD dbi
@c EN
Executes a query created by @code{dbi-prepare}.  You should pass
the same number of @var{parameter}s as the query expects.
@c JP
@code{dbi-prepare}によって作成さればクエリを実行します。当該クエリが期
待するのと同じ数のパラメータを渡す必要があります。
@c COMMON

@c EN
If the issued query is @code{select} statement, @code{dbi-execute}
returns an object represents a @emph{relation}.
A relation encapsulates the values in
rows and columns, as well as meta information like column names.
See "Retrieving query results" below for how to access the result.
@c JP
発行されたクエリが@code{select}文の場合@code{dbi-execute}は
@emph{リレーション}を表わすオブジェクトを返します。リレーションは
行とカラムの値をカプセル化したもので、カラム名のようなメタ情報も同様で
す。結果へアクセスの方法については後述の「クエリの結果を見る」を見てく
ださい。
@c COMMON

@c EN
If the query is other types, such as @code{create}, @code{insert}
or @code{delete}, the return value of the query closure is unspecified.
@c JP
クエリがSELECT以外の@code{create}、@code{insert}、@code{delete}などの
場合、クエリクロージャー返り値は不定です。
@c COMMON
@end deffn

@deffn {Method} dbi-do conn sql :optional options parameter-value @dots{}
@c MOD dbi
@c EN
This is a convenience procedure when you create a query
and immediately execute it.   It is equivalent to the following
expression, although the driver may overload this method to avoid
creating intermediate query object to avoid the overhead.
@c JP
この手続はクエリを作成し、すぐに実行したいときに便利です。これは次の式
と同じですが、この場合はドライバはオーバーヘッドを避けるため、中間のク
エリを作らないようにこのメソッドをオーバーロードします。
@c COMMON
@example
(dbi-execute (apply dbi-prepare conn sql options)
             parameter-value @dots{})
@end example
@end deffn

@deffn {Method}  dbi-escape-sql conn str
@c MOD dbi
@c EN
Returns a string where special characters in @var{str} are escaped.
@c JP
@var{str}中の特殊文字をエスケープした文字列を返します。
@c COMMON

@c EN
The official SQL standard only specify a single quote (@code{'}) as
such character.  However, it doesn't specify non-printable characters,
and the database system may use other escaping characters.  So
it is necessary to use this method rather than doing escaping
by your own.
@c JP
SQLの公式標準ではこのような文字としてはシングルクォート(@code{'})につ
いてだけ規定しています。しかし、印字可能文字ではない文字については規定
がありません。また、データベースシステムによっては他のエスケープ文字を
使うものもあります。それゆえ、自分でエスケープしようとせずに、このメソッ
ドを使う必要があります。
@c COMMON

@c EN
@example
;; assumes c is a valid DBI connection
(dbi-escape-sql c "don't know")
  @result{} "don''t know"
@end example
@c JP
@example
;; c を利用可能なDBIコネクションとする
(dbi-escape-sql c "don't know")
  @result{} "don''t know"
@end example
@c COMMON
@end deffn

@c EN
@subsubheading Retrieving query results
@c JP
@subsubheading クエリの結果を見る
@c COMMON

@c EN
If the query is a @code{select} statement, it returns an object
of both @code{<collection>} and @code{<relation>}.
It is a collection of rows (that is, it implements @code{<collection>} API),
so you can use @code{map}, @code{for-each} or other generic functions
to access rows.  You can also use the relation API to retrieve column
names and accessors from it.  See @ref{Relation framework}, for the relation
API, and @ref{Collection framework}, for the collection API.
@c JP
クエリが@code{select}文である場合、@code{<collection>}と
@code{<relation>}の両方のオブジェクトが返ります。行のコレクション
(すなわち、@code{<collection>} APIの実装)ですから、行にアクセスするに
は@code{map}、@code{for-each}、その他のジェネリック関数が使えます。
また、カラム名やアクセサを取り出すにはリレーションAPIが使えます。
リレーションAPIについては@ref{Relation framework}をコレクションAPIにつ
いては@ref{Collection framework}を見てください。
@c COMMON

@c EN
The actual class of the object returned from a query depends on
the driver, but you may use the following method on it.
@c JP
クエリから戻ったオブジェクトの実際のクラスはドライバによりますが、
以下のメソッドを使うことができます。
@c COMMON

@deffn {Method} dbi-open? result
@c MOD dbi
@c EN
Check whether the result of a query is still active.
The result may become inactive when it is explicitly closed
by @code{dbi-close} and/or the connection to the database is
closed.
@c JP
クエリの結果がまだアクティブであるかどうかをチェックします。
結果は@code{dbi-close}によって明示的に閉じられるかデータベースへのコネ
クションが閉じられると非アクティブになります。
@c COMMON
@end deffn

@deffn {Method} dbi-close result
@c MOD dbi
@c EN
Close the result of the query.  This may cause releasing resources
related to the result.   You can no longer use @var{result} once it is
closed, except passing it to @code{dbi-open?}.
@c JP
クエリの結果を閉じます。結果に関連付けられていたリソースが解放されます。
@var{result}は、いったん閉じると使えなくなります。ただし、
@code{dbi-open?}にだけは渡せます。
@c COMMON

@c EN
Although a driver usually releases resources when the result is
garbage-collected, the application shouldn't rely on that and
is recommended call @code{dbi-close} explicitly when it is done
with the result.
@c JP
ドライバは通常、結果がガベージコレクタによって回収される時にリソースを
解放しますが、アプリケーションはこれに依存してはいけません。結果を使い
おわったら明示的に@code{dbi-close}を呼ぶことをおすすめします。
@c COMMON
@end deffn

@node Writing drivers for DBI,  , DBI user API, Database independent access layer
@subsection Writing drivers for DBI
@c NODE DBI用のドライバを書く

@c EN
Writing a driver for a specific database system means implementing
a module @code{dbd.@var{foo}}, where @var{foo} is the name of the driver.
@c JP
特定のデータベースシステムのドライバを書くということは、
@code{dbd.@var{foo}}モジュールを実装することです。ここで@var{foo}はド
ライバの名前になります。
@c COMMON

@c EN
The module have to implement several classes and methods, as explained below.
@c JP
このモジュールは以下に説明するいくつかのクラスとメソッドを実装しなけれ
ばなりません。
@c COMMON

@c EN
@subsubheading DBI classes to implement
@c JP
@subsubheading 実装するDBIクラス
@c COMMON

@c EN
You have to define the following classes.
@c JP
以下のクラスを定義しなければなりません。
@c COMMON

@c EN
@itemize @bullet
@item
Subclass @code{<dbi-driver>}.
The class name @emph{must} be @code{<@var{foo}-driver>}, where
@var{foo} is the name of the driver.
Usually this class produces a singleton instance,
and is only used to dispatch @code{dbi-make-connection}
method below.
@item
Subclass @code{<dbi-connection>}.  An instance of this class is created
by @code{dbi-make-connection}.  It needs to keep the information about
the actual connections.
@item
Subclass @code{<relation>} and @code{<collection>} to represent
query results suitable for the driver.  (In most cases, the order of
the result of SELECT statement is significant, since it may be
sorted by ORDER BY clause.  Thus it is more appropriate to
inherit @code{<sequence>}, rather than @code{<collection>}).
@item
Optionally, subclass @code{<dbi-query>} to keep driver-specific
information of prepared queries.
@end itemize
@c JP
@itemize @bullet
@item
@code{<dbi-driver>}のサブクラス。このクラスの名前は@emph{必ず}
@code{<@var{foo}-driver>}でなければなりません。ここで、@var{foo}は
ドライバの名前です。通常このクラスはシングルトンインスタンスを生成し、
後述の@code{dbi-make-connection}メソッドをディスパッチするためにのみ利
用されます。
@item
@code{<dbi-connection>}のサブクラス。このクラスのインスタンスは
@code{dbi-make-connection}によって生成されます。そのためには、実際のコ
ネクションに関する情報を保持する必要があります。
@item
ドライバにあったクエリ結果を表現するための@code{<relation>}および
@code{<collection>}のサブクラス。(ほとんどの場合、SELECT文の結果は順序
が重要です。それは、ORDER BY 節によってソートされる可能性があるからで
す。したがって、@code{<sequence>}を継承するほうが、@code{<collection>}
を継承するよりも適切です。)
@item
オプションとして、プリペアドクエリのドライバ特有の情報を保持するため
@code{<dbi-query>}のサブクラスを実装します。
@end itemize
@c COMMON

@c EN
@subsubheading DBI methods to implement
@c JP
@subsubheading 実装するDBIメソッド
@c COMMON

@c EN
The driver need to implement the following methods.
@c JP
ドライバは以下のメソッドを実装しなければなりません。
@c COMMON

@deffn {Method} dbi-make-connection (d <foo-driver>) (options <string>) (options-alist <list>) :key username password @dots{}
@c MOD dbi
@c EN
This method is called from @code{dbi-connect}, and responsible to
connect to the database and to create a connection object.
It must return a connection object, or raise an @code{<dbi-error>} if
it cannot establish a connection.
@c JP
このメソッドは@code{dbi-connect}から呼ばれ、データベースへの接続を担い、
コネクションオブジェクトを作成します。コネクションオブジェクトを返さな
ければなりません。コネクションが確立できない場合には、
@code{<dbi-error>}をあげなければなりません。
@c COMMON

@c EN
@var{Options} is the option part of the data source name (DSN) given to
@code{dbi-connect}.  @var{options-alist} is an assoc list of
the result of parsing @var{options}.  Both are provided so that
the driver may interpret @var{options} string in nontrivial way.
@c JP
@var{options}は@code{dbi-connect}に与えられるデータソースネーム(DSN)の
オプションパートです。@var{options-alist}は@var{options}を解析した結果
の連想リストです。両方ともに用意して、ドライバが自明ではない方法で
@var{options}文字列を解釈できるようにします。
@c COMMON

@c EN
For example, given @code{"dbi:foo:myaddressbook;host=dbhost;port=8998"}
as DSN, foo's @code{dbi-make-connection} will receive
@code{"myaddressbook;host=dbhost;port=8998"} as @var{options},
and @code{(("myaddressbook" . #t) ("host" . "dbhost") ("port" . "8998"))}
as @var{options-alist}.
@c JP
たとえば、DSNとして
@code{"dbi:foo:myaddressbook;host=dbhost;port=8998"}が与えられたとする
と、fooの@code{dbi-make-connection}は@var{options}として
@code{"myaddressbook;host=dbhost;port=8998"}を受け取り、
@var{options-alist}として
@code{(("myaddressbook" . #t) ("host" . "dbhost") ("port" . "8998"))}
を受け取ります。
@c COMMON

@c EN
After @var{options-alist}, whatever keyword arguments given to
@code{dbi-connect} are passed.  DBI protocol currently
specifies only @var{username} and @var{password}.
The driver may define other keyword arguments.
It is recommended to name the driver-specific keyword arguments
prefixed by the driver name, e.g. for @code{dbd.foo}, it may take
a @code{:foo-whatever} keyword argument.
@c JP
@var{options-alist}の後ろならどのようなキーワード引数でも
@code{dbi-connect}に渡せます。DBIプロトコルは現在のところは
@var{username}および@var{password}のみを指定します。
ドライバはその他のキーワード引数を定義できます。
ドライバ特有のキーワード引数にはドライバ名を接頭辞として付けることをお
勧めします。たとえば、@code{dbd.foo}なら、@code{:foo-whatever}のように
です。
@c COMMON

@c EN
It is up to the driver writer to define what options are available and
the syntax of the options.  The basic idea is that the DSN
identifies the source of the data; it's role is like URL in WWW.
So, it may include the hostname and port number of the database,
and/or the name of the database, etc.  However, it shouldn't include
information related to authentication, such as username and password.
That's why those are passed via keyword arguments.
@c JP
どのようなオプションを使えるようにするか、あるいはオプションの構文をど
うするかはドライバを書く人しだいです。基本的な考え方は、DSN はデータの
ソースを識別するためのものであり、その役割りはWWWにおけるURLのようなも
のだということです。それゆえ、データベースのホスト名、ポート番号、それ
にデータベース名などが含まれることになるでしょう。しかし、ユーザ名やパ
スワードのような認証に関する情報を含めてはいけません。というわけで、そ
の手の情報はキーワード引数で渡すのです。
@c COMMON
@end deffn

@deffn {Method} dbi-prepare (c <foo-connection>) (sql <string>) :key pass-through @dots{}
@c MOD dbi
@c EN
This method should create and return a prepared query object,
which is an instance of @code{<dbi-query>} or its subclass.
The query specified by @var{sql} is issued to the database system
when the prepared query object is passed to @code{dbi-execute}.
@c JP
このメソッドは@code{<dbi-query>}あるいはそのサブクラスのインスタンスで
あるプリペアドクエリオブジェクトを生成し、それを返すものでなくてはなり
ません。@var{sql}によるクエリがデータベースに発行されるのは、プリペア
ドクエリオブジェクトが@code{dbi-execute}に渡されたときです。
@c COMMON

@c EN
The method must set @var{c} to the @code{connection} slot of
the returned query object.
@c JP
このメソッドは返されるクエリオブジェクトの@code{connection}スロットに
@var{c}を設定しなけばなりません。
@c COMMON

@c EN
@var{Sql} is an SQL statement.  It may contain placeholders represented
by @code{'?'}.  The query closure should take the same number of arguments
as of the placeholders.   It is up to the driver whether it parses
@var{sql} internally and construct a complete SQL statement when
the query closure is called, or it passes @var{sql} to the back-end
server to prepare the statement and let the query closure just send
parameters.
@c JP
@var{sql}はSQL文です。これには@code{'?'}で表現されたプレイスホルダが含
まれることがあります。クエリクロージャはこのプレイスホルダと同じ数の引
数をとらなければなりません。内部的に@var{sql}をどのようにパーズするか、
クエリクロージャが呼ばれたとき完全なSQL文を構築するか、@var{sql}をバッ
クエンドのサーバに送って文を準備し、クエリクロージャはパラメータだけを
送るようにするかなどはドライバに依存します。
@c COMMON

@c EN
If the driver parses SQL statement internally, it should recognize
a keyword argument @code{pass-through}.  If a true value is given,
the driver must treat @code{sql} opaque and pass it as is when
the query closure is called.
@c JP
ドライバがSQL文を内部的にわたす場合、キーワード引数@code{pass-through}
を認識しなければいけません。もし、真の値が与えられたら、ドライバは
@code{sql}を不透明なものとして扱い、これをそのままクエリクロージャが呼
ばれた際に渡さなければなりません。
@c COMMON

@c EN
The driver may define other keyword arguments.
It is recommended to name the driver-specific keyword arguments
prefixed by the driver name, e.g. for @code{dbd.foo}, it may take
a @code{:foo-whatever} keyword argument.
@c JP
ドライバがその他のキーワード引数を定義することもできます。
その場合、ドライバ特有のキーワード引数にはドライバ名を接頭辞として付け
ることをお勧めします。たとえば、@code{dbd.foo}なら、
@code{:foo-whatever}のようにです。
@c COMMON
@end deffn

@deffn {Method} dbi-execute-using-connection (c <foo-connection>) (q <dbi-query>) (params <list>)
@c MOD dbi
@c EN
This method is called from @code{dbi-execute}.
It must issue the query kept in @var{q}.  If the query is parameterized,
the actual parameters given to @var{dbi-execute} are passed to
@var{params} argument.
@c JP
このメソッドは@code{dbi-execute}から呼ばれます。@var{q}が保持するクエ
リを発行しなければなりません。クエリがパラメータ化されている場合、
@var{dbi-execute}に与えられた実際のパラメータは@var{params}引数に渡さ
れます。
@c COMMON

@c EN
If @var{q} is a @code{select}-type query, this method must return
an appropriate relation object.
@c JP
@var{q}が@code{select}-型のクエリの場合は、このメソッドは適切なリレー
ションオブジェクトを返さなければなりません。
@c COMMON
@end deffn

@deffn {Method} dbi-escape-sql (c <foo-connection>) str
@c MOD dbi
@c EN
If the default escape method isn't enough, the driver may
overload this method to implement a specific escaping.
For example, MySQL treats backslash characters specially
as well as single quotes, so it has its @code{dbi-escape-sql}
method.
@c JP
デフォルトのエスケープメソッドでは十分でないとき、ドライバは特別のエス
ケープを行うためにこのメソッドをオーバーロードすることができます。たと
えば、MySQLではバックスラッシュ文字はシングルクォートと同様に特別あつ
かいしますので、@code{dbi-escape-sql}メソッドを持っています。
@c COMMON
@end deffn

@deffn {Method} dbi-open? (c <foo-connection>)
@deffnx {Method} dbi-open? (q <foo-query>)
@deffnx {Method} dbi-open? (r <foo-result>)
@deffnx {Method} dbi-close (c <foo-connection>)
@deffnx {Method} dbi-close (q <foo-query>)
@deffnx {Method} dbi-close (r <foo-result>)
@c MOD dbi
@c EN
Queries open/close status of a connection and a result, and
closes a connection and a result.  The close methods should cause
releasing resources used by connection/result.  The driver
has to allow @code{dbi-close} to be called on a connection or a
result which has already been closed.
@c JP
これらのメソッドでコネクションおよび結果の状態を調べ、コネクションおよ
び結果を閉じます。closeメソッドはコネクションや結果が利用しているリソー
スを解放しなければなりません。ドライバは@code{dbi-close}がすでに閉じら
れたコネクションや結果に対しても適用できるようにしておかなければなりま
せん。
@c COMMON
@end deffn

@deffn {Method} dbi-do (c <foo-connection>) (sql <string>) :optional options parameter-value @dots{}
@c MOD dbi
@c EN
The default method uses @code{dbi-prepare} and @code{dbi-execute}
to implement the function.  It just works,
but the driver may overload this method in order to skip
creating intermediate query object for efficiency.
@c JP
この機能を実装するのにデフォルトメソッドは@code{dbi-prepare}および
@code{dbi-execute}を使っています。これだけでも動きますが、
ドライバは効率のために中間のクエリオブジェクトの生成をスキップするため
にこのメソッドをオーバーロードできます。
@c COMMON
@end deffn

@c EN
@subsubheading DBI utility functions
@c JP
@subsubheading DBIのユーティリティ関数
@c COMMON

@c EN
The following functions are low-level utilities which you may
use to implement the above methods.
@c JP
以下の関数は上述のメソッドを実装するための低レベルのユーティリティです。
@c COMMON

@defun dbi-parse-dsn data-source-name
@c MOD dbi
@c EN
Parse the data source name (DSN) string given to @code{dbi-connect},
and returns tree values: (1) The driver name in a string. (2)
'options' part of DSN as a string.  (3) parsed options in an assoc
list.  This may raise @code{<dbi-error>} if the given string doesn't
conform DSN syntax.
@c JP
@code{dbi-connect}に与えられたデータソースネーム(DSN)文字列を解析し、
以下の3つの値を返す。(1) ドライバ名(文字列) (2) DSNのオプション部分(文
字列) (3) 解析済オプション(連想リスト)。与えられた文字列がDSN構文に準
拠していない場合には@code{<dbi-error>}があがります。
@c COMMON

@c EN
You don't need to use this to write a typical driver, for the
parsing is done before @code{dbi-make-connection} is called.
This method may be useful if you're writing a kind of meta-driver,
such as a proxy.
@c JP
典型的なドライバを書く場合には必要ありません。構文解析は
@code{dbi-make-connection}を呼ぶ前にすんでいるからです。このメソッドは
プロキシのようなメタドライバという類のものを書くときに便利です。
@c COMMON
@end defun

@defun dbi-prepare-sql connection sql
@c MOD dbi
@c EN
Parses an SQL statement @var{sql} which may contain placeholders,
and returns a closure, which generates a complete SQL statement when
called with actual values for the parameters.  If the back-end
doesn't support prepared statements, you may use this function
to prepare queries in the driver.
@c JP
プレイスホルダを含むSQL文 @var{sql} をパーズし、実際の値をパラメータと
して渡されたときに完全なSQLを生成するクロージャを作成します。
バックエンドがプリペアド文をサポートしていない場合は、ドライバ中でクエ
リを準備するのにこの関数を使うことになります。
@c COMMON

@c EN
@var{Connection} is a DBI connection to the database.  It is required
to escape values within SQL properly (see @code{dbi-escape-sql} above).
@c JP
@var{connection}はデータベースへのDBIコネクションです。SQL中の値は適切
にエスケープされている必要があります(上述の@code{dbi-escape-sql}をみて
ください)。
@c COMMON

@c EN
@example
;; assume c contains a valid dbi connection
((dbi-prepare-sql c "select * from table where id=?") "foo'bar")
 => "select * from table where id='foo''bar'"
@end example
@c JP
@example
;; c は正しいdbiコネクションを持っているとする
((dbi-prepare-sql c "select * from table where id=?") "foo'bar")
 => "select * from table where id='foo''bar'"
@end example
@c COMMON
@end defun

@c ----------------------------------------------------------------------

@node Generic DBM interface, File-system dbm, Database independent access layer, Library modules - Utilities
@section @code{dbm} - Generic DBM interface
@c NODE 汎用DBMインタフェース, @code{dbm} - 汎用DBMインタフェース

@deftp {Module} dbm
@mdindex dbm
@c EN
DBM-like libraries provides an easy way to store values to a file,
indexed by keys.  You can think it as a persistent associative memory.
@c JP
DBM系のライブラリはキーでインデックスされた値をファイルに格納する簡単な方法を
提供します。一種の永続的な連想記憶と言えるでしょう。
@c COMMON

@c EN
This modules defines @code{<dbm>} abstract class, which has
a common interface to use various DBM-type database packages.
As far as you operate on the already opened database,
importing @code{dbm} module is enough.
@c JP
このモジュールが定義する抽象クラス@code{<dbm>}は、DBM系ライブラリへの
統一されたインタフェースを提供します。@code{dbm}モジュールだけをインポートすれば、
既にオープンされたデータベースを操作することができます。
@c COMMON

@c EN
To create or open a database, you need a concrete implementation
of the database.  With the default build-time configuration,
the following implementations are included in Gauche.
Bindings to various other dbm-like libraries are
available as extension packages.
Each module defines its own low-level accessing functions
as well as the common interface.
Note that your system may not have one or more of those DBM libraries;
Gauche defines only what the system provides.
@c JP
データベースをオープンしたり作成したりするには、dbmインタフェースを実装した
モジュールが必要になります。デフォルトのビルド時コンフィグレーションでは、
以下の実装がGaucheに含まれます。他の様々なdbmライブラリへのバインディングが
拡張パッケージとして提供されています。
それぞれのモジュールは、dbmインタフェース共通の手続きの他に、
直接実装を操作できる低レベルの手続きも提供します。
システムによっては以下のインタフェースの全てが実装されているわけではないことに
注意してください。Gaucheではシステムが提供する実装のみを定義します。
@c COMMON

@table @code
@item dbm.fsdbm
@c EN
file-system dbm (@pxref{File-system dbm}).
@c JP
ファイルシステムdbm (@ref{File-system dbm}参照).
@c COMMON

@item dbm.gdbm
@c EN
GDBM library (@pxref{GDBM interface}).
@c JP
GDBMライブラリ (@ref{GDBM interface}参照).
@c COMMON

@item dbm.ndbm
@c EN
NDBM library (@pxref{NDBM interface}).
@c JP
NDBMライブラリ (@ref{NDBM interface}参照).
@c COMMON

@item dbm.odbm
@c EN
DBM library  (@pxref{Original DBM interface}).
@c JP
DBMライブラリ  (@ref{Original DBM interface}参照).
@c COMMON
@end table
@end deftp

@c EN
The following code shows a typical usage of the database.
@c JP
以下にdbmデータベースの使用例を示します。
@c COMMON

@example
(use dbm)         ; @r{dbm abstract interface}
(use dbm.gdbm)    ; @r{dbm concrete interface}

; @r{open the database}
(define *db* (dbm-open <gdbm> :path "mydb" :rw-mode :write))

; @r{put the value to the database}
(dbm-put! *db* "key1" "value1")

; @r{get the value from the database}
(define val (dbm-get *db* "key1"))

; @r{iterate over the database}
(dbm-for-each *db* (lambda (key val) (foo key val)))

; @r{close the database}
(dbm-close *db*)
@end example

@c EN
The @code{<dbm>} abstract class implements collection 
and dictionary framework.  (See @ref{Collection framework}
and @ref{Dictionary framework}, respectively).
@c JP
@var{<dbm>}抽象クラスは、コレクションフレームワークと
ディクショナリフレームワークを実装しています。
(それぞれ@ref{Collection framework}と@ref{Dictionary framework}参照。)
@c COMMON

@menu
* Opening and closing a dbm database::
* Accessing a dbm database::
* Iterating on a database::
* Managing dbm database instance::
* Dumping and restoring dbm database::
* Writing a dbm implementation::
@end menu

@node Opening and closing a dbm database, Accessing a dbm database, Generic DBM interface, Generic DBM interface
@subsection Opening and closing a dbm database
@c NODE DBMデータベースのオープンとクローズ

@deftp {Class} <dbm>
@clindex dbm
@c MOD dbm
@c EN
An abstract class for dbm-style database.    Inherits
@code{<dictionary>} (@pxref{Dictionary framework}).
Defines the common
database operations.   This class has the following instance slots.
They must be set before the database is actually opened by
@code{dbm-open}.

The concrete class may add more slots for finer control on the database,
such as locking.
@c JP
DBM系のデータベースのための抽象クラスです。
@code{<dictionary>}クラスを継承します (@ref{Dictionary framework}参照)。
データベースへの共通のオペレーションを
定義します。以下のインスタンススロットを持ちます。これらのスロットの値は
@code{dbm-open}によってデータベースがオープンされる前にセットされて
いなければなりません。

具体クラスは、データベースの操作をより細かく行うための追加のスロット(例えばロックを
行うかどうか)を持つかもしれません。
@c COMMON

@defivar <dbm> path
@c EN
Pathname of the dbm database.  Some dbm implementation may append
suffixes to this.
@c JP
データベースファイルのパス名。dbmの実装によっては、このパスにサフィックスが追加されます。
@c COMMON
@end defivar

@defivar <dbm> rw-mode
@c EN
Specifies read/write mode.  Can be either one of the following keywords:
@table @code
@item :read
The database will be opened in read-only mode.  The database file must
exist when @code{dbm-open} is called.
@item :write
The database will be opened in Read-write mode.
If the database file does not exist, @code{dbm-open} creates one.
@item :create
The database will be created and opened in Read-write mode.
If the database file exists, @code{dbm-open} truncates it.
@end table
@c JP
読み書きのモードを指定します。以下の値のいずれかを取ります。
@table @code
@item :read
データベースは@code{dbm-open}によって読みだし専用モードでオープンされます。
オープンされる時点でデータベースは存在していなければなりません。
@item :write
データベースは@code{dbm-open}によって読み書き可能なモードでオープンされます。
データベースが存在しなければ、@code{dbm-open}は新しいデータベースを作成します。
@item :create
@code{dbm-open}によって新しいデータベースが作成され、読み書き可能なモードでオープンされます。
既にデータベースが存在していた場合、その内容はクリアされます。
@end table
@c COMMON
@end defivar

@defivar <dbm> file-mode
@c EN
Specifies the file permissions (as @code{sys-chmod}) to create the
database.  The default value is @code{#o664}.
@c JP
データベースが作成されるときのファイルパーミッションを指定します。
デフォルトは@code{#o664}です。
@c COMMON
@end defivar

@defivar <dbm> key-convert
@defivarx <dbm> value-convert
@c EN
By default, you can use only strings for both key and values.  With this
option, however, you can specify how to convert other Scheme values to/from
string to be stored in the database.   The possible values are the
followings:
@table @asis
@item @code{#f}
The default value.  Keys (values) are not converted.  They must be
a string.
@item @code{#t}
Keys (values) are converted to its string representation, using
@code{write}, to store in the database, and converted
back to Scheme values, using @code{read}, to retrieve from the database.
The data must have an external representation that can be read back.
(But it is not checked when the data is written; you'll get an error
when you read the data).  The key comparison is done in the string
level, so the external representation of the same key must match.
@item a list of two procedures
Both procedure must take a single argument.  The first procedure must
receive a Scheme object and returns a string.  It is used to convert
the keys (values) to store in the database.  The second procedure
must receive a string and returns a Scheme object.  It is used to
convert the stored data in the database to a Scheme object.
The key comparison is done in the string
level, so the external representation of the same key must match.
@end table
@c JP
デフォルトでは、dbmデータベースはキーにも値にも文字列しか使うことはできません。
これらのスロットによって、それ以外のSchemeオブジェクトを取り扱う方法を指定することが
できます。以下の値のいずれかが可能です。
@table @asis
@item @code{#f}
デフォルトの値です。キーあるいは値は変換されません。それらは文字列でなければなりません。
@item @code{#t}
キーあるいは値は@code{write}を使って文字列に変換されデータベースに格納されます。
そして@code{read}を使って文字列からSchemeオブジェクトへと変換されます。
後で@code{read}で読みこめるようなキーあるいは値のみを扱うことができます。
(但し、dbmライブラリは書き込み時にそれが後で読み込めるかどうかのチェックは行いません)。
キーの比較は文字列に変換された後で行われるので、同じ値となるキーは同じ文字列表現を
持つ必要があります。
@item 二つの手続きのリスト
どちらの手続きも一つの引数を取ります。最初の手続きはSchemeオブジェクトを受け取り、
文字列を返します。キーあるいは値をデータベースに格納する時に呼ばれます。
二つ目の手続きは文字列を受け取りSchemeオブジェクトを返します。データベースから
キーあるいは値を取り出す時に呼ばれます。
キーの比較は文字列に変換された後で行われるので、同じ値となるキーは同じ文字列に
変換される必要があります。
@end table
@c COMMON
@end defivar
@end deftp

@deftp {Metaclass} <dbm-meta>
@clindex dbm-meta
@c MOD dbm
@c EN
A metaclass of @code{<dbm>} and its subclasses.
@c JP
@var{<dbm>}クラス及びそのサブクラスのメタクラスです。
@c COMMON
@end deftp

@deffn {Method} dbm-open (dbm <dbm>)
@c MOD dbm
@c EN
Opens a dbm database.  @var{dbm} must be an instance of
one of the concrete classes that derived from the @code{<dbm>} class,
and its slots must be set appropriately.   On success, it returns
the @var{dbm} itself.  On failure, it signals an error.
@c JP
DBMデータベースをオープンします。@var{dbm}は、@code{<dbm>}クラスを継承した
具体クラスのインスタンスでなければなりません。また、そのスロットには適切な値が
セットされている必要があります。オープンに成功したら@var{dbm}自身が返されます。
失敗した場合はエラーが報告されます。
@c COMMON
@end deffn

@deffn {Method} dbm-open (dbm-class <dbm-meta>) options @dots{}
@c MOD dbm
@c EN
A convenient method that creates dbm instance and opens it.
It is defined as follows.
@c JP
DBMインスタンスを作成してオープンするための便利なメソッドです。
次のように定義されます。
@c COMMON
@example
(define-method dbm-open ((class <class>) . initargs)
  (dbm-open (apply make class initargs)))
@end example
@end deffn

@c EN
Database file is closed when it is garbage collected.
However, to ensure the modification is properly synchronized,
you should close the database explicitly.
@c JP
データベースファイルはガベージコレクトされる際にクローズされますが、
変更を正しくデータベースに反映するには、明示的にクローズした方が良いでしょう。
@c COMMON

@deffn {Method} dbm-close (dbm @code{<dbm>})
@c MOD dbm
@c EN
Closes a database @var{dbm}.  Once the database is closed, any
operation to access the database content raises an error.
@c JP
データベース@var{dbm}をクローズします。データベースがクローズされると、
それ以降のアクセスオペレーションはエラーとなります。
@c COMMON
@end deffn

@deffn {Method} dbm-closed? (dbm @code{<dbm>})
@c MOD dbm
@c EN
Returns true if a database @var{dbm} is already closed, false otherwise.
@c JP
データベース@var{dbm}が既にクローズされていたら@code{#t}を返します。
@c COMMON
@end deffn

@defun dbm-type->class dbmtype
@c MOD dbm
Sometimes you don't know which type of dbm implementation you
need to use in your application beforehand, but rather you need to
determine the type according to the information given at run-time.
This procedure fulfills the need.

The @var{dbmtype} argument is a symbol that names the type
of dbm implementation; for example, @code{gdbm} for @code{dbm.gdbm},
and @code{fsdbm} for @code{dbm.fsdbm}.   We assume that the
dbm implementation of type @code{@var{foo}} is provided as
a module @code{dbm.@var{foo}}, and its class is named
as @code{<@var{foo}>}.

This procedure first checks if the required module has been
loaded, and if not, it tries to load it.   If the module
loads successfully, it returns the class object of the
named dbm implementation.   If it can't load the module,
or can't find the dbm class, this procedure returns #f.

@example
(use dbm)

(dbm-type->class 'gdbm)
  @result{} @code{#<class <gdbm>>}

(dbm-type->class 'nosuchdbm)
  @result{} @code{#f}
@end example
@end defun

@node Accessing a dbm database, Iterating on a database, Opening and closing a dbm database, Generic DBM interface
@subsection Accessing a dbm database
@c NODE DBMデータベースのアクセス

@c EN
Once a database is opened, you can use the following methods
to access individual key/value pairs.
@c JP
データベースがオープンされたら、以下のアクセスメソッドが使えます。
@c COMMON

@deffn {Method} dbm-put! (dbm @code{<dbm>}) key value
@c MOD dbm
@c EN
Put a @var{value} with @var{key}.
@c JP
値@var{value}をキー@var{key}と関連付けて保存します。
@c COMMON
@end deffn

@deffn {Method} dbm-get (dbm @code{<dbm>}) key :optional default
@c MOD dbm
@c EN
Get a value associated with @var{key}.  If no value exists for @var{key}
and @var{default} is specified, it is returned.  If no value exists for
@var{key} and @var{default} is not specified, an error is signaled.
@c JP
キー@var{key}に関連付けられた値を返します。もし値が存在しなければ、@var{default}が
与えられていればそれを返し、そうでなければエラーを報告します。
@c COMMON
@end deffn

@deffn {Method} dbm-exists? (dbm @code{<dbm>}) key
@c MOD dbm
@c EN
Return true if a value exists for @var{key}, false otherwise.
@c JP
キー@var{key}に関連付けられた値が存在すれば@code{#t}を返します。
@c COMMON
@end deffn

@deffn {Method} dbm-delete! (dbm @code{<dbm>}) key
@c MOD dbm
@c EN
Delete a value associated with @var{key}.
@c JP
キー@var{key}に関連付けられた値を消去します。値が存在しない場合は何もしません。
@c COMMON
@end deffn

@node Iterating on a database, Managing dbm database instance, Accessing a dbm database, Generic DBM interface
@subsection Iterating on a dbm database
@c NODE DBMデータベース上の繰り返し処理

@c EN
To walk over the entire database, following methods are provided.
@c JP
全データベースを渡り歩く処理のために、以下のメソッドが用意されています。
@c COMMON

@deffn {Method} dbm-fold (dbm @code{<dbm>}) procedure knil
@c MOD dbm
@c EN
The basic iterator.
For each key/value pair, @var{procedure} is called as
@code{(@var{procedure} @var{key} @var{value} @var{r})},
where @var{r} is @var{knil} for the fist call of @var{procedure},
and the return value of the previous call for subsequent calls.
Returns the result of the last call of @var{procedure}.
If no data is in the database, @var{knil} is returned.

The following method returns the sum of all the integer values.
@c JP
基本的な繰り返し処理です。データベース内の各キー／値のペアに関して、手続き
@var{procedure}が @code{(@var{procedure} @var{key} @var{value} @var{r})},
のように呼ばれます。ここで@var{r}は、最初の@var{procedure}の呼び出しの時には@var{knil}
が、以降の呼び出しの時にはその直前の@var{procedure}が返した値が渡されます。
最後の@var{procedure}の戻り値が@code{dbm-fold}の戻り値となります。
データベース中にデータがひとつもなければ@var{knil}がそのまま返されます。

次の例は、データベース中の整数の値を全て加算します。
@c COMMON
@example
(dbm-fold dbm (lambda (k v r) (if (integer? v) (+ v r) r)) 0)
@end example
@end deffn

@deffn {Method} dbm-for-each (dbm @code{<dbm>}) procedure
@c MOD dbm
@c EN
For each key/value pair in the database @var{dbm}, @var{procedure}
is called.  Two arguments are passed to @var{procedure}---a key and
a value.   The result of @var{procedure} is discarded.
@c JP
データベース内の各キー／値のペアに関して、手続き@var{procedure}を呼び出します。
@var{procedure}にはキーと値が渡されます。@var{procedure}の戻り値は捨てられます。
@c COMMON
@end deffn

@deffn {Method} dbm-map (dbm @code{<dbm>}) procedure
@c MOD dbm
@c EN
For each key/value pair in the database @var{dbm}, @var{procedure}
is called.  Two arguments are passed to @var{procedure}---a key and
a value.   The result of @var{procedure} is accumulated to a list
which is returned as a result of @code{dbm-map}.
@c JP
データベース内の各キー／値のペアに関して、手続き@var{procedure}を呼び出します。
@var{procedure}にはキーと値が渡されます。@var{procedure}の戻り値はリストに
集められて@code{dbm-map}の戻り値となります。
@c COMMON
@end deffn

@node Managing dbm database instance, Dumping and restoring dbm database, Iterating on a database, Generic DBM interface
@subsection Managing dbm database instance
@c NODE DBMデータベースインスタンスの管理

@c EN
Each dbm implementation has its own way to store the
database.  Legacy dbm uses two files, whose names are
generated by adding @file{.dir} and @file{.pag} to the
value of @var{path} slot.  @code{Fsdbm} creates a directory
under @var{path}.  If dbm database is backed up by
some database server, @var{path} may be used only as
a key to the database in the server.
@c JP
各DBM実装は、データベースを格納するのに独自の方法を使います。
レガシーなDBMは、@var{path}スロットの値にそれぞれ@file{.dir}と
@file{.pag}を付けた名前の2つのファイルを使います。
@code{fsdbm}は@var{path}の下にディレクトリを作ります。
DBMデータベースが他のデータベースサーバによってバック
アップされる場合は、@var{path}はそのサーバで単なるキーと
して使われるでしょう。

@c EN
The following methods hide such variations and provides
a convenient way to manage a database itself.   You have to
pass a class that implements a concrete dbm database to their
first argument.
@c JP
以下のメソッドは、そのようなバリエーションを隠し、
データベースそれ自体を管理する簡易な方法を提供します。
最初の引数に、具体的なDBMデータベースを実装している
クラスを渡す必要があります。
@c COMMON

@deffn {Generic Function} dbm-db-exists? class name
@c MOD dbm
@c EN
Returns @code{#t} if a database of class @var{class}
specified by @var{name} exists.
@c JP
@var{name}で指定された@var{class}クラスのデータベースが
存在する場合は@code{#t}を返します。
@c COMMON

@example
;; Returns #t if testdb.dir and testdb.pag exist
(dbm-db-exists? <odbm> "testdb")
@end example
@end deffn

@deffn {Generic Function} dbm-db-remove class name
@c MOD dbm
@c EN
Removes an entire database of class @var{class} specified by
@var{name}.
@c JP
@var{name}で指定される@var{class}クラスのデータベース
全体を削除します。
@c COMMON
@end deffn

@deffn {Generic Function} dbm-db-copy class from to
@c MOD dbm
@c EN
Copy a database of class @var{class} specified by
@var{from} to @var{to}.  The integrity of @var{from}
is guaranteed if the @var{class}'s dbm implementation supports
locking (i.e. you won't get a corrupted database even if
some other process is trying to write to @var{from}
during copy).   If the destination database @var{to} exists,
its content is destroyed.  If this function is interrupted,
whether @var{to} is left in incomplete state or not depends
on the dbm implementation.   The implementation usually tries
its best to provide transactional behavior, that is,
to recover original @var{to} when the copy fails.  However,
for the robust operations the caller have to check the state
of @var{to} if @code{dbm-db-copy} fails.
@c JP
@var{from}で指定された@var{class}クラスのデータベースを
@var{to}へコピーします。
@var{class}のdbm実装がロックをサポートしている限り、@var{from}の一貫性は
保たれます (つまり、コピー中に他のプロセスが@var{from}を
変更しようとした場合であっても、@var{to}が壊れたデータベースになることは
ありません)。  もしコピー先の@var{to}が既に存在するデータベースで
あった場合、@var{to}の元の内容は失われます。
コピーが中断された場合に@var{to}が不完全な状態のままになるかどうかは
dbm実装に依存します。dbm実装の多くはトランザクショナルな振る舞い、
すなわち、コピーが失敗した場合に元の@var{to}を復元することを試みます。
しかし確実な操作のためには、コピーが失敗した場合には呼び出し側で@var{to}の
状態を確認することが必要です。
@c COMMON

@example
(dbm-db-copy <gdbm> "testdb.dbm" "backup.dbm")
@end example
@end deffn

@deffn {Generic Function} dbm-db-move class from to
@c MOD dbm
@c EN
Moves or renames a database of class @var{class} specified by
@var{from} to @var{to}.  Like @code{dbm-db-copy}, the database
integrity is guaranteed as far as @var{class}'s dbm implementation
supports locking.  If the destination database @var{to} exists,
its content is destroyed.
@c JP
@var{from}で指定された@var{class}クラスのデータベースを
@var{to}へ移動、あるいはリネームします。@code{dbm-db-copy}と同じく、
@var{class}のdbm実装がロックをサポートしていれば
データベースの一貫性は保証されます。移動先の@var{to}が既に
存在していた場合、その元の内容は失われます。
@c COMMON
@end deffn

@node Dumping and restoring dbm database, Writing a dbm implementation, Managing dbm database instance, Generic DBM interface
@subsection Dumping and restoring dbm database
@c NODE DBMデータベースのダンプとリストア

Most dbm implementations use some kind of binary format, and
some of them are architecture dependent.
That makes it difficult to pass around dbm databases
between different machines.
A safe way is to write out the content of a dbm database
into some portable format on the source machine,
and rebuild another dbm database from it on the destination
machine.

The operation is so common that Gauche provides convenience
scripts that does the job.  They are installed into the
standard Gauche library directory, so it can be invoked
by @code{gosh <scriptname>}.

To write out the content of a dbm database named by @var{dbm-name},
you can use @code{dbm/dump} script:

@example
$ gosh dbm/dump [-o @var{outfile}][-t @var{type}] @var{dbm-name}
@end example

The @var{outfile} argument names the output file.  If omitted,
the output is written out to stdout.  The @var{type} argument
specifies the implementation type of the dbm database; e.g.
@code{gdbm} or @code{fsdbm}.  The program calls
@code{dbm-type->class} (@pxref{Opening and closing a dbm database})
on the @var{type} argument to load the necessary dbm implementation.

The dumped format is simply a series of S-expressions,
each of which is a dotted pair of string key and string value.
Character encodings are assumed to be the same as
@code{gosh}'s native character encoding.

The dumped output may contain S-expressions other than dotted pair
of strings to include meta information.  For now, programs
that deals with dumped output should just ignore S-expressions
other than dotted pairs.

To read back the dumped dbm format, you can use @code{dbm/restore}
script:

@example
$ gosh dbm/restore [-i @var{infile}][-t @var{type}] @var{dbm-name}
@end example

The @var{infile} argument names the dumped file to be read.
If omitted, it reads from stdin.  The @var{type} argument
specifies the dbm type, as in @code{dbm/dump} script.
The @var{dbm-name} argument names the dbm database; if the
database already exists, its content is cleared, so be careful.


@node Writing a dbm implementation,  , Dumping and restoring dbm database, Generic DBM interface
@subsection Writing a dbm implementation
@c NODE DBM実装を書く

When you write an extension module that behaves like
a persistent hashtable, it is a good idea to adapt it
to the dbm interface, so that the application can use
the module in a generic way.

The minimum procedures to conform the dbm interface
are as follow:

@itemize @bullet
@item
Define a metaclass @code{<@var{foo}-meta>}.   It doesn't
need to inherit anything except @code{<class>}.
@item
Define a dbm class @code{<@var{foo}>} that inherits @code{<dbm>}
and whose metaclass is @code{<@var{foo}-meta>}.
@item
Define methods for @code{dbm-open}, @code{dbm-close},
@code{dbm-put!}, @code{dbm-get}, @code{dbm-exists},
@code{dbm-delete!}, @code{dbm-fold}, @code{dbm-closed?},
specialized for @code{<@var{foo}>}.
(The case of @code{dbm-open} for @code{<@var{foo}-meta>} is
handled automatically, so you don't need to define it unless
you want something special).
Also note that the specialized @code{dbm-open} must call
@code{next-method} in it to set up dbm base class internals.
@item
Define methods for @code{dbm-db-exists?} and
@code{dbm-db-remove} on @code{<@var{foo}-meta>}.
@end itemize

Besides above, you may define the following methods.

@itemize @bullet
@item
Methods for @code{dbm-for-each} and @code{dbm-map}.
If you don't define them, a generic implementation
by @code{dbm-fold} is used.  There may be an implementation
specific way which is more efficient.
@item
Methods for @code{dbm-db-copy} and @code{dbm-db-move}.
If you don't define them, a fallback method
opens the specified databases and copies elements one by
one, and removes the original if the method is  @code{dbm-db-move}.
Note that the fallback method is not only inefficient,
but also it may not copy any implementation-specific
meta information.  It is highly recommended for the
dbm implementation to provide these methods as well.
@end itemize

It is generally recommended to name the implementation module
as @code{dbm.@var{foo}}, and the class of the implementation
as @code{<@var{foo}>}.  With this convention it is easier to
write an application that dynamically loads and uses
dbm implementation specified at runtime.

@c ----------------------------------------------------------------------
@node File-system dbm, GDBM interface, Generic DBM interface, Library modules - Utilities
@section @code{dbm.fsdbm} - File-system dbm
@c NODE ファイルシステムdbm, @code{dbm.fsdbm} - ファイルシステムdbm

@deftp {Module} dbm.fsdbm
@mdindex dbm.fsdbm
Implements fsdbm.  Extends @code{dbm}.
@end deftp

@deftp {Class} <fsdbm>
@clindex fsdbm
@c MOD dbm.fsdbm
@c EN
@code{Fsdbm} is a dbm implementation that directly uses
the filesystem.  Basically, it uses file names for keys,
and file content for values.   Unlike other dbm implementations,
this doesn't depend on external libraries---it is pure Scheme
implementation---so it is always available, while other dbm
implementations may not.
@c JP
@code{fsdbm}は、直接ファイルシステムを扱うDBM実装です。
基本的には、ファイル名をキー、ファイルの内容を値として使います。
他のDBM実装とは違い、これは他の特別なライブラリに依存しません
(純粋にSchemeのみにより実装されています)。
したがって、他のDBM実装が使えないときでも、いつでも使うことが
できます。

@c EN
Obviously, it is not suitable for the database that has
lots of entries, or has entries deleted and added very frequently.
The advantage is when the number of entries
are relatively small, and the values are relatively large while
keys are small.
@c JP
明らかに、たくさんのエントリを持っていたり、エントリの追加や
削除が頻繁に起こるようなデータベースには向いていません。
エントリの数が相対的に小さく、キーが小さいのに値が大きいような
場合に向いています。

@c EN
The database name given to @code{<fsdbm>} instance
is used as a directory name that stores the data.
@c JP
@code{<fsdbm>}のインスタンスに与えられるデータベース名は、
データを格納するディレクトリの名前として使われます。

@c EN
The data files are stored in subdirectories under @var{path} of
@code{fsdbm} instance, hashed by the key.  Non-alphanumeric characters
in the key is encoded like @code{_3a} for '@code{:}', for example.
If a key is too long to be a file name, it is chopped to chunks,
and each chunk but the last one is used as a directory name.
Note that a long key name may still cause a problem, for example,
some of old 'tar' command can't deal with pathnames (not each
pathname components, but the entire pathname) longer than 256
characters.
@c JP
データのファイルは、@code{fsdbm}インスタンスの@var{path}の
サブディレクトリに格納され、キーによりハッシュされます。
キーに英数字でない文字がある場合はエンコードされます。
例えば、'@code{:}'は、@code{_3a}にエンコードされます。
キーがファイル名としては長すぎる場合は、いくつかに
分割され、その最後の文字列片以外はディレクトリ名として
使われます。長いキー名は問題を引き起こすかも知れないことに
注意して下さい。例えば、いくつかの古い'tar'コマンドは、256文字
を越える長いパス名を扱えません(それぞれのパスコンポーネント
ではなく、パス名全体でです)。
@c COMMON
@end deftp

@c EN
Fsdbm implements all of the dbm protocol
(see @ref{Generic DBM interface}).
It doesn't have any fsdbm-specific procedures.
@c JP
fsdbmは、全てのDBMプロトコルを実装しています
(@ref{Generic DBM interface}参照)。
fsdbm特有の手続きというものはありません。
@c COMMON

@c ----------------------------------------------------------------------
@node GDBM interface, NDBM interface, File-system dbm, Library modules - Utilities
@section @code{dbm.gdbm} - GDBM interface
@c NODE GDBMインタフェース, @code{dbm.gdbm} - GDBMインタフェース

@deftp {Module} dbm.gdbm
@mdindex dbm.gdbm
Provides interface to the gdbm library.  Extends @code{dbm}.
@end deftp

@deftp {Class} <gdbm>
@clindex gdbm
@c MOD dbm.gdbm
@c EN
Inherits @code{<dbm>}.  Provides an implementation for GDBM library.
This module is only installed when your system already has GDBM
(1.8.0 is preferred, but works with older 1.7.x with some limitations).
@c JP
@code{<dbm>} を継承します。GDBM ライブラリのための実装を提供します。
このモジュールは、すでにあなたのシステムにすでに GDBM がある場合にのみ
インストールされます(バージョン 1.8.0 が推奨されますが、いくつかの制限が
あるだけで古い 1.7.x でも動作します)。
@c COMMON

@defivar <gdbm> sync
@end defivar
@defivar <gdbm> nolock
@end defivar
@defivar <gdbm> bsize
@end defivar
@end deftp

@c EN
Besides the unified DBM interface (@pxref{Generic DBM interface}),
this module provides the following low-level functions that provides
direct access to the gdbm API.  See gdbm manual for details of these
APIs.
@c JP
統合された DBM インターフェース (@pxref{Generic DBM interface}) の
他に、このモジュールでは GDBM API への直接のアクセスを提供する以下の
低レベルな手続きを提供しています。これらの API の詳細については GDBM の
マニュアルを見て下さい。
@c COMMON

@defun gdbm-open path :optional size rwmode fmode error-callback
@c MOD dbm.gdbm
@end defun

@defvar GDBM_READER
@c MOD dbm.gdbm
@end defvar

@defvar GDBM_WRITER
@c MOD dbm.gdbm
@end defvar

@defvar GDBM_WRCREAT
@c MOD dbm.gdbm
@end defvar

@defvar GDBM_NEWDB
@c MOD dbm.gdbm
@end defvar

@defvar GDBM_FAST
@c MOD dbm.gdbm
@end defvar

@defvar GDBM_SYNC
@c MOD dbm.gdbm
@end defvar

@defvar GDBM_NOLOCK
@c MOD dbm.gdbm
@end defvar

@defun gdbm-close gdbm-object
@c MOD dbm.gdbm
@end defun

@defun gdbm-closed? gdbm-object
@c MOD dbm.gdbm
@end defun

@defun gdbm-store key value :optional flag
@c MOD dbm.gdbm
@end defun

@defvar GDBM_INSERT
@c MOD dbm.gdbm
@end defvar

@defvar GDBM_REPLACE
@c MOD dbm.gdbm
@end defvar


@defun gdbm-fetch gdbm-object key
@c MOD dbm.gdbm
@end defun


@defun gdbm-delete gdbm-object key
@c MOD dbm.gdbm
@end defun


@defun gdbm-firstkey gdbm-object
@c MOD dbm.gdbm
@end defun


@defun gdbm-nextkey gdbm-object key
@c MOD dbm.gdbm
@end defun


@defun gdbm-reorganize gdbm-object
@c MOD dbm.gdbm
@end defun


@defun gdbm-sync gdbm-object
@c MOD dbm.gdbm
@end defun


@defun gdbm-exists? gdbm-object key
@c MOD dbm.gdbm
@end defun


@defun gdbm-strerror errno
@c MOD dbm.gdbm
@end defun


@defun gdbm-setopt gdbm-object option value
@c MOD dbm.gdbm
@end defun

@defvar GDBM_CACHESIZE
@c MOD dbm.gdbm
@end defvar

@defvar GDBM_FASTMODE
@c MOD dbm.gdbm
@end defvar

@defvar GDBM_SYNCMODE
@c MOD dbm.gdbm
@end defvar

@defvar GDBM_CENTFREE
@c MOD dbm.gdbm
@end defvar

@defvar GDBM_COALESCEBLKS
@c MOD dbm.gdbm
@end defvar

@defun gdbm-version
@c MOD dbm.gdbm
@end defun

@defun gdbm-errno
@c MOD dbm.gdbm
@end defun

@c ----------------------------------------------------------------------
@node NDBM interface, Original DBM interface, GDBM interface, Library modules - Utilities
@section @code{dbm.ndbm} - NDBM interface
@c NODE NDBMインタフェース, @code{dbm.ndbm} - NDBMインタフェース

@deftp {Module} dbm.ndbm
@mdindex dbm.ndbm
Provides interface to the 'new' dbm library, a.k.a. ndbm.
Extends @code{dbm}.
@end deftp

@deftp {Class} <ndbm>
@clindex ndbm
@c MOD dbm.ndbm
@c EN
Inherits @code{<dbm>}.  Provides an implementation for NDBM library.
This module is only installed when your system already has NDBM.
@c JP
@code{<dbm>} を継承します。NDBM ライブラリのための実装を提供します。
このモジュールはあなたのシステムにすでに NDBM がある場合にのみ
インストールされます。
@c COMMON
@end deftp

@c EN
Besides the unified DBM interface (@pxref{Generic DBM interface}),
this module provides the following low-level functions that provides
direct access to the ndbm API.  See ndbm manual for details of these
APIs.
@c JP
統合された DBM インターフェース (@pxref{Generic DBM interface}) の
他に、このモジュールでは NDBM API への直接のアクセスを提供する以下の
低レベルな手続きを提供しています。これらの API の詳細については NDBM の
マニュアルを見て下さい。
@c COMMON

@defun ndbm-open path flags mode
@c MOD dbm.ndbm
@end defun

@defun ndbm-close ndbm-object
@c MOD dbm.ndbm
@end defun

@defun ndbm-closed? ndbm-object
@c MOD dbm.ndbm
@end defun

@defun ndbm-store ndbm-object key content :optional flag
@c MOD dbm.ndbm
@end defun

@defun ndbm-fetch ndbm-object key
@c MOD dbm.ndbm
@end defun

@defun ndbm-delete ndbm-object key
@c MOD dbm.ndbm
@end defun

@defun ndbm-firstkey ndbm-object
@c MOD dbm.ndbm
@end defun

@defun ndbm-nextkey ndbm-object
@c MOD dbm.ndbm
@end defun

@defun ndbm-error ndbm-object
@c MOD dbm.ndbm
@end defun

@defun ndbm-clear-error ndbm-object
@c MOD dbm.ndbm
@end defun

@c ----------------------------------------------------------------------
@node Original DBM interface, Filtering file content, NDBM interface, Library modules - Utilities
@section @code{dbm.odbm} - Original DBM interface
@c NODE オリジナルのDBMインタフェース, @code{dbm.odbm} - オリジナルのDBMインタフェース

@deftp {Module} dbm.odbm
@mdindex dbm.odbm
Provides interface to the legacy dbm library.
Extends @code{dbm}.
@end deftp

@deftp {Class} <odbm>
@clindex odbm
@c MOD dbm.odbm
@c EN
Inherits @code{<dbm>}.  Provides an implementation for legacy DBM
library.
This module is only installed when your system already has DBM.

The biggest limitation of the legacy DBM is that you can only open
one database at a time.  You can create a multiple @code{<odbm>}
instances, but you can open at most one of it at a time, or
you'll get an error.
@c JP
@code{<dbm>} を継承しています。レガシーな DBM ライブラリのための実装を
提供します。このモジュールは、あなたのシステムにすでに DBM がある場合にのみ
インストールされます。

レガシー DBM の最大の制限は、データベースを一時に一つしか開けないことです。
複数の @code{<odbm>} のインスタンスを作ることができますが、一時に一つしか
開くことが出来ず、一つ以上開こうとするとエラーになります。
@c COMMON
@end deftp

@c EN
Besides the unified DBM interface (@pxref{Generic DBM interface}),
this module provides the following low-level functions that provides
direct access to the dbm API.  See dbm manual for details of these
APIs.
@c JP
統合された DBM インターフェース (@pxref{Generic DBM interface}) の
他に、このモジュールでは DBM API への直接のアクセスを提供する以下の
低レベルな手続きを提供しています。これらの API の詳細については DBM の
マニュアルを見て下さい。
@c COMMON

@defun odbm-init path
@c MOD dbm.odbm
@end defun

@defun odbm-close
@c MOD dbm.odbm
@end defun

@defun odbm-store key value
@c MOD dbm.odbm
@end defun

@defun odbm-fetch key
@c MOD dbm.odbm
@end defun

@defun odbm-delete key
@c MOD dbm.odbm
@end defun

@defun odbm-firstkey
@c MOD dbm.odbm
@end defun

@defun odbm-nextkey key
@c MOD dbm.odbm
@end defun


@c ----------------------------------------------------------------------
@c @node Pseudo DBM interface, gauche.charconv - Character code conversion, Original DBM interface, Library modules
@c @section @code{dbm.pdbm} - Pseudo DBM interface

@c ----------------------------------------------------------------------
@node Filtering file content, Filesystem utilities, Original DBM interface, Library modules - Utilities
@section @code{file.filter} - Filtering file content
@c NODE ファイルのフィルタ, @code{file.filter} - ファイルのフィルタ

@deftp {Module} file.filter
@mdindex file.filter
@c EN
This module provides utilities for a common pattern in
filter-type commands, that is, to take an input, to process
the content, and to write the result.   The common occurring
pattern is:

@itemize @bullet
@item
Input may be a specified file, or an input port
(the current input port by default).
@item
Output may be a specified file, or an output port
(the current output port by default).
@item
Output may be a temporary file, which will be renamed
upon completion of the processing.
@item
Output file may be removed when an error occurs
in the processing.
@end itemize
@c JP
このモジュールは、フィルター型のコマンド、
すなわち入力を読み込み、処理をして結果を書き出すような場合に
共通するパターンに使えるユーティリティ手続きを提供します。
共通するパターンとは：

@itemize @bullet
@item
入力は指定されたファイルかポートで、デフォルトはカレント入力ポート。
@item
出力は指定されたファイルかポートで、デフォルトはカレント出力ポート。
@item
出力は一時ファイルに書き出すこともできて、
その場合は処理が終了した時点で指定されたファイルにリネーム。
@item
処理途中でエラーが起こった場合に出力ファイルを削除
@end itemize
@c COMMON
@end deftp

@defun file-filter proc :key input output temporary-file keep-output? rename-hook
@c MOD file.filter
@c EN
Calls @var{proc} with two arguments, an input port and
an output port.   Returns the result(s) of @var{proc}.
The input port and output port are chosen depending on the keyword arguments.
@c JP
二つの引数、入力ポートと出力ポートを引数として@var{proc}を呼び出し、
その結果を返します。
入力ポートと出力ポートはキーワード引数により決定されます。
@c COMMON

@table @code
@item input
@c EN
The argument must be either an input port or a string
that specifies a file name.
If it's an input port, it is passed to @var{proc} as is.
If it's a string, the named file is opened for input and the resulting
port is passed to @var{proc}, and the port is closed when @var{proc}
returns.
If this argument is omitted, the current input port is passed.
@c JP
この引数は入力ポートかファイル名を示す文字列でなければなりません。
入力ポートの場合、それはそのまま@var{proc}に渡されます。
文字列が渡された場合は、そのファイル名を持つファイルを入力用にオープンし、
そのポートが@var{proc}に渡され、またこのポートは@var{proc}が戻った時に閉じられます。
この引数が省略された場合は、現在の入力ポートが渡されます。
@c COMMON
@item output
@c EN
The argument must be either an output port or a string
that specifies a file name.
If it's an output port, it is passed to @var{proc} as is.
If it's a string, the named file is opened for output
(unless @var{temporary-file} is given, in that case
a temporary file is opened instead), and the resulting port
is passed to @var{proc}.  This port is closed when @var{proc} returns.
If this argument is omitted, the current output port is passed.
@c JP
この引数は出力ポートかファイル名を示す文字列でなければなりません。
出力ポートの場合、それはそのまま@var{proc}に渡されます。
文字列が渡された場合は、そのファイル名を持つファイルを出力用にオープンし、
そのポートが@var{proc}に渡されます (但し、@var{temporary-file}
引数が渡された時はそれに指定されるファイルが一時ファイルとしてオープンされます)。
オープンされたポートは@var{proc}が戻った時に閉じられます。
この引数が省略された場合は、現在の出力ポートが渡されます。
@c COMMON
@item temporary-file
@c EN
The value must be a boolean or a string.  If a non-false value
is given, and output is a file, then a fresh temporary file is
created and opened for output and passed to @var{proc}.
When @var{proc} returns normally, the file is renamed
to the name given to @var{output} keyword argument.

If @code{#t} is given, a temporary file name is generated
based on the name of the output file.
If a string file name is given to this argument, the name
is used for @code{sys-mkstemp}.

If the given file name begins with characters except @code{"/"}, @code{"./"}
or @code{"../"}, the directory of the file name given to @var{output} argument
is attached before it.

The default value is @code{#f} (do not use a temporary file).
@c JP
値は真偽値か文字列でなければなりません。@code{#f}でない値が渡され、
かつ出力がファイルである場合、新たな一時ファイルが出力用に作成され@var{proc}に
渡されます。
そして@var{proc}が正常に返って来た時点で、一時ファイルは@var{output}に指定された
ファイルへとリネームされます。

この引数が@code{#t}の場合、一時ファイル名は出力ファイル名をもとに作られます。
この引数が文字列の場合はそれが@code{sys-mkstemp}に渡されます。

もし一時ファイル名が@code{"/"}、@code{"./"}、@code{"../"}以外の
文字で始まっていた場合は、@var{output}に与えられたファイル名のディレクトリが
一時ファイルの前に追加されます。

デフォルトの値は@code{#f} (一時ファイルを使わない) です。
@c COMMON
@item keep-output?
@c EN
If a true value is given, the output is not deleted even
when @var{proc} signals an error.
By default, the output (or the temporary file when
@var{temporary-file} is given) will be deleted on error.
@c JP
真の値が与えられた場合、@var{proc}がエラーになった場合でも出力ファイルを削除しません。
デフォルトでは、出力ファイル(もしくは@var{temporary-file}が与えられた場合は
そのファイル)はエラーの場合には削除されます。
@c COMMON
@item leave-unchanged
@c EN
When a temporary file is used, and a true value is given to this argument,
the existing output file is left intact when the generated output in
the temporary file exactly matches the original content of the output
file.  It is useful if touching output file may trigger some actions
(e.g. by @code{make}) and you want to avoid invoking unnecessary
actions.  The default value is @code{#f} (always replace the output).
@c JP
一時ファイルを使う場合に、この引数に真の値が与えられると、
出力ファイルが既に存在して一時ファイルに生成された内容と全く同じだった場合に、
出力ファイルをそのままにします。これは、出力ファイルに触ることで何らかの
アクションが起きるようになっている場合に(例: @code{make})、
不必要なアクションを起こさないために便利です。
デフォルトの値は@code{#f} (常に出力ファイルを置き換える) です。
@c COMMON
@end table
@end defun

@defun file-filter-fold proc seed :key reader input output temporary-file keep-output? rename-hook
@c MOD file.filter
@c EN
A convenience wrapper of @code{file-filter}.
Call @var{proc} for each item read from input
by @var{reader} (@code{read-line} by default).  The argument
@var{proc} receives is the item, the seed value and the output port;
@var{proc} can emit the output, as well as returning some value
that is passed along as the seed value.  Other keyword arguments
are passed to @code{file-filter}.

For example, the following code reads each line from @file{file.txt} and
displays lines matching @code{#/regexp/} with line numbers.
@c JP
@file{file-filter}の便利なラッパー手続きです。
入力から@var{reader}によって読まれるデータに対して次々に@var{proc}を
呼び出します。@var{reader}のデフォルトは@code{read-line}です。
@var{proc}の引数は、読まれたデータ、シード値、出力ポートです。
@var{proc}は何かを出力することもできますし、値を返せばそれが
次のシード値として受け渡されてゆきます。他のキーワード引数は
@code{file-filter}にそのまま渡されます。

例えば次のコードは、@file{file.txt}を1行づつ読み、@code{#/regexp/}に
マッチする行を行番号つきで出力します。
@c COMMON

@example
(file-filer-fold
  (^[line nc out]
    (when (#/regexp/ line) (format out "~3d: ~a\n" nc line))
    (+ nc 1))
  1 :input "file.txt")
@end example
@end defun

@defun file-filter-map proc :key reader input output temporary-file keep-output? rename-hook
@defunx file-filter-for-each proc :key reader input output temporary-file keep-output? rename-hook
@c MOD file.filter
@c EN
Utilities similar to @code{file-filter-fold},
like @code{map} and @code{for-each} to @code{fold}.

The procedure @var{proc} is called with two arguments,
an item read from the input and an output port.
The results of @var{proc} are collected as a list and returned
by @code{file-filter-map}, and discarded by @code{file-filter-for-each}.

The meaning of keyword arguments are the same as @code{file-filter-fold}.
@c JP
@code{file-filter-fold}に似たユーティリティです。
@code{fold}に対する@code{map}、@code{for-each}に相当します。

手続き@var{proc}は二つの引数、入力から読まれたデータと出力ポートを受けとります。
@var{proc}の結果は、@code{file-filter-map}では集められてリストとして
戻り値となり、@code{file-filter-for-each}では捨てられます。

キーワード引数の意味は@code{file-filter-fold}と同じです。
@c COMMON
@end defun


@c ----------------------------------------------------------------------
@node Filesystem utilities, Mathematic constants, Filtering file content, Library modules - Utilities
@section @code{file.util} - Filesystem utilities
@c NODE ファイルシステムユーティリティ, @code{file.util} - ファイルシステムユーティリティ

@deftp {Module} file.util
@mdindex file.util
@c EN
Provides convenient utility functions handling files and directories.
Those functions are built on top of the primitive system
procedures described in @ref{Filesystems}.
@c JP
ファイルやディレクトリを扱う便利な手続き群を提供します。
これらの手続きは@ref{Filesystems}で述べられたプリミティブなシステム手続きの上に
構築されています。
@c COMMON

@c EN
Many procedures in this module takes a keyword argument @var{follow-link?},
which specifies the behavior when the procedure sees a symbolic link.
If true value is given to @var{follow-link?} (which is the default),
the procedure operates on the file referenced by the link; if false is
given, it operates on the link itself.
@c JP
このモジュール内の多くの手続きは@var{follow-link?}というキーワード引数を取ります。
これは手続きがシンボリックリンクに出会ったときの動作を指定します。@var{follow-link?}が
真であれば、手続きはリンクの指す先のファイルに作用します。これがデフォルトの振舞いです。
@var{follow-link?}に@code{#f}が渡された場合は手続きはリンクそのものに作用します。
@c COMMON
@end deftp

@c EN
Note on the naming convention: Some Scheme implementations "create"
new directories and files, while the others "make" them.
Some implementations "delete" them, while the others "remove" them.
It seems that both conventions are equally popular.
So Gauche provides @emph{both}.
@c JP
名前つけ規則に関する注記：ファイルやディレクトリを
作成するのに@code{"create"}という語を使う処理系と@code{"make"}を
使う処理系があります。ファイルやディレクトリを削除するのにも@code{"remove"}と
@code{"delete"}の流派があります。どちらも同じくらい広く使われているようなので、
Gaucheでは@emph{両方の}名前を提供することにしました。
@c COMMON

@menu
* Directory utilities::
* Pathname utilities::
* File attribute utilities::
* File operations::
* Temporary files and directories::
* Lock files::
@end menu

@node Directory utilities, Pathname utilities, Filesystem utilities, Filesystem utilities
@subsection Directory utilities
@c NODE ディレクトリユーティリティ

@defun current-directory :optional new-directory
@c MOD file.util
@c EN
When called with no argument, this returns the pathname of the current
working directory.  When called with a string argument @var{new-directory},
this sets the current working directory of the process to it.
If the process can't change directory to @var{new-directory}, an error is
signaled.

This function is in ChezScheme, MzScheme and some other Scheme
implementations.

SRFI-170 defines @code{current-directory} without arguments, to return
the current working directory.
@c JP
引数無しで呼ばれた場合、カレントディレクトリを返します。
文字列@var{new-directory}が与えられた場合はプロセスのカレントディレクトリを
@var{new-directory}に変更します。変更が出来なかった場合はエラーとなります。

この関数はChezSchemeやMzSchemeなどいくつかのScheme処理系に見られます。

SRFI-170は引数を取らない@code{current-directory}を定義しています。
現在のディレクトリを返すのは一緒です。
@c COMMON
@end defun

@defun home-directory :optional user
@c MOD file.util
@c EN
Returns the home directory of the given @var{user},
which may be a string user name or an integer user id.
If @var{user} is omitted, the current user is assumed.
If the given user cannot be found, or the home directory
of the user cannot be determined, @code{#f} is returned.
@c JP
名前または整数のユーザidで与えられたユーザ@var{user}のホームディレクトリを
返します。@var{user}が省略された場合はカレントユーザが使われます。
与えられたユーザが見付けられないか、ホームディレクトリを決定できなかった場合は
@code{#f}が返されます。
@c COMMON

@c EN
On Windows native platforms, this function is only supported
to query the current user's directory.
@c JP
Windowsネイティブ環境では、この関数はカレントユーザに対してのみ動作します。
@c COMMON
@end defun

@defun directory-list path :key children? add-path? filter filter-add-path?
@c MOD file.util
@c EN
Returns a list of entries in the directory @var{path}.
The result is sorted by dictionary order.

By default, only the basename (the last component) of the entries
returned.   If @var{add-path?} is given and true, @var{path} is appended
to each entry.  If @var{children?} is given and true, @code{"."} and
@code{".."} are excluded from the result.

If @var{filter} is given, it must be a predicate that takes one argument.
It is called on every element of the directory entry,
and only the entries on which
@var{filter} returns true are included in the result.
The argument passed to @var{filter} is a basename of the directory entry
by default, but when @var{filter-add-path?} is true, @var{path} is
appended to the entry.

If @var{path} is not a directory, an error is signaled.
@c JP
ディレクトリ@var{path}中のエントリのリストを返します。
リストは文字列順にソートされます。

デフォルトではエントリのベースネーム(パスの最後のコンポーネント)のみが
返されますが、キーワード引数@var{add-path?}に真の値が与えられた時は
@var{path}が各エントリの前に追加されます。
@var{children?}に真の値が与えられた時は、カレントディレクトリと親ディレクトリが
リストから除かれます。

@var{filter}引数は、もし与えられれば、一つの引数を取る
手続きでなければなりません。ディレクトリ中の各エントリを引数としてその手続きが呼ばれ、
真を返したエントリのみが結果に含まれます。
@var{filter}に与えられるエントリはデフォルトではベース名のみですが、
引数@var{filter-add-path?}が真ならば@var{path}が前に追加された名前となります。

@var{path}がディレクトリでない場合はエラーが報告されます。
@c COMMON

@example
(directory-list "test")
 @result{} ("." ".." "test.scm" "test.scm~")

(directory-list "test" :add-path? #t)
 @result{} ("test/." "test/.." "test/test.scm" "test/test.scm~")

(directory-list "test" :children? #t)
 @result{} ("test.scm" "test.scm~")

(directory-list "test" :children? #t :add-path? #t
   :filter (lambda (e) (not (string-suffix? "~" e))))
 @result{} ("test/test.scm")
@end example
@end defun

@defun directory-list2 path :key children? add-path? filter follow-link?
@c MOD file.util
@c EN
Like @code{directory-list}, but returns two values; the first one is a list
of subdirectories, and the second one is a list of the rest.
The keyword arguments @var{children?}, @code{add-path?} and @var{filter}
are the same as @code{directory-list}.

Giving false value to @var{follow-link?} makes @code{directory-list2}
not follow the symbolic links; if the @var{path} contains a
symlink to a directory,
it will be included in the first list if @var{follow-link?}
is omitted or true,
while it will be in the second list if @var{follow-link?} is false.
@c JP
@code{directory-list}に似ていますが、ふたつの値を返します。最初の値は
@var{path}内にあるサブディレクトリのリストで、次の値はそれ以外のエントリのリストです。
キーワード引数@var{children?}、@code{add-path?}、@var{filter}は
@code{directory-list}と同じ意味をもちます。

偽の値を@var{follow-link?}に与えると、@var{path}内のシンボリックリンクを
辿りません；すなわち、@var{path}内にディレクトリへのシンボリックリンクがあった場合、
デフォルト、もしくは@var{follow-link?}に真の値が与えられた場合は
それは最初のリスト(サブディレクトリ)に入りますが、@var{follow-link?}
に偽の値が与えられた場合は後者のリスト(その他のエントリ)に入ります。
@c COMMON
@end defun

@defun directory-fold path proc seed :key lister follow-link?
@c MOD file.util
@c EN
A fundamental directory traverser.
Conceptually it works as follows, in recursive way.
@c JP
ディレクトリ探索の最も基本的な手続きです。基本的な動作は以下に示すような再帰的なものです。
@c COMMON

@c EN
@itemize @bullet
@item
If @var{path} is not a directory, calls
@code{(@var{proc} @var{path} @var{seed})} and returns the result.
@item
If @var{path} is a directory, calls
@code{(@var{lister} @var{path} @var{seed})}.  The procedure @var{lister}
is expected to return two values: a list of pathnames, and the
next seed value.   Then
@code{directory-fold} is called on each returned pathname,
passing the returned seed value to the @var{seed} argument of the
next call of @code{directory-fold}.
Returns the result of the last seed value.
@end itemize
@c JP
@itemize @bullet
@item
@var{path}がディレクトリでない場合は@code{(@var{proc} @var{path} @var{seed})} を
評価し、結果を返します。
@item
@var{path}がディレクトリであった場合、まず
@code{(@var{lister} @var{path} @var{seed})} を評価します。
手続き@var{lister}は2つの値、パス名のリストと次のseedとなる値を
返さなければなりません。
続いて、@code{directory-fold}が各パス名に対して再帰的に呼ばれます。
各呼び出しの結果が次の再帰呼び出しの@var{seed}の値に使われます。
@end itemize
@c COMMON

@c EN
The default procedure of @var{lister} is just a call to @code{directory-list},
as follows.
@c JP
デフォルトの@var{lister}は@code{directory-list}を次のように呼び出すものです。
@c COMMON
@example
(lambda (path seed)
  (values (directory-list path :add-path? #t :children? #t)
          seed))
@end example

@c EN
Note that @var{lister} shouldn't return the given path itself (@code{"."})
nor the parent directory (@code{".."}), or the recursion wouldn't
terminate.  Also note @var{lister} is expected to return a path accessible
from the current directory, i.e. if @var{path} is @code{"/usr/lib/foo"} and
it contains @code{"libfoo.a"} and @code{"libfoo.so"}, @var{lister} should
return @code{'("/usr/lib/foo/libfoo.a" "/usr/lib/foo/libfoo.so")}.
@c JP
@var{lister}は@var{path}自身への参照 (@code{"."}) やその親ディレクトリへの参照を
返してはなりません。また、@var{lister}の戻り値は現在のディレクトリからアクセス可能な
パス名でなければなりません。例えば@var{path}が@code{"/usr/lib/foo"}であり、
そのディレクトリが@code{"libfoo.a"}と@code{"libfoo.so"}を含んでいた場合、
@var{lister}は@code{'("/usr/lib/foo/libfoo.a" "/usr/lib/foo/libfoo.so")}
のようなリストを返す必要があります。
@c COMMON

@c EN
The keyword argument @var{follow-link?} is used to determine whether
@var{lister} should be called on a symbolic link pointing to a directory.
When @var{follow-link?} is true (default), @var{lister} is called
with the symbolic link if it points to a directory.
When @var{follow-link?} is false, @var{proc} is not called.
@c JP
キーワード引数@var{follow-link?}はディレクトリを指しているシンボリックリンクに対して
@var{lister}を呼ぶかどうかを決定します。@var{follow-link?}が真(デフォルト値)である
場合はそのようなシンボリックリンクに対しても@var{lister}が呼ばれます。
一方、@var{follow-link?}が偽であればシンボリックリンクに対しては@var{proc}が呼ばれます。
@c COMMON

@c EN
The following example returns a list of pathnames of the emacs backup files
(whose name ends with "~") under the given path.
@c JP
次の例は、与えられたpath以下からemacsのバックアップファイル ("~"で終る名を持つファイル)
のリストを返します。
@c COMMON
@example
(use srfi-13) ;; for string-suffix?
(directory-fold path
                (lambda (entry result)
                  (if (string-suffix? "~" entry)
                      (cons entry result)
                      result))
                '())
@end example

@c EN
The following example lists all the files and directories under the
given pathname.   Note the use of @var{lister} argument to include
the directory path itself in the result.
@c JP
次の例は与えられたpath以下全てのファイルとディレクトリ名をリストにして
返します。@var{lister}引数を使ってディレクトリ名そのものを結果に
含めていることに注目して下さい。
@c COMMON
@example
(directory-fold path cons '()
  :lister (lambda (path seed)
            (values (directory-list path :add-path? #t :children? #t)
                    (cons path seed))))
@end example

@end defun

@defun make-directory* name :optional perm
@defunx create-directory* name :optional perm
@c MOD file.util
@c EN
Creates a directory @var{name}.  If the intermediate path to the
directory doesn't exist, they are also created
(like @code{mkdir -p} command on Unix).   If the directory
@var{name} already exist, these procedure does nothing.
@var{Perm} specifies the integer flag for permission bits of the
directory.
@c JP
ディレクトリ@var{name}を作成します。@var{name}に至るパスが存在しない
場合は必要なディレクトリが作成されます (Unixの@code{mkdir -p}コマンドと
同様です)。ディレクトリ@var{name}が既に存在していた場合は何もしません。
@var{perm}は作成されるディレクトリのパーミッションビットを指定します。
@c COMMON
@end defun


@defun remove-directory* name
@defunx delete-directory* name
@c MOD file.util
@c EN
Deletes directory @var{name} and its content recursively
(like @code{rm -r} command on Unix).   Symbolic links are not
followed.
@c JP
ディレクトリ@var{name}とその内容を再帰的に消去します
(Unixの@code{rm -r}コマンドと同様です)。シンボリックリンクは辿られません。
@c COMMON
@end defun

@defun copy-directory* src dst :key if-exists backup-suffix safe keep-timestamp keep-mode follow-link?
@c MOD file.util
@c EN
If @var{src} is a regular file, copies its content to @var{dst}, just like
@code{copy-file} does.  If @var{src} is a directory, recursively
descends it and copy the file tree to @var{dst}.  Basically
it mimics the behavior of @code{cp -r} command.

If there's any symbolic links under @var{src}, the link itself
is copied instead of the file pointed to by it, unless a true value
is given to the @var{follow-link?} keyword argument,
i.e. the default value of @var{follow-link?} is @code{#f}.
(Note that this is opposite to the @code{copy-file}, in which
@var{follow-link?} is true by default.)
@c JP
@var{src}が通常のファイルであれば、@code{copy-file}と同じように
その内容を@var{dst}にコピーします。しかし@var{src}がディレクトリの場合は、
再帰的にディレクトリを辿り、その全てを@var{dst}へとコピーします。
@code{cp -r}コマンドに相当するものだと考えて良いでしょう。

@var{src}がディレクトリの場合、デフォルトではその下にあるシンボリックリンクは
辿られず、リンクそのものがコピーされます。リンク先の内容をもコピーしたい
場合は@var{follow-link?}キーワード引数に真の値を与えてください。
つまり、@var{follow-link?}キーワード引数のデフォルト値は@code{#f}です。
(このデフォルト値は@code{copy-file}と逆であることに注意してください。
@code{copy-file}では@var{follow-link?}はデフォルトで真であり、
リンクそのものをコピーしたい場合に明示的に@code{#f}を与える必要があります。)
@c COMMON

@c EN
The meanings of the other keyword arguments are the same as
@code{copy-file}.  See the entry of @code{copy-file} for the details.
@c JP
他のキーワード引数の意味は@code{copy-file}と同じです。
詳細は@code{copy-file}を参照してください。
@c COMMON
@end defun

@defun create-directory-tree dir spec
@c MOD file.util
@c EN
Creates a directory tree under @var{dir} according to @var{spec}.
This procedure is useful to set up certain directory hierarchy at once.

The @var{spec} argument is an S-expression with the following structure:

@example
<spec> : <name>                             ; empty file
       | (<name> <option> ...)              ; empty file
       | (<name> <option> ... <string>)     ; file with content
       | (<name> <option> ... <procedure>)  ; file with generated content
       | (<name> <option> ... (<spec> ...)) ; directory

<name> : string or symbol

<option> ... : keyword-value alternating list
@end example
@c JP
@var{spec}で指定されるディレクトリツリーを@var{dir}の下に作成します。
特定のディレクトリ構造を一気にセットアップする際に便利です。

@var{spec}引数は次に示される構造をもつS式です。

@example
<spec> : <name>                             ; 空のファイル
       | (<name> <option> ...)              ; 空のファイル
       | (<name> <option> ... <string>)     ; 固定内容のファイル
       | (<name> <option> ... <procedure>)  ; 内容を生成するファイル
       | (<name> <option> ... (<spec> ...)) ; ディレクトリ

<name> : 文字列かシンボル

<option> ... : キーワードと値の交代リスト
@end example
@c COMMON

@c EN
With the first and second form of @var{spec}, an empty file is created
with the given name.
With the third form of @var{spec}, the string becomes the
content of the file.

With the fourth form of @var{spec}, the procedure is called with the
pathname as an argument, and output to the current output
port within the procedure is written to the created file.
The pathname is relative to the @var{dir} argument.
At the time the procedure is called, its parent directory
is already created.

The last form of @var{spec} creates a named directory,
then creates its children recursively according to the specs.
@c JP
@var{spec}の最初と2番目の形式では、名前@var{name}を持つ空のファイルが作られます。
3番目の形式では与えられた文字列がファイルの内容となります。

4番目の形式では、手続きがファイルのパス名を引数として呼び出され、
その手続きがcurrent output portに出力した内容がファイルの内容となります。
引数に渡されるパス名は@var{dir}引数からの相対パスです。
手続きが呼ばれる時、その親ディレクトリは既につくられています。

最後の形式は、名前@var{name}を持つディレクトリを作成し、
その子供として再帰的に指定された@var{spec}によるファイル/ディレクトリを作成します。
@c COMMON

@c EN
With @var{option}s you can control attributes of created files/directories.
Currently the following options are recognized.

@table @code
@item :mode @var{mode}
Takes integer as permission mode bits.
@item :owner @var{uid}
@itemx :group @var{gid}
Takes integer uid/gid of the owner/group of the file/directory.
Calling process may need special privilege to change the owner
and/or group.
@item :symlink @var{path}
This is only valid for file spec, and it causes
@code{create-directory-tree} to create a named symbolic link
whose content is @var{path}.
@end table
@c JP
@var{option}によって、作られるファイル/ディレクトリの属性を細かく指定できます。
今のところ、次のオプションが認識されます。

@table @code
@item :mode @var{mode}
整数@var{mode}でパーミッションのモードビットを指定します。
@item :owner @var{uid}
@itemx :group @var{gid}
整数@var{uid}/@var{gid}で作成されるエントリのオーナー/グループを指定します。
作成されるエントリのオーナー/グループを変更するには、
呼び出すプロセスに特権が必要かもしれません。
@item :symlink @var{path}
ファイルを作成する@var{spec}でのみ有効なオプションで、
@var{path}を指すシンボリックリンクを作成します。
@end table
@c COMMON
@end defun

@defun check-directory-tree dir spec
@c MOD file.util
@c EN
Checks if a directory hierarchy according to @var{spec} exists
under @var{dir}.  Returns @code{#t} if it exists, or @code{#f} otherwise.

The format of @var{spec} is the same
as @code{create-directory-tree} described above.

If @var{spec} contains options, the attributes of existing
files/directories are also checked if they match the given options.
@c JP
@var{spec}で記述されるディレクトリ階層が@var{dir}の下に存在するかどうかを
調べ、存在すれば@code{#t}、そうでなければ@code{#f}を返します。

@var{spec}の形式は上で説明した@code{create-directory-tree}と同じです。

@var{spec}がオプションを含んでいる場合、該当するファイル/ディレクトリの
属性もそのオプションに合致するかどうかチェックされます。
@c COMMON
@end defun


@node Pathname utilities, File attribute utilities, Directory utilities, Filesystem utilities
@subsection Pathname utilities
@c NODE パスネームユーティリティ

@defun build-path base-path component @dots{}
@c MOD file.util
@c EN
Appends pathname components @var{component} to the @var{base-path}.
@var{Component} can be a symbol @code{up} or @code{same};
in Unix, they are synonym to @code{".."} and @code{"."}.
This API is taken from MzScheme.
@c JP
パス名のコンポーネント@var{component}を@var{base-path}に追加します。
@var{Component}はシンボル@code{up}または@code{same}であっても
構いません; Unixではそれらは@code{".."}または@code{"."}と等価です。
このAPIはMzSchemeから採られました。
@c COMMON
@end defun

@defun absolute-path? path
@defunx relative-path? path
@c MOD file.util
@c EN
Returns @code{#t} if @var{path} is absolute or relative, respectively.
@c JP
@var{path}がそれぞれ絶対パスまたは相対パスならば@code{#t}を返します。
@c COMMON
@end defun

@defun expand-path path
@c MOD file.util
@c EN
Expands tilda-notation of @var{path} if it contains one.
Otherwise, @var{path} is returned.  This function does not
check if @var{path} exists and/or readable.
@c JP
@var{path}がチルダ表記を含んでいたらそれを展開したものを返します。
そうでなければ@var{path}そのものを返します。この手続きは@var{path}が
存在しアクセス可能であるかどうかはチェックしません。
@c COMMON
@end defun

@defun resolve-path path
@c MOD file.util
@c EN
Expands @var{path} like @code{expand-path},
then resolve symbolic links for every components
of the path.  If @var{path} does not exist, or contains dangling link,
or contains unreadable directory, an error is signaled.
@c JP
@var{path}を@code{expand-path}と同様に展開し、
続いて@var{path}の各コンポーネントに対してそれがシンボリックリンクであればリンク先の
ものに置き換えてゆきます。@var{path}が存在しないパスを指していたり、
シンボリックリンクの先が存在しなかったり、読み出せないディレクトリがあった場合は
エラーとなります。
@c COMMON
@end defun

@defun simplify-path path
@c MOD file.util
@c EN
Remove 'up' (@code{".."}) components and 'same' (@code{"."}) components
from @var{path} as much as possible.
This function does not access the filesystem.
@c JP
@var{path}から、親ディレクトリへの参照(@code{".."})と自分自身への参照(@code{"."})を
出来る限り取り除きます。この手続きはファイルシステムへはアクセスしません。
@c COMMON
@end defun

@defun decompose-path path
@c MOD file.util
@c EN
Returns three values; the directory part of @var{path},
the basename without extension of @var{path}, and
the extension of @var{path}.    If the pathname doesn't have an extension,
the third value is @code{#f}.  If the pathname ends with a directory
separator, the second and third values are @code{#f}. (Note: This treatment
of the trailing directory separator differs from
@code{sys-dirname}/@code{sys-basename}; those follow popular shell's
convention, which ignores trailing slashes.)
@c JP
パス名@var{path}のディレクトリ部、拡張子を除いたファイル名、
そして拡張子の3つの値を返します。パス名が拡張子を持たない場合、
最後の値は@code{#f}になります。パス名がディレクトリセパレータで
終わっている場合は2番目と3番目の値が@code{#f}になります。
(後置されたディレクトリセパレータに関するこの取扱いは、
@code{sys-dirname}/@code{sys-basename}と異なることに注意して下さい。
@code{sys-dirname}等は後置されたディレクトリセパレータを無視するという
シェル等の慣習に従っています。)
@c COMMON
@example
(decompose-path "/foo/bar/baz.scm")
  @result{} "/foo/bar", "baz", "scm"
(decompose-path "/foo/bar/baz")
  @result{} "/foo/bar", "baz", #f

(decompose-path "baz.scm")
  @result{} ".", "baz", "scm"
(decompose-path "/baz.scm")
  @result{} "/", "baz", "scm"

;; Boundary cases
(decompose-path "/foo/bar/baz.")
  @result{} "/foo/bar", "baz", ""
(decompose-path "/foo/bar/.baz")
  @result{} "/foo/bar", ".baz", #f
(decompose-path "/foo/bar.baz/")
  @result{} "/foo/bar.baz", #f, #f
@end example
@end defun

@defun path-extension path
@defunx path-sans-extension path
@c MOD file.util
@c EN
Returns an extension of @var{path},
and  a pathname of @var{path} without extension, respectively.
If @var{path} doesn't have an extension, @code{#f} and @var{path}
is returned respectively.
@c JP
それぞれ、@var{path}の拡張子と、@var{path}から拡張子を除いたものを返します。
@var{path}が拡張子を持っていない場合はそれぞれ@code{#f}と@var{path}が返されます。
@c COMMON

@example
(path-extension "/foo/bar.c")       @result{} "c"
(path-sans-extension "/foo/bar.c")  @result{} "/foo/bar"

(path-extension "/foo/bar")         @result{} #f
(path-sans-extension "/foo/bar")    @result{} "/foo/bar"
@end example
@end defun

@defun path-swap-extension path newext
@c MOD file.util
@c EN
Returns a pathname in which the extension of @var{path} is replaced
by @var{newext}.  If @var{path} doesn't have an extension,
"." and @var{newext} is appended to @var{path}.

If @var{newext} is @code{#f}, it returns @var{path} without extension.
@c JP
@var{path}の拡張子が@var{newext}に置換されたものが返されます。@code{path}が
拡張子を持たない場合は、@var{path}に "." と@var{newext}が追加されます。

@var{newext}が@code{#f}の場合は、@var{path}の拡張子が除かれたものが
返されます。
@c COMMON

@example
(path-swap-extension "/foo/bar.c" "o")  @result{} "/foo/bar.o"
(path-swap-extension "/foo/bar.c" "")   @result{} "/foo/bar."
(path-swap-extension "/foo/bar.c" #f)   @result{} "/foo/bar"

(path-swap-extension "/foo/bar" "o")  @result{} "/foo/bar.o"
(path-swap-extension "/foo/bar" "")   @result{} "/foo/bar."
(path-swap-extension "/foo/bar" #f)   @result{} "/foo/bar"
@end example
@end defun

@defun find-file-in-paths name :key paths pred extensions
@c MOD file.util
@c EN
Looks for a file that has name @var{name} in the given list of pathnames
@var{paths} and that satisfies a predicate @var{pred}.  If found,
the absolute pathname of the file is returned.  Otherwise, @code{#f}
is returned.

If @var{name} is an absolute path, only the existence of @var{name}
and whether it satisfies @var{pred} are checked.

The default value of @var{paths} is taken from the environment variable
@code{PATH}, and the default value of @var{pred} is @code{file-is-executable?}
(@pxref{File attribute utilities}).  That is, @code{find-file-in-paths}
searches the named executable file in the command search paths
by default.
@c JP
名前@var{name}を持ち、述語@var{pred}を満たすファイルをパス名のリスト@var{paths}
から探します。見つかった場合はファイルの絶対パス名を、見つからなかった場合は
@code{#f}を返します。

@var{name}が絶対パス名で与えられた場合はそれが存在するかどうかと
@var{pred}を満たすかどうかのみがチェックされます。

@var{paths}のデフォルト値は環境変数@code{PATH}から取られます。また、
@var{pred}のデフォルト値は@code{file-is-executable?}
(@ref{File attribute utilities}参照)です。すなわち、デフォルトでは
この手続きはコマンドサーチパスから実行可能ファイルを探すのに使えます。
@c COMMON

@example
(find-file-in-paths "ls")
  @result{} "/bin/ls"

@c EN
;; @r{example of searching user preference file of my application}
@c JP
;; @r{アプリケーション"myapp"のユーザプレファレンスファイルを探す例}
@c COMMON
(find-file-in-paths "userpref"
  :paths `(,(expand-path "~/.myapp")
           "/usr/local/share/myapp"
           "/usr/share/myapp")
  :pred  file-is-readable?)
@end example

@c EN
The @var{extensions} keyword argument may list alternative extensions
added to @var{name}.  For example, the following example searches
not only @file{notepad}, but also @file{notepad.exe} and @file{notepad.com},
in the PATH.  If an alternate name is found,
the returned pathname contains the extension.
@c JP
@var{extensions}キーワード引数には、@var{name}に追加して探すべき拡張子の
リストを指定できます。例えば次の例では、@file{notepad}に加え
@file{notepad.exe}と@file{notepad.com}がPATHから探されます。
拡張子つきの名前が見つかった場合、返されるパスは拡張子を含んだものとなります。
@c COMMON

@example
(find-file-in-paths "notepad" :extensions '("exe" "com"))
@end example

@c EN
For each path, the name and the alternative names are checked in order.
That is,
if there are @file{/bin/b.com} and @file{/usr/bin/b.exe} and @var{paths}
is @code{("/bin" "/usr/bin")}, you'll get @file{/bin/b.com} when you
search @file{b} with extensions @code{("exe" "com")}.
@c JP
各パスについて、@var{name}および拡張子つきの名前が順にチェックされます。
すなわち、@file{/bin/b.com}と@file{/usr/bin/b.exe}があって
@var{paths}が@code{("/bin" "/usr/bin")}である場合、
@var{extensions}に@code{("exe" "com")}を与えて@file{b}を探すと、
@file{/bin/b.com}が返ります。
@c COMMON
@end defun

@defun null-device
@c MOD file.util
@c EN
Returns a name of the @emph{null} device.
On unix platforms (including cygwin) it returns @code{"/dev/null"},
and on Windows native platforms (including mingw) it returns @code{"NUL"}.
@c JP
nullデバイス名を返します。cygwinを含むunixプラットフォームでは
@code{"/dev/null"}、mingwを含むWindowsネイティブプラットフォームでは
@code{"NUL"}が返されます。
@c COMMON
@end defun

@defun console-device
@c MOD file.util
@c EN
Returns a name of the console device.
On unix platforms (including cygwin) it returns @code{"/dev/tty"},
and on Windows native platforms (including mingw) it returns @code{"CON"}.

This function does not guarantee the device is actually available
to the calling process.
@c JP
コンソールデバイス名を返します。cygwinを含むunixプラットフォームでは
@code{"/dev/tty"}、mingwを含むWindowsネイティブプラットフォームでは
@code{"CON"}が返されます。

そのデバイスが実際に現在のプロセスから利用可能であるかどうかはチェックされません。
@c COMMON
@end defun


@node File attribute utilities, File operations, Pathname utilities, Filesystem utilities
@subsection File attribute utilities
@c NODE ファイル属性ユーティリティ

@defun file-type path :key follow-link?
@defunx file-perm path :key follow-link?
@defunx file-mode path :key follow-link?
@defunx file-ino path :key follow-link?
@defunx file-dev path :key follow-link?
@defunx file-rdev path :key follow-link?
@defunx file-nlink path :key follow-link?
@defunx file-uid path :key follow-link?
@defunx file-gid path :key follow-link?
@defunx file-size path :key follow-link?
@defunx file-atime path :key follow-link?
@defunx file-mtime path :key follow-link?
@defunx file-ctime path :key follow-link?
@c MOD file.util
@c EN
These functions return the attribute of file/directory specified by
@var{path}.  The attribute name corresponds to the slot name of
@code{<sys-stat>} class (@pxref{File stats}).
If the named path doesn't exist, @code{#f} is returned.

If @var{path} is a symbolic link, these functions queries the
attributes of the file pointed by the link, unless
an optional argument @var{follow-link?} is given and false.

MzScheme and Chicken have @code{file-size}.  Chicken also has
@code{file-modification-time}, which is @code{file-mtime}.
@c JP
これらの手続きは@var{path}で示されるファイルやディレクトリのアトリビュートを
返します。アトリビュート名は@code{<sys-stat>}のスロット名に対応しています。
@ref{File stats}を参照して下さい。@var{path}で示されるファイルが
存在しなければ@code{#f}が返されます。

@var{path}がシンボリックリンクだった場合、オプショナルな引数
@var{follow-link?} に偽の値が与えられていない限り、これらの手続きは
リンクの指す先のファイルに関する情報を返します。

MzSchemeとChickenには@code{file-size}があります。
Chickenには@code{file-modification-time}があり、これは@code{file-mtime}と
同じです。
@c COMMON
@end defun

@defun file-is-readable? path
@defunx file-is-writable? path
@defunx file-is-executable? path
@c MOD file.util
@c EN
Returns @code{#t} if @var{path} exists and readable/writable/executable
by the current effective user, respectively.
This API is taken from STk.
@c JP
@var{path}が存在して、現在の実効ユーザがそれぞれ読み取り/書き込み/実行可能なら@code{#t}を
返します。
このAPIはSTkから取られました。
@c COMMON
@end defun

@defun file-is-symlink? path
@c MOD file.util
@c EN
Returns @code{#t} if @var{path} exists and a symbolic link.
See also @code{file-is-regular?} and @code{file-is-directory?} in
@ref{File stats}.
@c JP
@var{path}が存在して、それがシンボリックリンクなら@code{#t}を返します。
(参照：@ref{File stats}の@code{file-is-regular?}, @code{file-is-directory?}).
@c COMMON
@end defun

@defun file-eq? path1 path2
@defunx file-eqv? path1 path2
@defunx file-equal? path1 path2
@c MOD file.util
@c EN
Compares two files specified by @var{path1} and @var{path2}.
@code{file-eq?} and @code{file-eqv?} checks if @var{path1} and @var{path2}
refers to the identical file, that is, whether they are on the same
device and have the identical inode number.  The only difference is
when the last component of @var{path1} and/or @var{path2} is a symbolic
link, @code{file-eq?} doesn't resolve the link (so compares the links
themselves) while @var{file-eqv?} resolves the link and compares the
files referred by the link(s).
@c JP
@var{path1}と@var{path2}で示されるファイルを比較します。
@code{file-eq?}と@code{file-eqv?}は@var{path1}と@var{path2}が
全く同一のファイルを参照しているかどうか、すなわち、同じデバイス上にあり同じ
inode番号を持つかどうかをチェックします。二つの手続きの違いは、
@code{path1}や@var{path2}の最後のコンポーネントがシンボリックリンクで
あった場合に、@var{file-eq?}はリンクそのものの比較をするが
@code{file-eqv?}はリンクを辿った先のファイルの比較をする、という点です。
@c COMMON

@c EN
@code{file-equal?} compares @var{path1} and @var{path2} considering their
content, that is, when two are not the identical file in the sense of
@code{file-eqv?}, @code{file-equal?} compares their content and returns
@code{#t} if all the bytes match.
@c JP
@code{file-equal?}は@var{path1}と@var{path2}をその内容まで考慮して比較します。
すなわち、二つのファイルが@code{file-eqv?}の意味で同一でなかった場合、
@code{file-equal?}はファイルの内容を比較し、全てが一致した場合に@code{#t}を返します。
@c COMMON

@c EN
The behavior of @code{file-equal?} is undefined
when @var{path1} and @var{path2} are both directories.
Later, it may be extended to scan the directory contents.
@c JP
@var{path1}と@var{path2}ともにディレクトリが与えられた場合の
@code{file-equal?}の動作は未定義です。将来、ディレクトリ内容を
スキャンするような拡張が加えられるかもしれません。
@c COMMON
@end defun

@deffn {Generic Function} file-mtime=? f1 f2
@deffnx {Generic Function} file-mtime<? f1 f2
@deffnx {Generic Function} file-mtime<=? f1 f2
@deffnx {Generic Function} file-mtime>? f1 f2
@deffnx {Generic Function} file-mtime>=? f1 f2
@c MOD file.util
@c EN
Compares file modification time stamps.  There are a bunch of methods defined,
so each argument can be either one of the followings.

@itemize @bullet
@item
String pathname.   The mtime of the specified path is used.
@item
@code{<sys-stat>} object (@pxref{File stats}).
The mtime is taken from the stat structure.
@item
@code{<time>} object.  The time is used as the mtime.
@item
Number.  It is considered as the number of seconds since Unix Epoch, and
used as mtime.
@end itemize
@c JP
二つのファイルの変更時間を比較します。それぞれの引数に対して、
次のような型のオブジェクトが渡せるようなメソッドが定義されています。

@itemize @bullet
@item
文字列のパス名。そのパス名で示されるファイルから変更時間が取られます。
@item
@code{<sys-stat>}オブジェクト (@pxref{File stats})。
stat構造体から変更時間が取られます。
@item
@code{<time>}オブジェクト。その示す時間が変更時間と考えられます。
@item
数値。変更時間をUnix Epochからの秒数で表したものと見なされます。
@end itemize
@c COMMON

@example
@c EN
;; @r{compare "foo.c" is newer than "foo.o"}
@c JP
;; @r{"foo.c" より "foo.o" が新しいかどうか調べる}
@c COMMON
(file-mtime>? "foo.c" "foo.o")

@c EN
;; @r{see if "foo.log" is updated within last 24 hours}
@c JP
;; @r{"foo.log"が過去24時間以内に更新されたかどうかを調べる}
@c COMMON
(file-mtime>? "foo.c" (- (sys-time) 86400))
@end example
@end deffn

@deffn {Generic Function} file-ctime=? f1 f2
@deffnx {Generic Function} file-atime=? f1 f2
@findex file-ctime<?
@findex file-ctime<=?
@findex file-ctime>?
@findex file-ctime>=?
@findex file-atime<?
@findex file-atime<=?
@findex file-atime>?
@findex file-atime>=?
@c MOD file.util
@c EN
Same as @code{file-mtime=?}, except these checks file's change time
and access time, respectively.
All the variants of @code{<}, @code{<=}, @code{>}, @code{>=} are also
defined.
@c JP
@code{file-mtime=?}と同じですが、ファイルの属性変更時間とアクセス時間に
関して比較します。
@code{<}, @code{<=}, @code{>}, @code{>=}を使う関数も同様に定義されています。
@c COMMON
@end deffn

@node File operations, Temporary files and directories, File attribute utilities, Filesystem utilities
@subsection File operations
@c NODE ファイル操作

@defun touch-file path :key (time #f) (type #f) (create #t)
@defunx touch-files paths :key (time #f) (type #f) (create #t)
@c MOD file.util
@c EN
Updates timestamp of @var{path}, or each path in the list @var{paths},
to the current time.  If the specified path
doesn't exist, a new file with size zero is created, unless
the keyword argument @var{create} is @code{#f}.

If the keyword argument @var{time} is given and not @code{#f}, it
must be a nonnegative real number.  It is used as the timestamp value
instead of the current time.

The keyword argument @var{type} can be @code{#f} (default), a symbol
@code{atime} or @code{mtime}.  If it is a symbol, only the access time
or modification time is updated.

Note: @code{touch-files} processes one file at a time, so the timestamp
of each file may not be exactly the same.

These procedures are built on top of the system call
@code{sys-utime} (@pxref{File stats}).
@c JP
@var{path}もしくはリスト@var{paths}中の各パスの
タイムスタンプを現在の時刻に更新します。
指定されたパスが存在しなかった場合、キーワード引数@var{create}が@code{#f}でなければ、
その名前で大きさゼロのファイルが作成されます。

キーワード引数@var{time}が与えられて@code{#f}でない場合、それは
非負の実数でなければなりません。現在の時刻のかわりにその値がタイムスタンプとして使われます。

キーワード引数@var{type}は@code{#f}(デフォルト)か、シンボル@code{atime}もしくは
@code{mtime}です。シンボルの場合は、それぞれアクセス時刻か変更時刻のみが更新されます。

註：@code{touch-files}はファイルをひとつづつ処理するので、各ファイルの
タイムスタンプが完全に同一にはならない可能性があります。

これらの手続きはシステムコール@code{sys-utime}を使って作られています
(@ref{File stats}参照)。
@c COMMON
@end defun

@defun copy-file src dst :key if-exists backup-suffix safe keep-timestamp keep-mode follow-link?
@c MOD file.util
@c EN
Copies file from @var{src} to @var{dst}.  The source file @var{src} must exist.
The behavior when the destination @var{dst} exists varies by the keyword
argument @var{if-exists};

@table @code
@item :error
(Default) Signals an error when @var{dst} exists.
@item :supersede
Replaces @var{dst} to the copy of @var{src}.
@item :backup
Keeps @var{dst} by renaming it.
@item :append
Append the @var{src}'s content to the end of @var{dst}.
@item #f
Doesn't copy and returns @code{#f} when @var{dst} exists.
@end table
@c JP
ファイル@var{src}を@var{dst}へコピーします。コピー元ファイル@var{src}は
存在していなければなりません。コピー先ファイル@var{dst}が存在していた場合の
ふるまいはキーワード引数@var{if-exists}によって以下のように指定されます。

@table @code
@item :error
(デフォルト) @var{dst}が存在していたらエラーを通知する。
@item :supersede
@var{dst}を@var{src}のコピーで置き換える。
@item :backup
@var{dst}の名前を変えてキープする。
@item :append
@var{dst}の末尾に@var{src}の内容を追加する。
@item #f
@var{dst}が存在していたらコピーをせず@code{#f}を返す。
@end table
@c COMMON

@c EN
@code{Copy-file} returns @code{#t} after completion.
@c JP
@code{copy-file}はコピーが完了したら@code{#t}を返します。
@c COMMON

@c EN
If @var{src} is a symbolic link, @code{copy-file} follows the
symlink and copies the actual content by default.  An error
is raised if @var{src} is a dangling symlink.

Giving @code{#f} to the keyword argument @var{follow-link?}
makes @code{copy-file} to copy the link itself.
It is possible that @var{src} is a dangling
symlink in this case.
@c JP
@var{src}がシンボリックリンクであった場合、@code{copy-file}は
デフォルトでリンクを辿ります。つまり、ファイルの実体がコピーされます。
@var{src}が存在しないパスを指すシンボリックリンクであった場合は
エラーが通知されます。

キーワード引数@var{follow-link?}に@code{#f}を与えることで、
@code{copy-link}にシンボリックリンクそのものをコピーさせることも
できます。この場合、@var{src}が存在しないパスを指すシンボリックリンクで
あっても構いません。
@c COMMON

@c EN
If @var{if-exists} is @code{:backup}, the keyword argument @var{backup-suffix}
specifies the suffix attached to the @var{dst} to be renamed.
The default value is @code{".orig"}.
@c JP
@var{if-exists}が@code{:backup}である場合、
@var{dst}がリネームされる名前は
@var{dst}にキーワード引数@var{backup-suffix}で指定されるサフィックスを
付けたものとなります。デフォルト値は@code{".orig"}です。
@c COMMON

@c EN
By default, @code{copy-file} starts copying to @var{dst} directly.
However, if the keyword argument @var{safe} is a true value,
it copies the file to a temporary file in the same directory of @var{dst},
then renames it to @var{dst} when copy is completed.
(When @var{safe} is true and @var{if-exists} is @code{:append},
we first copy the content of @var{dst} to a temporary file if @var{dst}
exists, appends the content of @var{src}, then renames the result to @var{dst}).
If copy is interrupted for some reason, the filesystem is "rolled back"
properly.

@c JP
デフォルトでは@code{copy-file}は直接@var{dst}にコピーを行いますが、
キーワード引数@var{safe}に真の値が与えられた場合は、@var{dst}と同じディレクトリ
内の一時ファイルにまずコピーし、それが完了した時点で@var{dst}へとリネームします。
(@var{safe}が真でかつ@var{if-exists}が@code{:append}であった場合は、
@var{dst}があればまずその内容を一時ファイルにコピーし、そこに@var{src}の内容を
追加し、最後にそれを@var{dst}へリネームします。)
コピーが何らかの理由で中断された場合、ファイルシステムはコピー前の状態へと
「ロールバック」されます。
@c COMMON

@c EN
If the keyword argument @var{keep-timestamp} is true, @code{copy-file}
sets the destination's timestamp to the same as the source's timestamp
after copying.
@c JP
キーワード引数@var{keep-timestamp}に真の値が与えられた場合は、
@code{copy-file}はコピー後にコピー先のファイルのタイムスタンプを
コピー元のタイムスタンプに合わせます。
@c COMMON

@c EN
If the keyword argument @var{keep-mode} is true, the destination file's
permission bits are set to the same as the source file's.  If it is false
(default), the destination file's permission remains the same if
the destination already exists and the @var{safe} argument is false,
otherwise it becomes @code{#o666} masked by umask settings.
@c JP
キーワード引数@var{keep-mode}に真の値が与えられた場合は、
コピー先のファイルのパーミッションビットはコピー元のそれに合わせられます。
@var{keep-mode}が偽の場合(デフォルト)は、コピー先が既に存在して
@var{safe}引数が偽の場合にコピー先のもとのパーミッションが保持され、
そうでなければ@code{#o666}がumaskセッティングによってマスクされた
値となります。
@c COMMON
@end defun

@c @defun copy-files files dstdir :key if-exists backup-suffix safe keep-timestamp keep-mode follow-link?
@c @c EN
@c Copies each file in a list @var{files} to the destination @var{dstdir}, which
@c must be an existing directory.  The keyword arguments are passed
@c to @code{copy-file}.
@c @c JP
@c リスト@var{files}中の各ファイルをディレクトリに@var{dstdir}にコピーします。
@c @var{dstdir}は既に存在しなければなりません。
@c キーワード引数はそのまま@code{copy-file}に渡されます。
@c @c COMMON
@c @end defun

@defun move-file src dst :key if-exists backup-suffix
@c MOD file.util
@c EN
Moves file @var{src} to @var{dst}.   The source @var{src} must exist.
The behavior when @var{dst} exists varies by the keyword argument
@var{if-exists}, as follows.
@table @code
@item :error
(Default) Signals an error when @var{dst} exists.
@item :supersede
Replaces @var{dst} by @code{src}.
@item :backup
Keeps @var{dst} by renaming it.
@item #f
Doesn't move and returns @code{#f} when @var{dst} exists.
@end table
@c JP
ファイル@var{src}を@var{dst}へ移動します。移動元ファイル@var{src}は
存在していなければなりません。移動先ファイル@var{dst}が存在した場合の
ふるまいはキーワード引数@var{if-exists}によって以下のように指定されます。
@table @code
@item :error
(デフォルト) @var{dst}が存在していたらエラーを通知する。
@item :supersede
@var{dst}を@code{src}で置き換える。
@item :backup
@var{dst}の名前を変えてキープする。
@item #f
@var{dst}が存在していたら移動をせず@code{#f}を返す。
@end table
@c COMMON

@c EN
@code{Move-file} returns @code{#t} after completion.
@c JP
@code{move-file}は移動が完了したら@code{#t}を返します。
@c COMMON

@c EN
If @var{if-exists} is @code{:backup}, the keyword argument @var{backup-suffix}
specifies the suffix attached to the @var{dst} to be renamed.
The default value is @code{".orig"}.
@c JP
@var{if-exists}が@code{:backup}である場合、@var{dst}がリネームされる
名前は@var{dst}にキーワード引数@var{backup-suffix}で指定されるサフィックスを
付けたものとなります。デフォルト値は@code{".orig"}です。
@c COMMON

@c EN
The file @var{src} and @var{dst} can be on the different filesystem.
In such a case, @code{move-file} first copies @var{src} to the
temporary file on the same directory as @var{dst}, then renames
it to @var{dst}, then removes @var{src}.
@c JP
ファイル@var{src}と@var{dst}は別のファイルシステム上にあっても構いません。
その場合、@code{move-file}はまず@var{src}を@var{dst}と同じディレクトリの
一時ファイルにコピーし、それを@var{dst}にリネームし、それから
@var{src}を消去します。
@c COMMON
@end defun

@c @defun move-files files dstdir :key if-exists backup-suffix
@c @c EN
@c Moves each file in a list @var{files} to @var{dstdir},
@c which must be an existing directory.  Keyword arguments
@c are passed to @code{move-file}.
@c @c JP
@c リスト@var{files}中の各ファイルをディレクトリ@var{dstdir}に移動します。
@c @var{dstdir}は既に存在しなければなりません。
@c キーワード引数はそのまま@code{move-file}に渡されます。
@c @c COMMON
@c @end defun

@defun remove-file filename
@defunx delete-file filename
[R7RS file]
@c MOD file.util
@c EN
Removes the named file.  An error is signalled if @var{filename}
does not exist, is a directory, or cannot be deleted with other
reasons such as permissions.
R7RS defines @code{delete-file}.

Compare with @code{sys-unlink} (@pxref{Directory manipulation}),
which doesn't raise an error when the named file doesn't exist.
@c JP
指定された名前のファイルを消去します。ファイルが存在しなかったり、ディレクトリであったり、
パーミッションがなく消去できなかった場合等にはエラーが報告されます。
@code{delete-file}はR7RSで定義されています。

@code{sys-unlink}と似ていますが、@code{sys-unlink}はファイルが無かった場合に
エラーをあげず@code{#f}を返すことに注意。(@ref{Directory manipulation}参照。)
@c COMMON
@end defun

@defun remove-files paths
@defunx delete-files paths
@c MOD file.util
@c EN
Removes each path in a list @var{paths}.  If the path is
a file, it is @code{unlink}ed.  If it is a directory,
its contents are recursively removed by @code{remove-directory*}.
If the path doesn't exist, it is simply ignored.

@code{delete-files} is just an alias of @code{remove-files}.
@c JP
リスト@var{paths}中の各パスを削除します。パスがファイルの場合は
@code{unlink}し、ディレクトリの場合は@code{remove-directory*}を
使って再帰的にその内容を消去します。存在しないパスは単に無視されます。

@code{delete-files}は@code{remove-files}の別名です。
@c COMMON
@end defun


@defun file->string filename options @dots{}
@defunx file->list reader filename options @dots{}
@defunx file->string-list filename options @dots{}
@defunx file->sexp-list filename options @dots{}
@c MOD file.util
@c EN
Convenience procedures to read from a file @var{filename}.
They first open the named file, then call @code{port->string},
@code{port->list}, @code{port->string-list} and @code{port->sexp-list}
on the opened file, respectively.  (@pxref{Input utility functions}).
The file is closed if all the content is read or an error is
signaled during reading.
@c JP
ファイル @var{filename} から読み込むための便利手続き。
これらの手続きは、まず、指定された名前のファイルをオープンし、その
オープンしたファイルに対してそれぞれ @code{port->string}、
@code{port->list}、@code{port->string-list} および @code{port->sexp-list}
を呼びます(@ref{Input utility functions}参照)。すべての内容が読み込まれる
かまたは読み込み中にエラーシグナルがあがれば、ファイルはクローズされます。
@c COMMON

@c EN
Those procedures take the same keyword arguments as
@code{call-with-input-file}.
When the named file doesn't exist, the behavior depends on
@var{:if-does-not-exist} keyword argument---an error is signaled
if it is @code{:error}, and @code{#f} is returned if the argument is
@code{#f}.
@c JP
これらの手続きは@code{call-with-input-file}と同じキーワード引数を取ります。
ファイルが見つからなかった場合の振舞いは
キーワード引数@code{:if-does-not-exist}によって指定できます。
それが@code{:error}ならエラーが報告され、
@code{#f}なら@code{#f}が返されます。
@c COMMON
@end defun

@defun string->file filename string options @dots{}
@defunx list->file writer filename lis options @dots{}
@defunx string-list->file filename lis options @dots{}
@defunx sexp-list->file filenme lis options @dots{}
@c MOD file.util
@c EN
Opposite of @code{file->string} etc.  They are convenient
to quickly write out things into a file.

NB: The name @code{string->file} etc. might suggest they would take the
object to be written as the first argument.  We decided to put @var{filename}
first, since in the situations where these procedures are used,
it is more likely that one want to write literal data, which would be
bigger than the filename itself.

The options part is passed to @code{call-with-output-file} as is.
For example, the following code appends the text when @file{foo.txt}
already exists:
@c JP
@code{file->string}等の逆を行う手続きです。
手軽にファイルに何かを書き出したい時に便利です。

註: @code{string->file}等の名前からして、
書き出されるオブジェクトを第一引数にする方が慣習にあっているかもしれません。
けれども、実際にこれらの手続きが使われる場面では、書き出されるオブジェクトとして
リテラルデータが来る場合も多く、だとするとより短いファイル名を先にした方が
読み書きしやすいだろうと考え、@var{filename}を先に持ってきてあります。

@var{options} @dots{}部分はそのまま@code{call-with-output-file}に
渡されます。次の例は@file{foo.txt}が存在していればそれにデータを書き足します。
@c COMMON

@example
(string->file "foo.txt" "New text to append\n"
              :if-exists :append)
@end example

@c EN
The @code{list->file} takes @var{writer} argument, which is a procedure
that receives two arguments, an element from the list @var{lis}, and an
output port.  It should write out the element to the port in a suitable
way.  The @code{string-list->file} and @code{sexp-list->file} are
specialized versions of @code{list->file}, where @code{string-list->file}
uses @code{(^[s p] (display s p) (newline p))} as @var{writer},
and @code{sexp-list->file} uses 
@code{(^[s p] (write s p) (newline p))} as @var{writer}.
@c JP
@code{list->file}が取る@var{writer}引数は、リスト@var{lis}からのひとつの要素と
出力ポートの二つの引数を取る手続きで、適切な形式で要素をポートに書き出します。
@code{string-list->file}と@code{sexp-list->file}は
@code{list->file}の特化したバージョンで、
@code{string-list->file}はwriterとして@code{(^[s p] (display s p) (newline p))}を、
@code{sexp-list->file}はwriterとして@code{(^[s p] (write s p) (newline p))}を
使います。
@c COMMON
@end defun


@node Temporary files and directories, Lock files, File operations, Filesystem utilities
@subsection Temporary files and directories
@c NODE 一時ファイルとディレクトリ

@deffn {Parameter} temporary-directory
@c MOD file.util
@c EN
A parameter that keeps the name of the directory that can be used
to create a temporary files.   The default value is
the one returned from @code{sys-tmpdir} (@pxref{Pathnames}).
The difference of @code{sys-tmpdir} is that, since this is a parameter,
it can be overridden by application during execution.
Libraries are recommended to use this instead of @code{sys-tmpdir}
for greater flexibility.
@c JP
一時ファイルを作るのに適したディレクトリ名を保持しているパラメータです。
デフォルトの値は@code{sys-tmpdir}の戻り値です (@ref{Pathnames}参照)。
@code{sys-tmpdir}との違いは、これはパラメータなので
アプリケーションが実行時に変更できることです。
ライブラリは柔軟性を高めるためにできるだけ@code{sys-tmpdir}よりは
こちらを利用するのが良いでしょう。
@c COMMON
@end deffn

@defun call-with-temporary-file proc :key directory prefix
@c MOD file.util
@c EN
Creates a temporary file with a unique name and opens it for output,
then calls @var{proc} with the output port and the temporary file's name.
The temporary file is removed after either @var{proc} returns
or raises an uncaught error.
Returns the value(s) @var{proc} returns.

The temporary file is created in the directory @var{directory},
with the name @var{prefix} followed by several random alphanumeric characters.
When omitted, the value of @code{(temporary-directory)} is used
for @var{directory}, and @code{"gtemp"} for @var{prefix}.

The name passed to @var{proc} consists of @var{directory} and
the file's name.  So whether the name is absolute or relative pathname
depends on the value of @var{directory}.

@example
(call-with-temporary-file (^[_ name] name)
 @result{} @r{Something like "/tmp/gtemp4dSpMh"}
@end example

You can keep the output file by renaming it in @var{proc}.  But if doing so,
make sure to specify @var{directory} so that the temporary file
is created in the same directory as the final output; rename
may not work across filesystems.

Internally, it calls @code{sys-mkstemp} to create a unique file.
@xref{Directory manipulation}, for the details.
@c JP
一意な名前を持つ一時ファイルを作成し、出力用にオープンして、
その出力ポートと名前を引数として@var{proc}を呼びます。
一時ファイルは、@var{proc}から戻った場合でも、@var{proc}がエラーを投げた場合でも、
消去されます。
@var{proc}の返す値(複数可)が@code{call-with-temporary-file}の戻り値となります。

一時ファイルはディレクトリ@var{directory}以下に作られ、
その名前は@var{prefix}の後にいくつかの英数字を付け加えたものになります。
省略された場合、@code{(temporary-directory)}の値が@var{directory}に、
@code{"gtemp"}が@var{prefix}に使われます。

@var{proc}に渡される名前は@var{directory}とファイル名をつなげたパス名です。
絶対パスになるか相対パスになるかは@var{directory}の値によります。

@example
(call-with-temporary-file (^[_ name] name)
 @result{} @r{例えば "/tmp/gtemp4dSpMh"}
@end example

出力したファイルを取っておきたい場合は、@var{proc}の中でリネームしてください。
その場合、最終的なファイルと同じディレクトリに一時ファイルを作るように、
@var{directory}引数を指定するのを忘れないように。
ファイルシステムをまたぐリネームはうまくいかない場合があります。

内部的に、この手続きは@code{sys-mkstemp}を呼んで一意なファイルを作っています。
@code{sys-mkstemp}については@ref{Directory manipulation}参照。
@c COMMON
@end defun

@defun call-with-temporary-directory proc :key directory prefix
@c MOD file.util
@c EN
Creates a temporary directory with unique name,
then calls @var{proc} with the name.
The temporary directory and its contents are removed
after either @var{proc} returns
or raises an uncaught error.
Returns the value(s) @var{proc} returns.

The temporary directory is created in the directory @var{directory},
with the name @var{prefix} followed by several random alphanumeric characters.
When omitted, the value of @code{(temporary-directory)} is used
for @var{directory}, and @code{"gtemp"} for @var{prefix}.

The name passed to @var{proc} consists of @var{directory} and
the directory name.  So whether the name is absolute or relative pathname
depends on the value of @var{directory}.

Internally, it calls @code{sys-mkdtemp} to create a unique file.
@xref{Directory manipulation}, for the details.
@c JP
一意な名前を持つ一時ディレクトリを作成し、
その名前を引数として@var{proc}を呼びます。
一時ディレクトリは、@var{proc}から戻った場合でも、@var{proc}がエラーを投げた場合でも、
消去されます。
@var{proc}の返す値(複数可)が@code{call-with-temporary-directory}の戻り値となります。

一時ディレクトリはディレクトリ@var{directory}以下に作られ、
その名前は@var{prefix}の後にいくつかの英数字を付け加えたものになります。
省略された場合、@code{(temporary-directory)}の値が@var{directory}に、
@code{"gtemp"}が@var{prefix}に使われます。

@var{proc}に渡される名前は@var{directory}とファイル名をつなげたパス名です。
絶対パスになるか相対パスになるかは@var{directory}の値によります。

内部的に、この手続きは@code{sys-mkdtemp}を呼んで一意なディレクトリを作っています。
@code{sys-mkstemp}については@ref{Directory manipulation}参照。
@c COMMON
@end defun

@node Lock files,  , Temporary files and directories, Filesystem utilities
@subsection Lock files
@c NODE ロックファイル

@c EN
Exclusivity of creating files or directories is often used
for inter-process locking.   The following procedure provides
a packaged interface for it.
@c JP
ファイルやディレクトリを作成する排他性は、しばしばプロセス間のロックに
使われます。以下の手続きはパッケージ化されたインタフェースを提供します。
@c COMMON

@defun with-lock-file lock-name thunk :key type retry-interval @
                      retry-limit secondary-lock-name retry2-interval @
                      retry2-limit perms abandon-timeout
@c MOD file.util
@c EN
Exclusively creates a file or a directory (@emph{lock file})
with @var{lock-name}, then executes @var{thunk}.
After @var{thunk} returns, or an error is thrown in it,
the lock file is removed.  When @var{thunk} returns normally,
its return values become the return values of @code{with-lock-file}.
@c JP
@var{lock-name}という名前を持つファイルもしくはディレクトリ (ここでは
@emph{ロックファイル}と呼びます) を排他的に作成し、
@var{thunk}を実行します。@var{thunk}から戻ってくるか、エラーが投げられたら、
ロックファイルは削除されます。@var{thunk}が正常に戻ってきた場合、
その戻り値が@code{with-lock-file}の戻り値となります。
@c COMMON

@c EN
If the lock file already exists, @code{with-lock-file} waits and retries
getting the lock until timeout reaches.  It can be configured by
the keyword arguments.
@c JP
ロックファイルが既に存在していた場合、@code{with-lock-file}はタイムアウトになるまで
少し待ってリトライすることを続けます。細かい動作はキーワード引数で指定できます。
@c COMMON

@c EN
There's a chance that @code{with-lock-file} leaves the lock file
when it gets a serious error situation and doesn't have the opportunity
to clean up.  You can allow @code{with-lock-file} to @emph{steal}
the lock if its timestamp is too old; say, if you know that the
applications usually locks just for seconds, and you find the lock
file is 10 minutes old, then it's likely that the previous
process was terminated abruptly and couldn't clean it up.
You can also configure this behavior by the keyword arguments.
@c JP
@code{with-lock-file}実行中に深刻なエラーによって、ロックファイルを消せずに
プロセスが終了してしまう可能性があります。そのため、
@code{with-lock-file}は、ロックファイルのタイムスタンプが非常に古い場合には
ロックを@emph{盗む}ことを許しています。例えば、通常アプリケーションはたかだか数秒しか
ロックしないはずなのに、10分前のタイムスタンプを持つロックファイルを見つけたとしたら、
以前のプロセスがクリーンアップをせずに落ちてしまったことは十分考えられるでしょう。
この振る舞いも、キーワード引数で制御することができます。
@c COMMON

@c EN
Internally, @emph{two} lock files are used to implement this
stealing behavior safely.  The creation and removal of the primary
lock file (named by @var{lock-name} argument) are guarded by
the secondary lock file (named by @var{secondary-lock-file} argument,
defaulted by @code{.2} suffix attached to @var{lock-name}).
The secondary lock prevents more than one process steals
the same primary lock file simultaneously.
@c JP
内部的には、安全な「盗ロック」を実現するために、二つのロックファイルが使われています。
主ロックファイル(@var{lock-name}で指定される名前を持つもの)の作成と削除の
操作がそれぞれ、副ロックファイル(@var{secondary-lock-file}で指定される名前を
持つもの。指定が省略された場合は@var{lock-name}にサフィックス@code{.2}をつけたもの)
によって保護されます。
副ロックは、二つ以上のプロセスが主ロックファイルを同時に盗もうとした場合を保護します。
@c COMMON

@c EN
The secondary lock is acquired for a very short period so there's
much less chance to be left behind by abnormal terminations.
If it happens, however, we just give up; we don't steal the
secondary lock.
@c JP
副ロックファイルによるロックはほぼ常に極めて短い期間に
限定されるため、事故により副ロックファイルが残されてしまう可能性は
主ロックファイルに比べ非常に小さいです。それでももし副ロックファイルが
残されてしまった場合は、@code{with-lock-file}は単に諦めます。副ロックファイルまで
盗むことはしません。
@c COMMON

@c EN
If @code{with-lock-file} couldn't get a lock before timeout,
a @code{<lock-file-failure>} condition is thrown.
@c JP
@code{with-lock-file}がタイムアウトまでにロックを獲得できなけば、
@code{<lock-file-failure>}コンディションが投げられます。
@c COMMON

@c EN
Here's a list of keyword arguments.
@c JP
以下のキーワード引数が認識されます。
@c COMMON

@table @var
@item type

@c EN
It can be either one of the symbols @code{file} or @code{directory}.
@c JP
シンボル@code{file}か@code{directory}のどちらか。
@c COMMON

@c EN
If it is @code{file}, we use a lock file, relying on the @code{O_EXCL}
exclusive creation flag of @code{open(2)}.
This is the default value.
It works for most platforms;
however, some NFS implementation may not implement the exclusive
semantics properly.   
@c JP
@code{file}を指定した場合、@code{open(2)}の@code{O_EXCL}フラグを使う
排他的ファイル作成を利用したロックファイルを使います。これがデフォルトの動作です。
ほとんどのプラッフォームで動作しますが、NFSの実装の一部に、
排他的ファイル作成のセマンティクスが正しく実装されていない場合があります。
@c COMMON

@c EN
If it is @code{directory}, we use a lock directory, relying on the
atomicity of @code{mkdir(2)}.  It should work for any platforms,
but it may be slower than @code{file}.
@c JP
@code{directory}を指定した場合は、@code{mkdir(2)}の排他性を利用した
ロックディレクトリを使います。これはどんなプラットフォームでも動作する
はずですが、@code{file}を指定した場合より遅いかもしれません。
@c COMMON

@item retry-interval
@itemx retry-limit

@c EN
Accepts a nonnegative real number that specifies either
the interval to attempt to acquire the primary lock, or the maximum
time we should keep retrying, respectively, in seconds.
The default value is 1 second interval and 10 second limit.
To prevent retrying, give 0 to @var{retry-limit}.
@c JP
時間を秒で指定する非負の実数を取ります。前者は主ロック獲得を再試行する
時間間隔、後者は再試行を繰り返す総時間を指定します。
デフォルトはそれぞれ、1秒と10秒です。再試行をしないようにするには、
@var{retry-limit}に0を渡してください。
@c COMMON

@item secondary-lock-name

@c EN
The name of the secondary lock file (or directory).  If omitted,
@var{lock-name} with a suffix @code{.2} attached is used.
Note: The secondary lock name must be agreed on all programs that
locks the same (primary) lock file.  I recommend to leave this
to the default unless there's a good reason to do otherwise.
@c JP
副ロックファイル(もしくはディレクトリ)の名前を指定します。
省略された場合は、@var{lock-name}にサフィックス@code{.2}をつけたものが使われます。
副ロックファイルの名前は、同じ(主)ロックファイルを使うプログラム全てで
一致していなければなりません。
特に変える必要が無ければデフォルトのままにするのが良いでしょう。
@c COMMON

@item retry2-interval
@itemx retry2-limit

@c EN
Like @var{retry-interval} and @var{retry-limit}, but these specify
interval and timeout for the secondary lock file.  The possibility
of secondary lock file collision is usually pretty low, so
you would hardly need to tweak these.  The default values are
1 second interval and 10 second limit.
@c JP
@var{retry-interval}と@var{retry-limit}に似ていますが、
こちらは副ロックファイルの再試行間隔と最長再試行時間を指定します。
副ロックが衝突する確率は通常極めて低いので、これらのパラメータを
調整する必要は滅多に無いでしょう。デフォルトの値はそれぞれ
1秒と10秒です。
@c COMMON

@item perms

@c EN
Specify the permission bitmask of the lock file or directory,
in a nonnegative exact integer.  The default is @code{#o644} for
a lock file and @code{#o755} for a lock directory.

Note that to control who can acquire/release/steal the lock,
what matters is
the permission of the directory in which the lock file/directory,
not the permission of the lock file/directory itself.
@c JP
ロックファイルもしくはディレクトリのパーミッションを、非負正確整数の
ビットマスクで指定します。デフォルトは、ロックファイルに対して@code{#o644}、
ロックディレクトリに対しては@code{#o755}です。

ロックを獲得/解放したり盗んだりするには、ロックファイル自身のパーミッションではなく、
ロックファイルが置かれるディレクトリのパーミッションが関係することに注意してください。
@c COMMON

@item abandon-timeout

@c EN
Specifies the period in seconds in a nonnegative real number.
If the primary lock file is
older than that, @code{with-lock-file} steals the lock.
To prevent stealing, give @code{#f} to this argument.
The default value is 600 seconds.
@c JP
時間の長さ(秒)を非負の実数で指定します。
@code{with-lock-file}がロックファイルを見つけて、そのタイムスタンプが
現在の時刻マイナスこの時間よりも古いものだった場合、ロックを盗みます。
ロックを盗むことを禁止したければこの引数に@code{#f}を渡してください。
デフォルトは600秒です。
@c COMMON

@end table

@end defun

@deftp {Condition type} <lock-file-failure>
@c MOD file.util
@c EN
A condition indicating that @code{with-lock-file} couldn't
obtain the lock.  Inherits @code{<error>}.
@c JP
@code{with-lock-file}がロックを獲得できなかった場合に投げられる
コンディションです。@code{<error>}を継承します。
@c COMMON

@defivar <lock-file-failure> lock-file-name
@c EN
The primary lock file name.
@c JP
獲得しようとした主ロックファイルの名前です。
@c COMMON
@end defivar
@end deftp

@c EN
Gauche also provides OS-supported file locking feature,
@code{fcntl} lock, via @code{gauche.fcntl} module.
Whether you want to use @code{fcntl} lock or @code{with-lock-file}
will depend on your application.
@c JP
Gaucheは、OSによりサポートされる@code{fcntl}ロックの機能も、
@code{gauche.fcntl}モジュールによって提供しています。
@code{fcntl}ロックを使うべきか@code{with-lock-file}を使うべきかは、
アプリケーションによります。
@c COMMON

@c EN
These are the advantages of the @code{fcntl} lock:
@c JP
@code{fcntl}ロックの利点は次の通りです。
@c COMMON

@itemize
@item
@c EN
The lock is removed when the process dies without explicitly unlocking it.
@c JP
プロセスが死んだ時に、ロックは自動的に解除される
@c COMMON
@item
@c EN
You can directly lock the file you're touching.
@c JP
作業するファイルそのものをロックできる。
@c COMMON
@item
@c EN
You can lock a part of a file.
@c JP
ファイルの一部だけをロックできる。
@c COMMON
@item
@c EN
You can have shared (read) and exclusive (write) locks.
@c JP
共有(読み出し)ロックと排他(書き込み)ロックが使える。
@c COMMON
@end itemize

@c EN
In common situations, probably the most handy property is the
first one; you don't need to worry about leaving lock behind
unexpected process termination.
@c JP
多くの場合、最も便利なのは最初の性質でしょう。プロセスが予想外に落ちてしまった
場合でも、ロックが残されてしまうことを心配しないで済みます。
@c COMMON

@c EN
However, there are a couple of shortcomings in @code{fcntl} locks.
@c JP
けれども、@code{fcntl}ロックには欠点もあります。
@c COMMON

@itemize
@item
@c EN
It is not guaranteed to work across different platforms,
and/or NFS-mounted filesystems.
@c JP
異なるプラットフォームや、NFSマウントされたファイルシステム間で
確実に動作する保証がない。
@c COMMON
@item
@c EN
The lock is per-process, per-file, and non-recursive.
If you have a lock in a file,
then calls a library that also locks the file, the lock always
succeeds.  Worse, if the library unlocks the file,
the lock is completely removed, while the caller doesn't know
about it.  It also means that, in order to prevent multiple threads
in a process from accessing the same file, you have to use
mutex along the fcntl lock.
@c JP
ロックはプロセス単位、ファイル単位でかつ非再帰的である。
例えば、既にプロセスがロックしているファイルに対して、呼び出したライブラリ内でまたロックを
獲得しようとすると、それは常に成功する。さらに悪いことに、そのライブラリが
ロックを解放した時点で、元からロックがかかっていたかどうかに関わらず、プロセス全体が
ロックを手放してしまう。このことはまた、複数のスレッド間で排他的にファイルに
アクセスしたい場合は、fcntlロックと一緒にmutexも使う必要があるということでもある。
@c COMMON
@end itemize

@c EN
Especially because of the second point, it is very difficult
to use @code{fcntl} lock unless you have total control over and knowledge
of the entire application.
It is ok to use the @code{fcntl} lock by the application code to lock
the application-specific file.
Library developers have difficulty, however, to make sure any potential
user of the library won't try to lock the same file as the library tries
to lock (usually it's impossible).
@c JP
二番目の欠点のせいで、アプリケーション全体を知っていてコードを好きにできる場合でなければ、
@code{fcntl}ロックを安全に使うことが非常に難しくなっています。
アプリケーションコードが、そのアプリケーションで使うためだけのファイルをロックするのに
@code{fcntl}ロックを使うのは何も問題ありません。
しかしライブラリ開発者は、ライブラリ内で@code{fcntl}ロックを使うなら、
そのライブラリのユーザや他のライブラリが将来に渡って同じファイルを決してロックしない
ということを保証しなければなりません(通常、そんなことは不可能です)。
@c COMMON

@c ----------------------------------------------------------------------
@node Mathematic constants, Mersenne-Twister random number generator, Filesystem utilities, Library modules - Utilities
@section @code{math.const} - Mathematic constants
@c NODE 定数, @code{math.const} - 定数

@deftp {Module} math.const
@mdindex math.const
@c EN
This module defines several commonly-used mathematic constants.
@c JP
いくつかの一般的に用いられる数学定数を定義しています。
@c COMMON
@end deftp

@defvr {Constant} pi
@defvrx {Constant} pi/2
@defvrx {Constant} pi/4
@defvrx {Constant} pi/180
@defvrx {Constant} 1/pi
@defvrx {Constant} 180/pi
@c MOD math.const
@c EN
Bound to pi, pi/2, pi/4, pi/180, 1/pi and 180/pi, respectively.
@c JP
それぞれ、π、π/2、π/4、π/180、1/π、180/πです。
@c COMMON
@end defvr

@defvr {Constant} e
@c MOD math.const
Napier's constant.
@end defvr

@c ----------------------------------------------------------------------
@node Mersenne-Twister random number generator, Prime numbers, Mathematic constants, Library modules - Utilities
@section @code{math.mt-random} - Mersenne Twister Random number generator
@c NODE Mersenne Twister乱数発生器, @code{math.mt-random} - Mersenne Twister乱数発生器

@deftp {Module} math.mt-random
@mdindex math.mt-random
@c EN
Provides a pseudo random number generator (RNG) based on
"Mersenne Twister" algorithm developed by Makoto Matsumoto and
Takuji Nishimura.   It is fast, and has huge period of 2^19937-1.
See @url{https://dl.acm.org/citation.cfm?id=272995}, for details about the algorithm.
@c JP
Makoto MatsumotoとTakuji Nishimuraにより開発された、
``Mersenne Twister''アルゴリズムに基づく、
仮想的な乱数発生器(RNG)を提供します。
高速で、2^19937-1という極めて長大な周期を持ちます。
アルゴリズムの詳細については、@url{https://dl.acm.org/citation.cfm?id=272995}を参照して下さい。
@c COMMON

@c EN
For typical use cases of random number generators,
we recommend to use @code{srfi-27} which is implemented
on top of this module and provides portable API.
You should use this module directly only when you need
functions that aren't available through @code{srfi-27}.
@c JP
乱数発生器の通常の用途には、@code{srfi-27}を使うことをお勧めします。
@code{srfi-27}はこのモジュールの上に実装されていますが、ポータブルなAPIを提供しています。
@code{srfi-27}にない機能が必要な時のみこのモジュールを直接使うようにしてください。
@c COMMON
@end deftp

@deftp {Class} <mersenne-twister>
@clindex mersenne-twister
@c MOD math.mt-random
@c EN
A class to encapsulate the state of Mersenne Twister RNG.
Each instance of this class has its own state, and can be used
as an independent source of random bits if initialized
by individual seed.

The random seed value can be given at the instantiation time
by @code{:seed} initialization argument, or by using
@code{mt-random-set-seed!} described below.
@c JP
Mersenne Twister RNGの状態をカプセル化するクラスです。
このクラスのそれぞれのインスタンスは独自の状態を持ち、
個別のシードで初期化されていれば、それぞれがランダムビットの
独立したソースになり得ます。

ランダムシードの値は初期化引数@code{:seed}により初期化時に与えるか、
以下で説明する@code{mt-random-set-seed!}を使います。
@c COMMON

@example
(define m (make <mersenne-twister> :seed (sys-time)))

(mt-random-real m) @result{} 0.10284287848537865
(mt-random-real m) @result{} 0.463227748348805
(mt-random-real m) @result{} 0.8628500643709712
@dots{}
@end example
@end deftp

@defun mt-random-set-seed! mt seed
@c MOD math.mt-random
@c EN
Sets random seed value @var{seed} to the Mersenne Twister RNG (MTRNG) @var{mt}.
@var{Seed} can be an arbitrary positive exact integer,
or arbitrary length of u32vector (@pxref{Homogeneous vectors}).
If it is a u32vector, up to 624 elements are used for initialization.
@c JP
メルセンヌツイスターRNG @var{mt}にランダムシードの値@var{seed}をセットします。
@var{seed}は任意の正の正確整数か、任意長のu32vector
(@ref{Homogeneous vectors}参照)が使えます。
u32vectorの場合は、初期化のために624個までの要素が使われます。
@c COMMON

@c EN
Internally, MTRNG keeps its state in array of 32-bit integers.  When a fixnum
is given, its lower 32bit is used to generate a linear congruential series
to fill the state space.  If you do so, there is an algorithm
that only samples a couple of result from MTRNG to calculate the original
seed value, hence can predict entire sequence.  If you want the random
sequence harder to predict, prepare your own u32vector seed filled with
high-entroby bits. 

Note that Mersenne Twister is never intended for cryptograhpy, you shouldn't
use it for security-sensitive purposes.
@c JP
MTRNGは32ビット整数配列を内部状態として持っています。fixnumが@var{seed}として
与えられた場合、その下位32bitを初期値とする線形合同法で得られる数列で内部状態が初期化されます。
そういた場合、MTRNGの二つの出力だけからシード値を逆算するアルゴリズムがあり、
全ての乱数列の値が予測できてしまいます。
もし乱数列をもっと予測しづらくしたいなら、u32vectorをエントロピーの高いビットで満たして
それをシードとして使ってください。

メルセンヌツイスターは暗号学的に安全であることを意図して作られてはいません。
セキュリティが重要な用途には使わないでください。
@c COMMON

@c EN
NB: Up to 0.9.9, when @var{seed} is a bignum, we roll our own way to
fold it in 32bit integer and then called Mersenne-Twister's initialization
function.  It loses the entropy, so we changed it and now all the bits
in the bignum is used for the seed.
@c JP
註: 0.9.9までは、@var{seed}にbignumが渡された場合、そこから独自のアルゴリズムで
32bitの値を生成してメルセンヌツイスタの初期化関数を呼んでいました。
しかしそれだとエントロピーを捨てることになるので、現在は
全てのビットがシード値に使われるように変更されています。
@c COMMON
@end defun

@defun mt-random-get-state mt
@defunx mt-random-set-state! mt state
@c MOD math.mt-random
@c EN
Retrieves and reinstalls the state of Mersenne Twister RNG @var{mt}.
The state is represented by a u32vector of 625 elements.  The state
can be stored elsewhere, and then restored to an instance of
@code{<mersenne-twister>} to continue to generate the pseudo random
sequence.
@c JP
Mersenne Twister RNG @var{mt}を取り出して再インストールします。
状態は、625要素のu32vectorで表現されます。
状態はどこにでも保存することができ、仮想的なランダムシーケンスの
生成を続行するために、@code{<mersenne-twister>}のインスタンスとして
リストアできます。
@c COMMON
@end defun

@defun mt-random-real mt
@defunx mt-random-real0 mt
@c MOD math.mt-random
@c EN
Returns a random real number between 0.0 and 1.0.
1.0 is not included in the range.  @code{Mt-random-real} doesn't
include 0.0 either, while @code{mt-random-real0} does.
Excluding 0.0 is from the draft SRFI-27.
@c JP
0.0と1.0の間のランダムな実数を返します。
1.0は範囲に含まれません。
@code{mt-random-real}は、0.0も範囲に含みませんが、
@code{mt-random-real0}は含みます。
0.0を含まないのは、SRFI-27ドラフトに依拠しています。
@c COMMON
@end defun

@defun mt-random-integer mt range
@c MOD math.mt-random
@c EN
Returns a random exact positive integer between 0 and @var{range}-1.
@var{Range} can be any positive exact integer.
@c JP
0から@var{range}-1までの正の正確整数をランダムに返します。
@var{range}はいかなる正の正確整数でも構いません。
@c COMMON
@end defun

@defun mt-random-fill-u32vector! mt u32vector
@defunx mt-random-fill-f32vector! mt f32vector
@defunx mt-random-fill-f64vector! mt f64vector
@c MOD math.mt-random
@c EN
Fills the given uniform vector by the random numbers.
For @code{mt-random-fill-u32vector!}, the elements are filled
by exact positive integers between 0 and 2^32-1.
For @code{mt-random-fill-f32vector!} and
@code{mt-random-fill-f64vector!}, it is filled by an inexact
real number between 0.0 and 1.0, exclusive.

If you need a bunch of random numbers at once, these are much
faster than getting one by one.
@c JP
与えられたユニフォームベクタをランダムな数値で埋めます。
@code{mt-random-fill-u32vector!}では、要素は0と2^32-1の間の
正の正確整数で埋められます。
@code{mt-random-fill-f32vector!}と@code{mt-random-fill-f64vector!}
では、0.0と1.0(含まれない)の間の不正確実数で埋められます。
@c COMMON
@end defun

@c ----------------------------------------------------------------------
@node Prime numbers, Windows support, Mersenne-Twister random number generator, Library modules - Utilities
@section @code{math.prime} - Prime numbers
@c NODE 素数, @code{math.prime} - 素数

@deftp {Module} math.prime
@mdindex math.prime
@c EN
This module provides utilities related to prime numbers.
@c JP
このモジュールは、素数を扱うユーティリティ関数を提供します。
@c COMMON
@end deftp

@c EN
@subheading Sequence of prime numbers
@c JP
@subheading 素数のシーケンス
@c COMMON

@defvar *primes*
@c MOD math.prime
@c EN
An infinite lazy sequence of primes.
@c JP
素数の無限遅延シーケンスです。
@c COMMON

@example
;; show 10 prime numbers from 100-th one.
(take (drop *primes* 100) 10)
 @result{} (547 557 563 569 571 577 587 593 599 601)
@end example
@end defvar

@defun reset-primes
@c MOD math.prime
@c EN
Once you take a very large prime out of @code{*primes*}, all primes
before that has been calculated remains in memory, since the
head of sequence is held in @code{*primes*}.  Sometimes you know
you need no more prime numbers and you wish those calculated ones
to be garbage-collected.  Calling @code{reset-primes} rebinds
@code{*primes*} to unrealized lazy sequence, allowing the previously
realized primes to be GCed.
@c JP
@code{*primes*}から大きな素数を取り出すと、それ以前の素数も全てメモリに
残り続けます。@code{*primes*}変数がシーケンスの頭を抱えているからです。
もう素数を必要としないことがわかっている場合、それらのメモリがガベージコレクト
されることが望ましいかもしれません。@code{reset-primes}手続きは
@code{*primes*}をまだ現実化されていない遅延シーケンスに再束縛し、
次のGCで計算済みの素数シーケンスが回収されるようにします。
@c COMMON
@end defun

@defun primes
@c MOD math.prime
@c EN
Returns a fresh lazy sequence of primes.  It is useful when
you need certain primes in a short period of time---if you don't keep
a reference to the head of the returned sequence, it will be garbage
collected after you've done with the primes.
(Note that calculation of a prime number needs the
sequence of primes from the beginning, 
so even if your code only keep a reference
in the middle of the sequence, the entire sequence will be kept
in the thunk within the lazy sequence---you have to release all
references in order to make the sequence GCed.)

On the other hand,
each sequence returned by @code{primes} are realized individually,
duplicating calculation.  

The rule of thumb is---if you use primes repeatedly throughout
the program, just use @code{*primes*} and you'll save calculation.
If you need primes one-shot, call @code{primes} and abandon it
and you'll save space.
@c JP
新たな素数の遅延シーケンスを返します。
その時だけ素数を使いたい、という時に便利です。返されたシーケンスへの
参照が無くなれば、シーケンスはガベージコレクトされます。
(ある素数の計算には素数のシーケンスが最初から必要なので、
たとえシーケンスの頭ではなく途中への参照だけを持っていたとしても、
遅延シーケンスの中のサンクにはシーケンスの頭への参照が保持されています。
シーケンスがGCされるためには、いかなる部分への参照も残さないようにしなければなりません)。

@code{primes}が返す各シーケンスは独立しているので、素数の計算もそれぞれで
(重複して)行われることになります。

単純なルールとして、プログラム中で何度も素数を使う必要があるのなら
変数@code{*primes*}を利用するのが良いでしょう。各素数の計算は一度しか
行われず、余分な計算を省くことができます。しかしその場だけ素数が欲しいなら、
@code{primes}を呼んで、仕事が済んだらシーケンスを捨ててしまえば、
不要なシーケンスがメモリに残りつづけることを心配しなくても済みます。
@c COMMON
@end defun

@c EN
@subheading Testing primality
@c JP
@subheading 素数かどうかを調べる
@c COMMON

@defun small-prime? n
@c MOD math.prime
@c EN
For relatively small positive integers 
(below @code{*small-prime-bound*}, to be specific), this procedure
determines if the input is prime or not, quickly and deterministically.
If @var{n} is on or above the bound, this procedure returns @code{#f}.

This can be used to quickly filter out known primes; it never returns
@code{#t} on composite numbers (while it may return @code{#f} on
large prime numbers).
Miller-Rabin test below can tell if the input is composite for sure,
but it may return @code{#t} on some composite numbers.
@c JP
比較的小さな正整数 (@code{*small-prime-bound*}以下の正整数) に対して、
それが素数であるかどうかを判定し、素数なら@code{#t}を返します。
@var{n}がそれ以上である場合は常に@code{#f}を返します。

この手続きは確実に素数であるとわかるものを素早く判別する時に便利です。
@code{#t}が返れば確実に素数であるとわかるからです (入力が大きな素数の時に
@code{#f}を返すことはありえますが)。
これに対し、下に述べるMiller-Rabin法では、合成数は確実に判別できますが、
素数であるかどうかは確実には言えません。
@c COMMON
@end defun

@defvar *small-prime-bound*
@c MOD math.prime
@c EN
For all positive integers below this value
(slightly above 3.4e14 in the current implementation),
@code{small-prime?} can determines whether it is a prime or not.
@c JP
これより小さな数に対しては、@var{small-prime?}は決定的に
素数かどうかを判別します。現在の実装ではこの数は3.4e14よりちょっと大きな数です。
@c COMMON
@end defvar


@defun miller-rabin-prime? n :key num-tests random-integer
@c MOD math.prime
@c EN
Check if an exact integer @var{n} is a prime number, using
probabilistic Miller-Rabin algorithm (@var{n} must be greater than 1).
If this procedure returns @code{#f},
@var{n} is a composite number.  If this procedure returns @code{#t},
@var{n} is @emph{likely} a prime, but there's a small probability
that it is a false positive.
@c JP
2以上の正確な整数@var{n}が素数かどうかを、確率的なMiller-Rabin法を使って判定します。
この手続きが@code{#f}を返したなら、@var{n}は確実に合成数です。
この手続きが@code{#t}を返した場合、@var{n}はおそらく素数ですが、
疑陽性である確率もわずかにあります。
@c COMMON

@c EN
Note that if @var{n} is smaller than a certain number
(@code{*small-prime-bound*}), the algorithm is
deterministic; if it returns @code{#t}, @var{n} is certainly a prime.
@c JP
ただし、@code{n}がある数(@code{*small-prime-bound*})
より小さければ、アルゴリズムは決定的で、@code{#t}が返る@var{n}は確実に素数です。
@c COMMON

@c EN
If @var{n} is greater than or equal to 
@code{*small-prime-bound*},
we use a probabilistic test.  We choosing random base integer
to perform Miller-Rabin test up to 7 times by default.
You can change the number of tests by the keyword argument
@var{num-tests}.  The error probability
(to return @code{#t} for a composite number)
is at most @code{(expt 4 (- num-tests))}.
@c JP
@var{n}が@code{*small-prime-bound*}以上の場合は
確率的テストを用います。デフォルトでは7回、ランダムにベース整数値を選んで
Miller-Rabinテストを適用します。試行回数は@var{num-tests}キーワード引数で
変更可能です。合成数に対して誤って@code{#t}を返してしまう確率は
たかだか@code{(expt 4 (- num-tests))}です。
@c COMMON

@c EN
For a probabilistic test, @code{miller-rabin-prime?} uses
its own fixed random seed by default.  We chose fixed seed
so that the behavior can be reproducible.  To change the random
sequence, you can provide your own random integer generator
to the @var{random-integer} keyword argument.   It must be
a procedure that takes a positive integer @var{k} and returns
a random integer from 0 to @var{k-1}, including.
@c JP
確率的テストでは、@var{miller-rabin-prime?}はデフォルトで
この手続き固有の、固定したランダムシードを使います。固定値なのは再現性を確保するためです。
異なる乱数系列を使いたければ、ランダムな整数生成手続きを
@var{random-integer}キーワード引数に与えてください。
手続きは正整数@var{k}を取り、0から@var{k-1}までのランダムな整数値を
返すものでなければなりません。
@c COMMON
@end defun

@defun bpsw-prime? n
@c MOD math.prime
@c EN
Check if an exact integer @var{n} is a prime number, using
Baillie-PSW primality test
(@url{http://www.trnicely.net/misc/bpsw.html}).   It is deterministic,
and returns the definitive answer below 2^64 (around 1.8e19).
For larger integers this can return @code{#t} on a composite number,
although such number hasn't been found yet.  This never returns @code{#f}
on a prime number.

This is slower than Miller-Rabin but fast enough for casual use,
so it is handy when you want a definitive answer below the above range.
@c JP
@var{n}が素数かどうかをBaillie-PSW法を用いて判定します
(@url{http://www.trnicely.net/misc/bpsw.html})。
このアルゴリズムは2^64 (約1.8e19) 以下の入力に対しては決定的であり、
正しい答えを返します。入力がそれ以上の場合、合成数に対して@code{#t}が返る可能性が
あります (具体的な数はまだ見つかっていませんが)。素数に対して@code{#f}が返ることは
決してありません。

Miller-Rabin法より遅いですがカジュアルに使う分には十分に速いので、
上記の入力範囲で確実な答えを得たい場合は便利でしょう。
@c COMMON
@end defun

@c EN
@subheading Factorization
@c JP
@subheading 素因数分解
@c COMMON

@defun naive-factorize n :optional divisor-limit
@c MOD math.prime
@c EN
Factorize a positive exact integer @var{n} by trying to divide it with
all primes up to @code{(sqrt n)}.  Returns a list of prime factors
(each of which is equal to or greater than 2),
smaller ones first.
@c JP
正整数@var{n}を、@code{(sqrt n)}までの素数で順に割ってみることで
素因数分解します。戻り値は小さい順に並べられた素因数(2以上の整数)のリストです。
@c COMMON

@example
(naive-factorize 142857)
  @result{} (3 3 3 11 13 37)
@end example

@c EN
Note that @code{(naive-factorize 1)} is @code{()}.
@c JP
@code{(naive-factorize 1)}は@code{()}を返します。
@c COMMON

@c EN
Although this is pretty naive method, this works well as far as
any of @var{n}'s factors are up to the order of around @code{1e7}.
For example, the following example runs in about 0.4sec on 2.4GHz Core2
machine.
(The first time will take about 1.3sec to realize lazy prime sequences.)
@c JP
この方法は極めてナイーブなものですが、目安としてどの素因数も@code{1e7}程度以下であれば
それなりに使えます。例えば次の例は2.4GHz Core2マシンで0.4秒で答えが返ります
(ただし、初回の実行は遅延素数シーケンスの実現化があるので1.3秒ほどかかりますが)。
@c COMMON

@example
(naive-factorize 3644357367494986671013))
  @result{} (10670053 10670053 32010157)
@end example

@c EN
Of course, if @var{n} includes any factors above that order,
the performance becomes abysmal.   So it is better to use this
procedure below 1e14 or so.
@c JP
もちろん@var{n}がより大きなオーダーの素因数を含んでいると、性能は急激に
悪化します。安全に使うには@var{n}を1e14程度のオーダーに止めておくのが良いでしょう。
@c COMMON

@c EN
Alternatively, you can give @var{divisor-limit} argument that specifies
the upper bound of the prime number to be tried.  If it is given,
@code{naive-factorize} leaves a factor @var{f} as is if it can't be
divided by any primes less than or equal to @var{divisor-limit}.
So, the last element of the returned list may be composite number.
This is handy to exclude trivial factors before applying more sophisticated
factorizing algorithms.
@c JP
オプショナル引数@var{divisor-limit}を与えると、試行する素数の上限を指定
できます。この引数がある場合、@code{naive-factorize}は因数@var{f}が
@var{divisor-limit}以下の素数で割りきれなければ、そこで諦めて@var{f}を
結果に含めます。この場合、結果の最後の要素は合成数であるかもしれないわけです。
これは、より高度な素因数分解アルゴリズムを適用する前にありきたりの素因数を
除外するのに便利です。
@c COMMON

@example
(naive-factorize 825877877739 1000)
  @result{} (3 43 6402154091)

;; whereas
(naive-factorize 825877877739)
  @result{} (3 43 4591 1394501)
@end example

@c EN
The procedure also memoizes the results on smaller @var{n} to make
things faster.
@c JP
この手続きは高速化のために小さな@var{n}に対する結果はメモ化しています。
@c COMMON
@end defun

@defun mc-factorize n
@c MOD math.prime
@c EN
Factorize a positive exact integer @var{n} using the algorithm
described in 
R. P. Brent, An improved Monte Carlo factorization algorithm, BIT 20 (1980), 176-184. @url{http://maths-people.anu.edu.au/~brent/pub/pub051.html}.
@c JP
正整数@var{n}をモンテカルロ素因数分解法
(R. P. Brent, An improved Monte Carlo factorization algorithm, BIT 20 (1980), 176-184. @url{http://maths-people.anu.edu.au/~brent/pub/pub051.html})により
素因数分解します。
@c COMMON

@c EN
This one is capable to handle much larger range than
@code{naive-factorize}, somewhere around 1e20 or so.

Since this method is probabilistic, the execution time may vary
on the same @var{n}.  But it will always return the definitive
results as far as every prime factor of @var{n} is smaller than 2^64.

At this moment, if @var{n} contains a prime factor greater than
2^64, this routine would keep trying factorizing it forever.
Practical applications should have some means to interrupt the
function and give it up after some time bounds.
This will be addressed once we have deterministic primality test.
@c JP
この手続きは@code{naive-factorize}よりも大きな数に使えます
(目安としては1e20程度まで)。

アルゴリズムは確率的なので、同じ@var{n}に対しても実行時間はばらつきますが、
@var{n}の素因数が全て2^64より小さければ、かならず確定的な答えを返します。

今のところ、@var{n}が2^64以上の素因数を含んでいる場合、この手続きは
永遠にそれを分割しようとしてループしてしまいます。現実的なアプリケーションは
何らかの方法で一定の時間でルーチンを中断して諦めるメカニズムが必要でしょう。
全ての入力に大して確定的な素数判定が実装されれば、この欠陥も修正されます。
@c COMMON
@end defun


@c EN
@subheading Miscellaneous
@c JP
@subheading その他の関数
@c COMMON

@defun jacobi a n
@c MOD math.prime
@c EN
Calculates Jacobi symbol @code{(@var{a}/@var{n})}
(@url{http://en.wikipedia.org/wiki/Jacobi_symbol}).
@c JP
Jacobi symbol @code{(@var{a}/@var{n})} を計算します
(@url{http://en.wikipedia.org/wiki/Jacobi_symbol})。
@c COMMON
@end defun

@defun totient n
@c MOD math.prime
@c EN
Euler's totient function of nonnegative integer @var{n}.

The current implementation relies on @code{mc-factorize} above,
so it may take very long if @var{n} contains large prime factors.
@c JP
オイラーのトーシェント関数です。@var{n}は非負整数です。

現在の実装は上の@code{mc-factorize}を使っており、
@var{n}が大きな素因数を持っている場合は非常に長い時間がかかります。
@c COMMON
@end defun


@c ----------------------------------------------------------------------
@node Windows support, PEG parser combinators, Prime numbers, Library modules - Utilities
@section @code{os.windows} - Windows support
@c NODE Windowsのサポート, @code{os.windows} - Windowsのサポート

@deftp {Module} os.windows
@mdindex os.windows
This module is only available on Windows-native Gauche, and
provides Windows-specific procedures.
You can check @code{gauche.os.windows} feature with
 @code{cond-expand} macro (@pxref{Feature conditional})
to conditionalize windows-specific code.

@example
(cond-expand
  [gauche.os.windows
   (use os.windows)
   ... Windows-specific code ...]
  [else
   ... Unix code ...])
@end example

Currently there aren't enough procedures provided here, but
eventually we want to support simple scripting on Windows.

Unless otherwise noted,
when Windows API returns an error value, a @code{<system-error>} condition
is thrown.
@end deftp

@menu
* Windows dialogs::
* Windows console API::
@end menu

@node Windows dialogs, Windows console API, Windows support, Windows support
@subsection Windows dialogs

Currenly we only have MessageBox API.

@defun sys-message-box window message :optional caption flags
@c MOD os.windows
Calls Windows MessageBox API.   The @var{window} argument should
be a handle for a window, or @code{#f}; at the moment we don't
provide any API that retrieves window handles, so you should always
pass @code{#f} here.  The @var{message} argument takes a string
for the content of the message box.  Optional @var{caption}
argument takes a string to be used in the window title.

The @var{flags} argument is an integer; it should be @code{logior}
of values from one or more of the following groups.  See the
Windows reference manual for the details.

@table @emph
@item Buttons
@code{MB_ABORTRETRYIGNORE},
@code{MB_CANCELTRYCONTINUE},
@code{MB_HELP},
@code{MB_OK} (default),
@code{MB_OKCANCEL},
@code{MB_RETRYCANCEL},
@code{MB_YESNO},
@code{MB_YESNOCANCEL}
@item Icon
Default is no icon.  Possible values:
@code{MB_ICONEXCLAMATION},
@code{MB_ICONWARNING},
@code{MB_ICONINFORMATION},
@code{MB_ICONASTERISK},
@code{MB_ICONQUESTION},
@code{MB_ICONSTOP},
@code{MB_ICONERROR},
@code{MB_ICONHAND}
@item Default button
@code{MB_DEFBUTTON1} (default),
@code{MB_DEFBUTTON2},
@code{MB_DEFBUTTON3},
@code{MB_DEFBUTTON4}
@item Modality
@code{MB_APPLMODAL} (default),
@code{MB_SYSTEMMODAL},
@code{MB_TASKMODAL}
@item Other options
@code{MB_DEFAULT_DESKTOP_ONLY},
@code{MB_RIGHT},
@code{MB_RTLREADING},
@code{MB_SETFOREGROUND},
@code{MB_TOPMOST},
@code{MB_SERVICE_NOTIFICATION}
@end table

Return value is one of the following integer constants,
indicating which button is pressed:
@code{IDABORT},
@code{IDCANCEL},
@code{IDCONTINUE},
@code{IDIGNORE},
@code{IDNO},
@code{IDOK},
@code{IDRETRY},
@code{IDTRYAGAIN}, or
@code{IDYES}
@end defun

@node Windows console API,  , Windows dialogs, Windows support
@subsection Windows console API

Most of these procedures corresponds to Windows Console API one-to-one.
See the Windows reference for the detail description of what each API does.

@subsubheading Attaching and detaching

@defun sys-alloc-console
@defunx sys-free-console
[Windows]
@c MOD os.windows
Calls @code{AllocConsole} and @code{FreeConsole}, respectively.
@end defun

@defun sys-generate-console-ctrl-event event pgid
[Windows]
@c MOD os.windows
@end defun

@defvr {Constant} CTRL_C_EVENT
@defvrx {Constant} CTRL_BREAK_EVENT
[Windows]
@c MOD os.windows
@end defvr

@subsubheading Console codepage

@defun sys-get-console-cp
@defunx sys-get-console-output-cp
@defunx sys-set-console-cp codepage
@defunx sys-set-console-output-cp codepage
[Windows]
@c MOD os.windows
@end defun

@defun sys-get-console-cursor-info handle
@defunx sys-set-console-cursor-info handle size visible
[Windows]
@c MOD os.windows
@end defun

@defun sys-set-console-cursor-position handle x y
[Windows]
@c MOD os.windows
@end defun

@subsubheading Console mode

@defun sys-get-console-mode handle
@defunx sys-set-console-mode handle mode
[Windows]
@c MOD os.windows
@end defun

@defvr {Constant} ENABLE_LINE_INPUT
@defvrx {Constant} ENABLE_ECHO_INPUT
@defvrx {Constant} ENABLE_PROCESSED_INPUT
@defvrx {Constant} ENABLE_WINDOW_INPUT
@defvrx {Constant} ENABLE_MOUSE_INPUT
@defvrx {Constant} ENABLE_PROCESSED_OUTPUT
@defvrx {Constant} ENABLE_WRAP_AT_EOL_OUTPUT
[Windows]
@c MOD os.windows
@end defvr

@subsubheading Screen buffer

@defun sys-create-console-screen-buffer desired-access share-mode inheritable
[Windows]
@c MOD os.windows
@end defun

@defvr {Constant} GENERIC_READ
@defvrx {Constant} GENERIC_WRITE
[Windows]
@c MOD os.windows
@end defvr

@defvr {Constant} FILE_SHARE_READ
@defvrx {Constant} FILE_SHARE_WRITE
[Windows]
@c MOD os.windows
@end defvr

@defun sys-set-console-active-screen-buffer handle
[Windows]
@c MOD os.windows
@end defun

@defun sys-scroll-console-screen-buffer handle scroll-rectangle clip-rectangle x y fill
[Windows]
@c MOD os.windows
@end defun

@deftp {Class} <win:console-screen-buffer-info>
@clindex win:console-screen-buffer-info
[Windows]
@c MOD os.windows

@defivar {<win:console-screen-buffer-info>} size.x
@defivarx {<win:console-screen-buffer-info>} size.y
@end defivar

@defivar {<win:console-screen-buffer-info>} cursor-position.x
@defivarx {<win:console-screen-buffer-info>} cursor-position.y
@end defivar

@defivar {<win:console-screen-buffer-info>} attributes
@end defivar

@defivar {<win:console-screen-buffer-info>} window.left
@defivarx {<win:console-screen-buffer-info>} window.top
@defivarx {<win:console-screen-buffer-info>} window.right
@defivarx {<win:console-screen-buffer-info>} window.bottom
@end defivar

@defivar {<win:console-screen-buffer-info>} maximum-window-size.x
@defivarx {<win:console-screen-buffer-info>} maximum-window-size.y
@end defivar

@end deftp

@defvr {Constant} FOREGROUND_BLUE
@defvrx {Constant} FOREGROUND_GREEN
@defvrx {Constant} FOREGROUND_RED
@defvrx {Constant} FOREGROUND_INTENSITY
@defvrx {Constant} BACKGROUND_BLUE
@defvrx {Constant} BACKGROUND_GREEN
@defvrx {Constant} BACKGROUND_RED
@defvrx {Constant} BACKGROUND_INTENSITY
[Windows]
@c MOD os.windows
@end defvr

@defun sys-get-console-screen-buffer-info handle
[Windows]
@c MOD os.windows
@end defun

@defun sys-get-largest-console-window-size handle
[Windows]
@c MOD os.windows
@end defun

@defun sys-set-screen-buffer-size handle x y
[Windows]
@c MOD os.windows
@end defun

@subsubheading Console input/output

@deftp {Class} <win:input-record>
@clindex win:input-record
[Windows]
@c MOD os.windows

@defivar {<win:input-record>} event-type
@end defivar

@defivar {<win:input-record>} key.down
@defivarx {<win:input-record>} key.repeat-count
@defivarx {<win:input-record>} key.virtual-key-code
@defivarx {<win:input-record>} key.virtual-scan-code
@defivarx {<win:input-record>} key.unicode-char
@defivarx {<win:input-record>} key.ascii-char
@defivarx {<win:input-record>} key.control-key-state
@end defivar

@defivar {<win:input-record>} mouse.x
@defivarx {<win:input-record>} mouse.y
@defivarx {<win:input-record>} mouse.button-state
@defivarx {<win:input-record>} mouse.control-key-state
@defivarx {<win:input-record>} mouse.event-flags
@end defivar

@defivar {<win:input-record>} window-buffer-size.x
@defivarx {<win:input-record>} window-buffer-size.y
@end defivar

@defivar {<win:input-record>} menu.command-id
@end defivar

@defivar {<win:input-record>} focus.set-focus
@end defivar

@end deftp

@defun sys-get-number-of-console-input-events handle
[Windows]
@c MOD os.windows
@end defun

@defun sys-get-number-of-console-mouse-buttons
[Windows]
@c MOD os.windows
@end defun

@defun sys-peek-console-input handle
@defunx sys-read-console-input handle
[Windows]
@c MOD os.windows
@end defun

@defun sys-read-console handle buf
[Windows]
@c MOD os.windows
@end defun

@defun sys-read-console-output handle buf w h x y region
[Windows]
@c MOD os.windows
@end defun

@defun sys-read-console-output-attribute handle buf x y
[Windows]
@c MOD os.windows
@end defun

@defun sys-read-console-output-character handle len x y
[Windows]
@c MOD os.windows
@end defun

@defun sys-set-console-text-attribute handle attr
[Windows]
@c MOD os.windows
@end defun

@defun sys-set-console-window-info handle absolute window
[Windows]
@c MOD os.windows
@end defun

@defun sys-write-console handle string
[Windows]
@c MOD os.windows
@end defun

@defun sys-write-console-output-character handle string x y
[Windows]
@c MOD os.windows
@end defun

@defun sys-fill-console-output-character handle char len x y
[Windows]
@c MOD os.windows
@end defun

@defun sys-fill-console-output-attribute handle attr len x y
[Windows]
@c MOD os.windows
@end defun

@defun sys-flush-console-input-buffer handle
[Windows]
@c MOD os.windows
@end defun

@defun sys-get-console-title
[Windows]
@c MOD os.windows
@end defun

@defun sys-set-console-title string
[Windows]
@c MOD os.windows
@end defun

@subsubheading Standard handles

@defun sys-get-std-handle which
@defunx sys-set-std-handle which handle
[Windows]
@c MOD os.windows
@end defun

@defvr {Constant} STD_INPUT_HANDLE
@defvrx {Constant} STD_OUTPUT_HANDLE
@defvrx {Constant} STD_ERROR_HANDLE
[Windows]
@c MOD os.windows
@end defvr


@c ----------------------------------------------------------------------
@node PEG parser combinators, RFC822 message parsing, Windows support, Library modules - Utilities
@section @code{parser.peg} - PEG parser combinators
@c NODE PEGパーザコンビネータ, @code{parser.peg} - PEGパーザコンビネータ

@deftp {Module} parser.peg
@mdindex parser.peg
@c EN
This module implements a parser combinator library
to build parsers based on Parsing Expression Grammar, or PEG.
@c JP
このモジュールは、Parsing Expression Grammar (PEG)に基づいたパーザを組み立てる
コンビネータライブラリを実装しています。
@c COMMON

@c EN
PEG is a @emph{formal grammar} to define a language, like regular
expressions or context-free grammars.
An interesting characteristic of PEG is that it can
be directly mapped to a recursive decent parser, which is exactly
what this library does---each production rule is a Scheme expression
that takes parsers and returns a combined parser.  One advantage of
this approach is that you can freely mix ordinary Scheme code
within the parser, that is, there's no special ``parser description
language'' distinct from the base Scheme language, nor you need to
run separate tools like parser generators to obtain a runnable parser code.
@c JP
PEGは、正規表現や文脈自由文法と同様の@emph{形式言語}です。
PEGが興味深いのは、文法記述がそのまま再帰下降パーザに移し替えられるところで、
このライブラリはまさにそれをやっています。各生成規則は、パーザを受け取って
結合されたパーザを返すScheme式です。
このアプローチの利点は、Schemeコードと文法記述を混ぜて書けることです。
特別な「パーザー記述言語」を別に学ぶ必要も、パーザジェネレータのような別ツールを
使ってソースコードを生成する必要もありません。
@c COMMON

@c EN
Although PEG can directly parse the character string, the parser
combinators are not tied to it.  In fact, most of the combinators
work transparently for any
sequence of tokens, where the exact meanings of tokens depend on
the application; you can have separate lexer that generates
token sequence that PEG parser can parse, for example.
@c JP
PEGは文字列を直接パーズすることもできますが、
パーザコンビネータは文字列のパーズ限定ではありません。実際、多くのコンビネータは
「トークン」の列 (具体的なトークンの意味はアプリケーションが決められます) に対して
透過的に動作します。例えば字句解析器を別に作ってトークンの列を生成し、
それをPEGでパーズする、ということもできます。
@c COMMON

@c EN
This library is specifically written to get a good performance
on Gauche.  The parser created by @code{parser.peg} is
no slower than the parser written manually from scratch.
However, you have to watch out some traps; see
@ref{PEG performance tips}, for the details.
@c JP
このライブラリは、Gaucheで性能が出るように書かれています。
@code{parser.peg}で作られたパーザは、手書きのパーザと遜色ない性能を持ちます。
但し、いくつか気をつけるべき点はあります。それについては
@ref{PEG performance tips}を参照してください。
@c COMMON
@end deftp

@menu
* PEG Walkthrough::
* PEG parser drivers::
* What is a PEG parser::
* PEG primitive parser builders::
* PEG ropes::
* PEG choice::
* PEG sequencing combinators::
* PEG repetition combinators::
* PEG miscellaneous combinators::
* PEG performance tips::
@end menu

@node PEG Walkthrough, PEG parser drivers, PEG parser combinators, PEG parser combinators
@subsection Walkthrough
@c NODE PEGひとめぐり

@c EN
In this section we cover the basic concepts and tools of @code{parser.peg}.
The code of examples is in @file{examples/pegintro.scm} if you have the
source tree of Gauche.
@c JP
本節では、@code{parser.peg}の基本的なコンセプトと道具を説明します。
例に使ったコードは、Gaucheのソースツリーの@file{examples/pegintro.scm}にあります。
@c COMMON

@c EN
In @code{parser.peg}, a parser is merely a Scheme procedure
that takes a list of tokens as an argument and returns
a result (well, in fact, it returns three values, but we'll go
into the details later.)
@c JP
@code{parser.peg}では、パーザとは単なるSchemeの手続きです。それは
トークンのリストを引数に取り、結果を返します
(実際は3つの値を返します。それについては後で詳しく述べます)。
@c COMMON

@c EN
Typically you don't need to write parser procedures directly.
Instead, you can use procedures that
generates parsers.   A parser can be as simple as the
following, which accepts a character @code{#\a}.
@c JP
パーザ手続きを直接書く必要は滅多にありません。
代わりに、パーザを生成する手続きがたくさん用意されているのでそれを使います。
例えば、文字@code{#\a}を受理するパーザはこう書けます。
@c COMMON

@example
($. #\a)   ; @result{} a parser
@end example

@c EN
Here, @emph{accept} means the parser checks if the head of input has
a character @code{#\a}, and if it is, it succeeds, and if not, it fails.
@c JP
ここで@emph{受理する}とは、パーザが入力の先頭をチェックして、
それが文字@code{#\a}ならば成功し、そうでなければ失敗するという意味です。
@c COMMON

@c EN
A parser can be invoked by a @emph{parser driver}.  For example,
you can use @code{peg-parse-string} to invoke the above parser
on a string:
@c JP
パーザは@emph{パーザドライバ}によって呼び出せます。例えば
@code{peg-parse-string}を使って、上のパーザで文字列をパーズしてみましょう。
@c COMMON

@example
gosh> (peg-parse-string ($. #\a) "abc")
#\a
@end example

@c EN
The parsing succeeds, and returns the matched value---@code{#\a} in this case.
If the parser can't accept the input, the driver throws an error
@code{<parse-error>}.
@c JP
パーズは成功し、マッチした値 (@code{#\a}) が返りました。
パーザが期待する入力でなかった場合には、ドライバは@code{<parse-error>}を投げます。
@c COMMON

@example
gosh> (peg-parse-string ($char #\a) "xyz")
*** PARSE-ERROR: expecting #\a at 0, but got #\x
@end example

@c EN
A parser can also be constructed by combining simpler parsers,
using @emph{parser combinators}.   For example, @code{$seq} takes
zero or more parsers and apply them sequentially, returning
the last result.
@c JP
単純なパーザを@emph{パーザコンビネータ}で組み合わせて、より複雑なパーザを作ることができます。
例えば、@code{$seq}はいくつかのパーザを受け取り、「それらを順に適用して
最後の結果を返すパーザ」を作って返します。
@c COMMON

@example
gosh> (peg-parse-string ($seq ($. #\a) ($. #\b) ($. #\c)) "abc")
#\c
@end example

@c EN
The combinator @code{$many} takes a parser and returns a new parser
that accepts zero or more occurrence of the string the original parser
accepts.
@c JP
コンビネータ@code{$many}はパーザを取ると、それのゼロ回以上の繰り返しを受理する
パーザを作って返します。
@c COMMON

@example
gosh> (peg-parse-string ($many ($. #\a)) "aaaaabc")
(#\a #\a #\a #\a #\a)
gosh> (peg-parse-string ($many ($. #\a)) "xxxxxyz")
()
@end example

@c EN
A parser is just an ordinary Scheme procedure, so it can be bound
to a variable, then can be used to construct more complex parsers.
@c JP
パーザは通常のSchemeの手続きなので、変数に束縛し、それをより複雑なパーザを作るのに使えます。
@c COMMON

@example
(define digits    ($many1 ($. #[\d])))
(define ws        ($many_ ($. #[\s])))
(define separator ($seq ws ($. #\,) ws))
@end example

@c EN
I leave explanation of @code{$many1} and
@code{$many_} for the later section,
but you may be able to guess what those parsers do;
@code{digits} accepts a sequence of one or more digits, and
@code{ws} accepts sequence of zero or more whitespaces.   The @code{separator}
parser accepts a comma, optionally surrounded by whitespaces.
@c JP
@code{$many1}と@code{$many_}の説明は後回しにしますが、
何となくこれらのパーザの動作は推測できるのではないでしょうか。
@code{digits}は1個以上の数字の並びを、
@code{ws}は0個以上の空白文字の並びを受理するパーザです。
@code{separator}パーザは0個以上の空白で囲まれたコンマを受容します。
@c COMMON

@c EN
The @code{digits} parser returns a list of accepted
characters:
@c JP
@code{digits}は受理した文字のリストを返します。
@c COMMON

@example
gosh> (peg-parse-string digits "12345")
(#\1 #\2 #\3 #\4 #\5)
@end example

@c EN
Can we create a parser that returns an integer as
a parsed result?    Yes, we can use the @code{$let} macro.
@c JP
パーズの結果として整数値を返すようにできるでしょうか。
@code{$let}マクロを使えばできます。
@c COMMON

@example
(define integer
  ($let ([ds digits])
    ($return (x->integer (list->string ds)))))
@end example

@c EN
The @code{$let} works somewhat like @code{and-let*}; it takes
a form of @code{($let ([@var{var} @var{parser}] @dots{}) @var{expr} @dots{})},
applying the @var{parser}s in order, binding the result of each
parser to @var{var}.  If any of the @var{parser} fails, the entire
parser created by @code{$let} macro fails.  When all the @var{parser} succeeds,
each result is  bound to @var{var} and @var{expr} @dots{} are
evaluated.  The last @var{expr} must yield a parser.
@c JP
@code{$let}は@code{and-let*}のように動作します。
@code{($let ([@var{var} @var{parser}] @dots{}) @var{expr})}という形式を取り、
@var{parser}を順に入力に適用してゆきます。
@var{parser}のどれかひとつでも失敗したら全体が失敗します。
全ての@var{parser}が成功したら、それぞれの結果が@var{var}に束縛された環境下で
@var{expr} @dots{}が評価されます。最後の@var{expr}はパーザを返さねばなりません。
@c COMMON

@c EN
The @code{$return} procedure creates a parser
that doesn't consume input, always succeeds
and returns the given value.  The name is taken from
Haskell's monads.  Note that is is just an ordinary procedure
and not like a control-transfer syntax like traditional language's
@code{return}.  You may think it just as type conversion
procedure from a Scheme object to a parser.
@c JP
@code{$return}手続きは、入力を消費せず、常に成功し、引数をパーズ結果とする
パーザを作ります。この名前はHaskellのモナドからきました。
他の多くの言語にあるreturnのように制御の流れを変えるのではなく、単なる手続きであることに
注意してください。任意のSchemeオブジェクトをパーザに変える変換手続きと考えても良いでしょう。
@c COMMON

@example
gosh> (peg-parse-string integer "12345")
12345
@end example

@c EN
Now you can combine those parsers to build more complex one, such
as a comma-separated list of integers:
@c JP
これらのパーザを組み合わせて、さらに複雑なパーザを作ることができます。
例えばコンマで区切られた整数のリストです：
@c COMMON

@example
(define integers1 ($seq integer
                        ($many ($seq separator integer))))

gosh> (peg-parse-string integers1 "123, 456, 789")
(456 789)
@end example

@c EN
Oops, where's 123?  Well, remember that
@code{$seq} discards the results but the last one.
We can use @code{$let} again to keep all the results.
@c JP
あれ、最初の123がどっかいっちゃいました。そうそう、
@code{$seq}は最後のパーザの値以外は捨てるのでした。
@code{$let}を使って結果を集めることができます。
@c COMMON

@example
(define integers2 ($let ([n  integer]
                         [ns ($many ($seq separator integer))])
                     ($return (cons n ns))))

gosh> (peg-parse-string integers2 "123, 456, 789")
(123 456 789)
@end example

@c EN
(Unlike @code{let} where the order of its init expressions are
not defined, @code{$let} guarantees the parsers are applied sequentially.
The reason it is not called @code{$let*} is the scope;
we also have @code{$let*}, which we'll explain shortly.)
@c JP
(@code{let}ではinit式の評価順序は決まっていませんが、
@code{$let}はパーザを書かれた順に適用することを保証しています。
これを@code{$let*}と呼んでいないのはスコープのためです。
すぐ後で@code{$let*}も紹介します。)
@c COMMON

@c EN
Another way to gather the results of parsers is a combinator @code{$lift}.
It is used as @code{($lift proc parser @dots{})}, where @var{proc}
is an ordinary procedure which receives the result of @var{parser} @dots{}
as arguments.  The return value of @var{proc} becomes the result of
the entire parser.  Unlike @code{$let}, @var{proc} doesn't need to
return a parser.
@c JP
パーザの結果を集めるもうひとつの方法は@code{$lift}コンビネータです。
@code{($lift proc parser @dots{})} のように使います。ここで
@var{proc}は普通の手続きで、@var{parser} @dots{}の結果を引数として受け取り、
@var{proc}の返した結果が全体のパーザの結果になります。
@code{$let}と違って、@var{proc}はパーザを返す必要はありません。
@c COMMON

@example
(define integers3 ($lift cons
                         integer
                         ($many ($seq separator integer))))
@end example

@c EN
The parsers so far doen't handle the case when the list contains no
integers.   Using @code{$or} combinator, which represents a choice,
we can modify it to handle zero-element case.
@c JP
これまでのパーザは入力に整数が全く含まれていない場合を考慮していませんでした。
選択を表す@code{$or}コンビネータを使って、整数が無いケースをサポートできます。
@c COMMON

@example
(define integers4 ($or ($let ([n  integer]
                              [ns ($many ($seq separator integer))])
                         ($return (cons n ns)))
                       ($return '())))
@end example

@c EN
By the way, ``list of stuff separated by something'' is a very common
pattern, so we can extract the pattern to name it:
@c JP
ところで、「何かで区切られた何かのリスト」というのは頻繁に出てくるので、次のように
パターンを取り出しておくことができます：
@c COMMON

@example
(define (sep-by stuff separator)
  ($or ($let ([n  stuff]
              [ns ($many ($seq separator stuff))])
         ($return (cons n ns)))
       ($return '())))
@end example

@c EN
Then the list of integers can be written this simple:
@c JP
すると整数のリストのパーザはこんなに簡単になります:
@c COMMON

@example
(define integers5 (sep-by integer separator))
@end example

@c EN
In fact, @code{parser.peg} provides @code{$sep-by} to do the above,
but we've just shown the definition to demonstrate
the power of the combinatorial approach;
you can use ordinary procedural abstraction to factor out common patterns.
@c JP
実は@code{parser.peg}には上と同じことができる@code{$sep-by}というのが
既に用意されているんですが、コンビネータを使う方法の強みを示すために
あえて実装してみました。
共通のパターンに通常の手続きを使った抽象化を使えるのが利点です。
@c COMMON

@c EN
There's one catch in the @code{$or} form.
It tries the next alternative only when the
parser fails @emph{without consuming the input}.  Once the input is
consumed, @code{$or} commits to that choice.   For example,
the following fails even if the input seems to match the
second alternative:
@c JP
@code{$or}についてはひとつ注意があります。ある選択肢が失敗した時、
@emph{それが入力を消費していない場合に限り}、次の選択肢が試されるということです。
入力が少しでも消費されたら、@code{$or}はその選択肢にコミットし、
その先で失敗しても他の選択肢を試しません。下の例では、
2番目の@code{$seq}が入力にマッチするにもかかわらず、パーズは失敗します。
@c COMMON

@example
(define paren  ($. #\())
(define thesis ($. #\)))

(peg-parse-string ($or ($seq paren ($."ab") thesis)
                       ($seq paren ($."cd") thesis))
                  "(cd)")
 @result{} *** PARSE-ERROR: expecting ab at 1, but got #\c
@end example

@c EN
It's because when @code{$or} tries the first branch, it reads the initial
open paren from the input, so @code{$or} commits to the first branch.
When the branch fails, @code{$or} doesn't bother to try the second branch.
(In other words, @code{$or} does not backtrack.)
@c JP
@code{$or}の最初の選択肢で、先頭の開き括弧はマッチに成功して入力が消費されます。
その後でマッチが失敗するわけですが、既に入力が消費されているので、
@code{$or}は他の選択肢を考慮することなく全体を失敗させます。
(言い換えれば、@code{$or}はバックトラックを行いません。)
@c COMMON

@c EN
You may factor out the common prefix:
@c JP
一つの手は、共通部分を括り出すことです。
@c COMMON

@example
($seq paren
      ($or ($."ab") ($."cd"))
      thesis)
@end example


@c EN
But it may complicates the syntax, and it is not always trivial to
factor out like above.  The better way is to use the @code{$try}
combinator: @code{($try @var{p})} runs a parser @var{p}, and if
it fails, @code{$try} rolls back the input as if it didn't
consume input at all.  Using with @code{$or}, you can do arbitrary
lookahead and backtrack.
@c JP
ただ、これは文法を複雑化させることがありますし、
いつでも簡単にできるとは限りません。よりうまい方法は@code{$try}コンビネータを
使うことです。 @code{($try @var{p})}はパーザ@var{p}を走らせ、それが
失敗したら入力を元の時点まで巻き戻します。@code{$or}と一緒につかえば、
いくらでも先読みとバックトラックができます。
@c COMMON

@example
($or ($try ($seq paren ($."ab") thesis))
     ($seq paren ($."cd") thesis))
@end example

@c EN
Now, let's get back to the integer list example and make
it more interesting.
Suppose the list of integers are surrounded by parentheses,
brackets or curly-braces.  Opening one and closing one must correspond.
@c JP
さて整数のリストの例をもうちょっとおもしろくしてみましょう。
リストは小括弧、中括弧、大括弧のどれかで囲まれていて、開き括弧と閉じ括弧は対応
していなければならない、とします。
@c COMMON

@example
(define begin-list 
  ($seq0 ($. #[\(\[\@{]) ws))

(define (end-list opener) 
  ($seq ws (case opener
            [(#\() ($. #\))]
            [(#\[) ($. #\])]
            [(#\@{) ($. #\@})])))

(define int-list
  ($let* ([opener begin-list]                ;*1
          [ints ($sep-by integer separator)] ;*2
          [ (end-list opener) ])             ;*3
    ($return ints)))
@end example

@c EN
The opening bracket is parsed by the parser @code{begin-list}.
The @code{$seq0} combinator is similar to @code{seq}, but returns
the result of the first parser instead of the last one
(it's @code{begin0} to @code{begin}).
@c JP
開き括弧は@code{begin-list}パーザが受理します。@code{$seq0}は
@code{$seq}とほぼ同じですが、最初のパーザの結果を返します。
(@code{begin}に対する@code{begin0}と同じです。)
@c COMMON

@c EN
The closing bracket must match the opening one, so @code{end-list}
is a procedure that takes the opening bracket and returns a suitable
parser to accept the corresponding closing bracket.
@c JP
閉じ括弧は開き括弧と対応しないとならないので、@code{end-list}は
開き括弧を取って適切な閉じ括弧のパーザを返す手続きになっています。
@c COMMON

@c EN
The @code{int-list} first parses the opening bracket by @code{begin-list}
and bind the result to @var{opener} (*1).
Then goes to parse comma-separated integers (*2) and bind the
result list to @var{ints}.
Finally, it parses the matching closing bracket (*3).  Note that
the it omits the variable, since we don't need the result of
closing bracket parser.
@c JP
@code{int-list}はまず開き括弧を@code{begin-list}でパーズし、その結果を
@var{opener}に束縛します(*1)。次にコンマ区切りの整数をパーズし、結果のリストを
@var{ints}に束縛します(*2)。最後に開き括弧に対応する閉じ括弧をパーズします(*3)。
最後のパーザは値を使わないので、変数を省略しています。
@c COMMON

@c EN
Since we need to use the value of @var{opener} in the following bindings,
we use @code{$let*} here, instead of @code{$let}.  The difference is
the scope of the parser expressions in the binding.  Note that, however,
@code{$let} is a lot more easier to optimize, so you want to use
@code{$let} whenever possible.
@c JP
@var{opener}の値を続く束縛フォームの中で使う必要があるので、
ここでは@code{$let}ではなく@code{$let*}を使いました。
この差は@code{let}と@code{let*}の差と同じで、スコープの違いです。
ただ、@code{$let}の方が処理系にはうんと最適化しやすいので、
可能な限り@code{$let}を使う方が良いでしょう。
@c COMMON

@c EN
Let's see it works.
@c JP
走らせてみます。
@c COMMON

@example
gosh> (peg-parse-string int-list "[123, 456, 789]")
(123 456 789)
gosh> (peg-parse-string int-list "@{123, 456, 789@}")
(123 456 789)
gosh> (peg-parse-string int-list "(123, 456, 789@}")
*** PARSE-ERROR: expecting #\) at 14, but got #\@}
@end example

@c EN
The last example shows it rejects unmatched brackets.
@c JP
最後の例は括弧の対応が取れていないと失敗する例です。
@c COMMON

@c EN
What if we want a nested list?  In BNF, we could write
something like this:
@c JP
ネストしたリストをパーズするにはどうすればいいでしょう?
BNFならこう書けるでしょう。
@c COMMON

@example
list : begin-list (elem (separator elem)* )? end-list
elem : integer | list
@end example

@c EN
The straight translation would be he following.
@c JP
これをそのまま移し替えると次のようになります。
@c COMMON

@example
;; First try
(define nested-list
  ($let* ([opener begin-list]
          [ints ($sep-by elem separator)]
          [ (end-list opener) ])
    ($return ints)))
(define elem  ($or integer nested-list))
@end example

@c EN
Let's load it... Oops.
@c JP
ロードしてみましょう。おっと
@c COMMON

@example
*** ERROR: unbound variable: elem
Stack Trace:
_______________________________________
  0  elem
        [unknown location]
  1  (eval expr env)
        at "../lib/gauche/interactive.scm":267
@end example

@c EN
We need the parser @code{elem} to construct @code{nested-list}, but
we need the parser @code{nested-list} to construct @code{elem}.
In lazy languages like Haskell this doesn't matter, but we Schemers
are @emph{eager}!
@c JP
@code{nested-list}の値を計算するのに@code{elem}の値を使いますが、
@code{elem}の値を計算するのに@code{nested-list}の値が必要です。
Haskellのような怠惰な言語ならこれでも構わないんですが、
Schemerは熱心なんです!
@c COMMON

@c EN
The solution is to delay the parser construction until it is
actually used.  The @code{$lazy} form does the job:
@c JP
解決策は、パーザの計算を必要になるまで遅らせることです。
@code{$lazy}フォームが必要な遅延を行います。
@c COMMON

@example
(define nested-list
  ($lazy
    ($let* ([opener begin-list]
            [ints ($sep-by elem separator)]
            [ (end-list opener) ])
      ($return ints))))
(define elem  ($or integer nested-list))

gosh> (peg-parse-string nested-list "(123, [456, @{@}, 789], 987)")
(123 (456 () 789) 987)
@end example

@c EN
Ok, we're almost done.  Our code can parse nested list of integers,
checking bracket matches.  But if you give an erroneous input, the message
is cryptic and not helpful:
@c JP
さあ、ほとんど完成です。
括弧の対応をチェックしながら、ネストした整数のリストをパーズできるようになりました。
ただ、間違いのある入力を与えた時に出されるエラーメッセージがわかりにくいですね。
@c COMMON

@example
gosh> (peg-parse-string nested-list "(123, [456, @{@}, 789), 987)")
*** PARSE-ERROR: expecting one of (#[0-9] #\]) at 19
Stack Trace:
_______________________________________
  0  (eval expr env)
        at "../lib/gauche/interactive.scm":267
@end example

@c EN
We could check the reason of failure in the parser, and call
@code{$fail} with more reasonable error message.  Let's replace
@code{end-list} above with @code{end-list2} below:
@c JP
パーザの中で失敗の理由を調べて、意味のあるエラーメッセージで@code{$fail}を呼び出すことが
できます。上の@code{end-list}を下の@code{end-list2}に置き換えてみて下さい。
@c COMMON

@example
(define (end-list2 opener) 
  (define expected
    (assv-ref '((#\( . #\)) (#\[ . #\]) (#\@{ . #\@})) opener))
  ($seq ws 
        ($let ([closer ($. #[\)\]\@}])])
          (if (eqv? closer expected)
            ($return closer)
            ($fail (format "Mismatched closing bracket. '~c' expected, \
                            but got '~c'"
                           expected closer))))))
@end example

@c EN
You also have to change @code{nested-list} and @code{elem} to 
use @code{end-list2}:
@c JP
@code{nested-list}と@code{elem}についても@code{end-list2}を使うように変更します:
@c COMMON
                           
@example
(define nested-list2
  ($lazy
    ($let* ([opener begin-list]
            [ints ($sep-by elem2 separator)]
            [ (end-list2 opener) ])
      ($return ints))))

(define elem2  ($or integer nested-list2))
@end example

@c EN
(You could redefine @code{end-list}, but if you do so, don't forget to
re-evaluate the definitions of @code{nested-list} and @code{elem}.  
It's because the combinators
are caculated taking the value of other combinators when it's defined,
unlike typical procedural approach where you redefine one procedure and
other procedures will refer to the updated version after that.)
@c JP
(@code{end-list}を再定義しても良いのですが、その場合は
@code{nested-list}と@code{elem}の定義を再評価することを忘れないでください。
コンビネータは、定義時に他のコンビネータの値を使って計算されます。
通常の手続き定義のアプローチでは、一つの手続きの定義を差し替えたら他の手続きは
新しい定義を使うようになりますが、それと異なるので要注意です。)
@c COMMON

@c EN
And now you see this error:
@c JP
これで、エラーメッセージはこんなふうになります。
@c COMMON

@example
gosh> (peg-parse-string nested-list2 "(123, [456, @{@}, 789), 987)")
*** PARSE-ERROR: Mismatched closing bracket. ']' expected, but got ')' at 20
Stack Trace:
_______________________________________
  0  (eval expr env)
        at "../lib/gauche/interactive.scm":267
@end example

@c EN
For further examples, you can take a look at some libraries in the
Gauche source tree that use @code{parser.peg}:
@c JP
更なる例は、Gaucheソースツリーの中で@code{parser.peg}を使っているライブラリに
見ることができます:
@c COMMON

@itemize @bullet
@item
@file{lib/rfc/json.scm}
@item
@file{lib/text/edn.scm}
@item
@file{lib/www/css.scm}
@end itemize


@node PEG parser drivers, What is a PEG parser, PEG Walkthrough, PEG parser combinators
@subsection Parser drivers
@c NODE PEGパーザドライバ, パーザドライバ

@defun peg-run-parser parser list
@c MOD parser.peg
@c EN
Apply @var{parser} on the input @var{list}.   If @var{parser} accepts it,
returns two values--the result of @var{parser}, and the rest of
the input.  If @var{parser} fails, raise @code{<parse-error>}.
@c JP
パーザ@var{parser}を入力@var{list}に適用します。入力が受理されたら、
@var{parser}の結果と、残りの入力の二つの値を返します。
@var{parser}が失敗したら、@code{<parse-error>}が投げられます。
@c COMMON

@c EN
The result of @var{parse} is a value yielded by @var{parser}
passed to @code{rope-finalize}, so any unfinalized rope is
finalized before being returned.  @xref{PEG ropes}, for the details.
@c JP
@var{parse}の結果は@code{rope-finalize}を通されるので、結果中の
ファイナライズされていないロープは全てファイナライズされて返されます。
ロープについては@ref{PEG ropes}を参照してください。
@c COMMON

@c EN
Typically, you don't want to have entire input as a list beforehand,
so you pass a lazy sequence as @var{list} (@pxref{Lazy sequences}).
If the input is a string
or a port, convenience procedures are defined.
@c JP
多くの場合、入力をあらかじめ全部リストで持っておきたくはないと思います。
その場合、遅延シーケンスを@var{list}に渡せば良いでしょう (@ref{Lazy sequences})。
なお、入力が文字列やポートの場合はユーティリティ手続きが定義されています。
@c COMMON

@c EN
Input doesn't need to be a character list.  You may, for example,
have a separate lexer that generates a (lazy) list of tokens, and let @var{parser}
parse them.
@c JP
入力が文字のリストである必要はありません。
例えば、別の字句解析器を使ってトークンの(遅延)リストにしてから、
@var{parser}でそれをパーズすることもできます。
@c COMMON
@end defun

@defun peg-parse-string parser string :optional cont
@defunx peg-parse-port parser iport :optional cont
@c MOD parser.peg
@c EN
Convenience wrappers of @code{peg-run-parser} that takes input from
@var{string} or @var{iport}.
@c JP
@code{peg-run-parser}で文字列@var{string}や入力ポート@var{iport}からの入力を
パーズするユーティリティ手続きです。
@c COMMON

@c EN
Without @var{cont} argument or it is @code{#f}, 
it returns the parsed result and discards
the rest of the input.  (Hint: To make sure there's no garbage
following, use @code{$eos} parser.)
@c JP
@var{cont}引数が省略されるか@code{#f}であれば、
この手続きはパーザが受理したところ以降の入力は捨てて、パーザの結果だけ返します。
(ヒント: 余分なゴミが後に続いてないことを保証するには@code{$eos}パーザが使えます)。
@c COMMON

@c EN
If you want to keep parsing after @var{parser} accepts its input,
pass @var{cont} a procedure; it must take two arguments, the result of
@var{parser} and a lazy sequence of the rest of the input.  What @var{cont}
returns will be the result of these procedures.
@c JP
@var{parser}が入力を受理した後、さらにパーズを続けたければ、@var{cont}に手続きを
渡します。その手続きは@var{parser}の結果と、残りの入力の遅延シーケンスの二つの
引数を取ります。@var{cont}が返すものが全体の返り値となります。
@c COMMON

@c EN
It is an error to pass other values ot @var{cont}.
@c JP
@var{cont}にそれ以外の値を渡すのはエラーです。
@c COMMON
@end defun

@defun peg-parser->generator parser list
@c MOD parser.peg
This is useful when you need to apply @var{parser} repeatedly over
the input @var{list}.    Returns a generator that generates
the parsed result one match at a time.

The same input can be accepted by
by @code{(peg-run-parser ($many parser) list)}, but this one
won't return until all input is consumed.
@end defun

@deftp {Condition type} <parse-error>
@c MOD parser.peg
An condition type raised by the parser driver when the given parser
failed ultimately.  Inherits @code{<error>}.
(Note that each parser won't throw this; one
parser's failure doesn't necessarily mean the entire parser fails.
It's the driver that recognizes the ultimate failure and raise this
condition.)

The following slots are available:

@defivar <parse-error> message
This slot is inherited from @code{<error>}.  Contains string error message.
@end defivar

@defivar <parse-error> position
The position the failure occurs, counted by the number of tokens
from the beginning of the input.
@end defivar

@defivar <parse-error> type
The type of failure.  It's either one of the follownig symbols:
@table @code
@item fail-expect
The parser expects one of the objects in @var{objects} slot, but
got a different one (stored in @var{token}).
@item fail-unexpect
The parser isn't expecting any of the objects in @var{objects} slot,
but got the one in @var{token}.
@item fail-compound
The parser failed multiple options.  The @var{objects} slot contains
a list of of @code{(type . msg)} where @var{type} is one of the
@code{<parse-error>} types, and
@var{msg} is the message associated with it.
@item fail-message
Other miscellaneous failure.  The @var{objects} slot contains
a mmessage.
@end table
@end defivar

@defivar <parse-error> objects
Value of this slot depends on the value of @var{type} slot.
@end defivar

@defivar <parse-error> token
The token at the head of input when failure occur.  If input already
reached at the end, this slot is set to @code{#<eof>}.
@end defivar
@end deftp

@node What is a PEG parser, PEG primitive parser builders, PEG parser drivers, PEG parser combinators
@subsection What is a PEG parser, really?

A PEG parser is a Scheme procedure that takes a list of items as an input,
and returns three values:

@itemize
@item
Failure type.  If the parser successfully accepts the input, this value
is @code{#f}.  If the parser fails to accept the input,
this value is either one of the symbols
@code{fail-expect}, @code{fail-unexpect}, @code{fail-compound}
and @code{fail-message}.  It corresponds to the @code{type} slot
of @code{<parse-error>}, and determines the meaning of the second
return value.
@item
Value.  If the parser successfully accepts the input, this
value is the parser's ``result'', sometimes called a semantic
value.  If the parser fails to accept the input,
this value contains the hint of the failure.  It corresponds
to the @code{objects} slot of @code{<parse-error>}; see the documentation
of @code{<parse-error>} for the details (@pxref{PEG parser drivers}).
@item
The rest of the input list.
@end itemize

Typically you don't need to write a parser as a procedure; instead,
you can use one of the parser builders and combinators described in
the following sections.

We do provide a few utilities to write a parser from scratch, in case
you need to do so.

@defun return-result value rest
@c MOD parser.peg
Call this at the tail position of the parser when it succeeds, with
@var{value} for the semantic value and @var{rest} for the rest of
input.  This is the same as @code{(values #f value rest)}, but
clearer to show the intention.
@end defun

@defun return-failure/expect objs rest
@defunx return-failure/unexpect objs rest
@defunx return-failure/message msg rest
@defunx return-failure/compound fails rest
@c MOD parser.peg
Call one of these at the tail position of the parser when it fails.
The first argument will be in @code{objects} slot of @code{<parse-error>}.

@itemize
@item
If you're expecting some types of objects (@var{objs}) but got anything
else, call @code{return-failure/expect}.  It generates @code{fail-expect}
type failure.
@item
If you're not expecting some types of objects (@var{objs}) but got one,
call @code{return-failure/unexpect}.  It generates @code{fail-unexpect}
type failure
@item
If you're failing because of all of multiple choices fail, you can
gather those failures into an assoc list
@code{((fail-type . objs) @dots{})}, and 
call @code{return-failure/compound}.  It generates @code{fail-compound}
type failure.
@item
Finally, your failure can't be categorized to one of the above,
you can call @code{return-failure/message}, with the message
describing the reason of the failure.
@end itemize
@end defun

@defun return-failure type objs rest
@c MOD parser.peg
This should only be used to pass down the failure form other parser.
See the example in @code{parse-success?} entry below.
@end defun


@defun parse-success? r
@c MOD parser.peg
Check the first return value of a parser to see if it is a success.
A typical usage is to check another parser's result and take
actions accordingly:

@example
(receive (r v s) (parser input)
  (if (parse-success? r)
     (... do things after PARSER succeeds ...
       (return-result ...))
     (return-failure r v s)))
@end example
@end defun


@node PEG primitive parser builders, PEG ropes, What is a PEG parser, PEG parser combinators
@subsection Primitive parser builders

Procedures and macros that create parsers.

@defun $return val
@c MOD parser.peg
Returns a parser that always succeeds, without consuming
input, and yields @var{val} as the result of parser.

Frequently used in @code{$let} and @code{$let*}'s body, but can be
used anywhere a parser is expected.
@end defun

@defun $fail msg-string
@c MOD parser.peg
Returns a parser that always fails, without consuming input,
and uses @var{msg-string} as the failure message.

Frequently used to produce user-friendly error messages.
@end defun

@defun $satisfy pred expect :optional result
@c MOD parser.peg
This corresponds to ``semantic predicate'' in PEG; a parser
that can apply an arbitrary predicate on input.

Returns a parser that works as follows:
@itemize @bullet
@item
If the head of input stream satisfies @var{pred},
call @code{(@var{result} head (@var{pred} head))} and
yield its return value as the result of successful parsing.
If @var{result} is omitted, it yields the head of input.
@item
Otherwise, the parsing fails with @var{expect} as the expected input.
@end itemize
@end defun

@defun $. obj
@c MOD parser.peg
Creates a parser that matches a Scheme object @var{obj},
which may be a character, a string, or a char-set.
If @var{obj} is a char-set, the parser matches any character in the set.

The resulting parser is atomic, that is, it doesn't consume
input when it fails.
@end defun

@defun $char c
@defunx $char-ci c
@c MOD parser.peg
Returns a parser that accepts a single character, @var{c}.
@code{$char-ci} ignores case.
On success, the parser yields the input character.
The resulting parser is atomic, that is, it doesn't consume
input when it fails.
@end defun

@defun $string str
@defunx $string-ci str
@c MOD parser.peg
Returns a parser that accepts an input that matches
a string @var{str}.  @code{$string-ci} ignores case.
On success, the parser yields the matched string.

The parsing of string is atomic: When the parser fails,
it doesn't consume the input.  That is,
@code{($string "ab")} is not the same as
@code{($let ([a ($char #\a)] [b ($char #\b)]) ($return (string a b)))}.
@end defun

@defun $one-of cset
@c MOD parser.peg
Returns a parser that accepts any character in the character set @var{cset}.
On success, the parser yields the accepted character.
@end defun

@defun $none-of cset
@c MOD parser.peg
Returns a parser that accepts any character not in the character set @var{cset}.
On success, the parser yields the accepted character.
@end defun

@defun $any
@c MOD parser.peg
Returns a parser that matches any one item, and yields the matched
input item on success.
It fails only when the input already reached at the end.
@end defun

@defun $eos
@c MOD parser.peg
Stands for ``end of stream''.  Returns a parser that matches
the end of input.  It never consumes input.
@end defun


@defmac $match1 pattern result
@defmacx $match1 pattern
@defmacx $match1 pattern (@code{=>} fail) result
@defmacx $match1* pattern result
@defmacx $match1* pattern
@defmacx $match1* pattern (@code{=>} fail) result
@c MOD parser.peg
The pattern matcher macro @code{match-let1} lifted to the parser.
@xref{Pattern matching}, for the details of supported @var{pattern}.

The macro @code{$match1} returns a parser that takes one item
from the input stream, and see if it matches @var{pattern}.
If it matches, evaluate @var{result} within an environment
where pattern variables are bound to matched content, and the
parser yields the value of @var{result}.  If the input doesn't
match @var{pattern}, or the input is empty, the parser fails without
consuming input.

In the third form @code{=>} must be a literal identifier and @var{fail}
must be an identifier.  The identifier @var{fail} is bound to a procedure
that takes one string argument in @var{result}.  You can call @var{fail}
at the tail position of @var{result} to make the match fail, with
the passed argument as the message.  If @var{fail} is called,
no input will be consumed.

(NB: The @code{match} macro in @code{util.match} has a similar feature,
but it binds @var{fail} to a continuation that abandons the current match
clause and go to try the next pattern.  In @code{$match1}, @var{fail}
is simply a procedure, so you have to call it at the tail position
to make it work.)

The macro @code{$match1*} is similar to @code{$match1}, except
the entire input is matched @var{pattern}.   It is useful to
look into several items in input, instead of just one.
Note that if you give a pattern that consumes arbitrary length
of input (e.g. @code{($match1* (a ...))}, it will consume entire
input.

These macros especially come handy when you have a token stream
generated by a separate lexer---each token can have some structure
(instead of just a character) and you can take advantage of @code{match}.
@end defmac



@node PEG ropes, PEG choice, PEG primitive parser builders, PEG parser combinators
@subsection Ropes

Often you want to construct a string out of the results of other parsers.
It can be costly to construct strings eagerly, for a string may be
just an intermediate one to be a part of a larger string.  We provide
a lightweight lazily string construction mechanism, called ropes.

A rope is either a character, a string or a pair of ropes.  It allows
O(1) concatenation.  A rope becomes a string when @emph{finalized}.
The parser drivers such as @code{peg-run-parser} automatically finalizes
ropes in the parser result.

@defun $->rope parser @dots{}
@c MOD parser.peg
The parsers must yield either a character, a string, a rope,
or @code{#f} or @code{()}.  This procedure
returns a parser that matches @var{parser} @dots{}, then gather the
result into a rope.  @code{#f} and @code{()} in the results are ignored.
@end defun

@defun $->string parser @dots{}
@c MOD parser.peg
This is a common idiom of @code{($lift rope->string ($->rope parser @dots{}))}.
@end defun

@defun $->symbol parser @dots{}
@c MOD parser.peg
Like @code{$->string}, but yields a symbol rather than a string.
@end defun

@defun rope->string rope
@c MOD parser.peg
Converts a rope to a string.
@end defun

@defun rope-finalize obj
@c MOD parser.peg
Converts any ropes in in @var{obj} into strings.
@end defun


@node PEG choice, PEG sequencing combinators, PEG ropes, PEG parser combinators
@subsection Choice, backtrack and assertion combinators

@defun $or p1 p2 @dots{}
@c MOD parser.peg
Returns a choice parser.  Tries the given parser in order on input.
If one succeeds, immediately yields its result.
If one fails, and does not consume input, then tries the next one.
If one fails with consuming input, immediately fails.

If @var{p1} @var{p2} @dots{} don't share the same prefix
to match, you can let it fail as soon as one parser fails with consuming
input.   If more than one parsers do match the same prefix,
you want to wrap them with @code{$try} except the last one.
@end defun

@defun $try p
@c MOD parser.peg
Returns a parser that accepts the same input
the parser @var{p} accepts, but when @var{p} fails
the returned parser doesn't consume input.  Used with @code{$or},
you can explicitly implement a backtrack behavior.
@end defun

@defun $optional p :optional fallback
@c MOD parser.peg
Returns a parser that tries @var{p} on the input.
If it succeeds, yielding its result.  If it fails,
it still succeeds, yielding @var{fallback} as the result.

This is atomic; if @var{p} fails, it doesn't consume input.
@end defun

@defun $assert p
@c MOD parser.peg
Returns a parser that accepts the same input as @var{p}
and returns its result on success, but never consumes the input.
It can be used as a lookahead assertion.
@end defun

@defun $not p
@c MOD parser.peg
Returns a parser that succeeds when @var{p} fails, and that fails
when @var{p} succeeds.  When @var{p} succeeds, it yields an
``unexpected'' error.  It never consumes input in either way.
It can be used as a negative lookahead assertion.
@end defun

@defun $expect p msg-string
@c MOD parser.peg
Returns a parser that calls a parser @var{p}, and if it succeeds
yields its result.  If @var{p} fails, fails with an error message
that says expecting @var{msg-string}.
Useful to produce user-friendly error messages.
@end defun


@node PEG sequencing combinators, PEG repetition combinators, PEG choice, PEG parser combinators
@subsection Sequencing combinators

@defun $seq p1 p2 @dots{}
@defunx $seq0 p1 p2 @dots{}
@c MOD parser.peg
Matches @var{p1}, @var{p2}, @dots{} sequentially.  When all the parser
succeeds, @code{$seq} returns
the last result, while @var{$seq0} returns the first result.
Fails immediately when one of the parsers fails.
@end defun

@defun $between p1 p2 p3
@c MOD parser.peg
Matches @var{p1}, @var{p2} and @var{p3} sequentially, and returns
the result of @var{p2}.
@end defun

@defun $bind p f
@c MOD parser.peg
The basic block of parser combinators;
@var{p} argument is a parser, and @var{f} is a procedure
that takes a Scheme value and returns a parser.

Returns a parser that first applies @var{p} on the input, and if
it succeeds, calls @var{f} with the result of @var{p}, and applies
the returned parser on the subsequent input.

This combinator, along with @code{$return} and @code{$fail},
composes a MonadFail interface as in Haskell.  Theoretically any
combinators can be built on top of these three.  In practice, 
however, it is not always easy to build things directly on top
of @code{$bind}, and more high-level forms such as @code{$let},
@code{$let*} and @code{$lift} are frequently used.
@end defun


@defmac $let (binding @dots{}) body @dots{}
@defmacx $let* (binding @dots{}) body @dots{}
@c MOD parser.peg
Monadic binding form.  Each @var{binding} can be one of the
following forms:

@table @code
@item (var parser)
Run the @var{parser}, and if it succeeds, bind its result to a variable
@var{var}.  If it fails, the entire @code{$let} or @code{$let*} immdiately
fails.

@item (parser)
The variable is omitted.  The @var{parser} is run, and if it succeeds,
its result is discarded and the next binding or body is evaluated.
If it fails, the entire @code{$let} or @code{$let*} immdiately fails.

@item parser
Same as above.  This form can only be used if @var{parser} is just
a vairable reference.
@end table

Once all the parsers in @var{binding} @dots{} succeeds, @var{body} @dots{}
are evaluated in the environment where @var{var} in bindings are bound
to the parser results.  The last expression of @var{body} must return
a parser.

Unlike @code{let}, the parsers in @var{binding} @dots{} are always applied
to the input sequentially.  The difference of @code{$let} and
@code{$let*} is the scope.  With @code{$let*}, the variables bound
in earlier @var{binding} can be used to consturct the @var{parser} later.

This means @code{$let} can evaluate all the parsers beforehand, while
@code{$let*} may need to construct parsers at the time of processing
input.  Creating a parser involves closure allocations, so you want
to use @code{$let} whenever possible.

Note: @code{$let*} is similar to Haskell's @code{do} construct.  We chose
the name @code{$let} and @code{$let*}, for it is easier to see it's
a binding form, and also Scheme already uses @code{do} for
loop construct.
@end defmac

@defun $lift f p @dots{}
@defunx $lift* f p @dots{}
@c MOD parser.peg
Lifts a procedure @var{f} onto the parsers' world.

In a pseudo type declaration, @code{lift}'s type can be understood
as follows:
@example
lift :: (a b ... -> z) (Parser a) (Parser b) ... -> (Parser z)
@end example

That is, @code{lift} creates a parser such that
it first applies parsers on the input, and if all of them succeeds,
it calls @var{f} with the parsers' results as arguments,
and the return value of @var{f} becomes the whole parser's result.

In other words, the following equivalence holds:
@example
($lift f p0 p1 @dots{})
 @equiv{} ($let ([r0a p0] [r1 p1] @dots{}) ($return (f r0 r1 @dots{})))
@end example

It is sometimes simpler to use @code{$lift} instead of @code{$let}.  
For example, the following code creates a parser that matches
input with @var{p0} @var{p1} @dots{} sequentially, then yields
the list of the parser results:

@example
($lift list p0 p1 @dots{})
@end example

Note that after all the parsers succeeds, the whole parser is
destined to succeed---the procedure @var{f} can't make the parser
fail.  If you need to fail after all the parsers succeeds, use @code{$let}
or @code{$let}.
@end defun

@defun $fold-parsers proc seed ps
@c MOD parser.peg
@var{Ps} is a list of parsers.  Apply those parsers sequentially
on the input, passing around the seed value.  That is, if we let
@code{v0}, @var{v1} @dots{} @var{vn} be the result of each parsers in @var{ps},
it returns @code{(proc vn (... (proc v2 (proc v1 seed))...))}.

If any of the parser in @var{ps} fails, @code{$fold-parsers} fails at
that point.

Conceptually, it can be written as follows:

@example
(define ($fold-parsers proc seed ps)
  (if (null? ps)
    ($return seed)
    ($let ([v (car ps)])
      ($fold-parsers proc (proc v seed) (cdr ps)))))
@end example

But we use more efficient implementation.
@end defun

@defun $fold-parsers-right proc seed ps
@c MOD parser.peg
Similar to @code{$fold-parsers}, but the folding by @var{proc}
right to left.  That is, if we let
@code{v0}, @var{v1} @dots{} @var{vn} be the result of each parsers in @var{ps},
it returns @code{(proc v1 (proc v2 (... (proc vn seed)...)))}.

If any of the parser in @var{ps} fails, @code{$fold-parsers-right} fails at
that point.
@end defun


@node PEG repetition combinators, PEG miscellaneous combinators, PEG sequencing combinators, PEG parser combinators
@subsection Repetition combinators


@defun $many p :optional min max
@defunx $many_ p :optional min max
@c MOD parser.peg
Without optional arguments, returns
a parser that accepts zero or more repetition of @var{p}.
On success, @code{$many} yields a list of mached results,
while @var{$many_} doesn't keep the results (and faster).

Optinoal @var{min} and @var{max} must be nonnegative integers
and limit the number of occurrences of @var{p}. The numbers are inclusive.
For example,
@code{($many ($. #\a) 3)} accepts three or more @code{#\a}'s,
and @code{($many ($. #\a) 2 4)} accepts @code{aa}, @code{aaa} and
@code{aaaa}.

Note that @code{$many} may fail if the input partially matches
@code{p}.

@example
(peg-parse-string ($many ($seq ($. #\a) ($. #\b))) "ababcd")
  @result{} (#\b #\b)
  
(peg-parse-string ($many ($seq ($. #\a) ($. #\b))) "ababac")
  @result{} *** PARSE-ERROR: expecting #\b at 5, but got #\c
@end example

If you want to stop @code{$many} at the first two occurrences
in the latter case, use @code{$try}:

@example
(peg-parse-string ($many ($try ($seq ($. #\a) ($. #\b)))) "ababac")
  @result{} (#\b #\b)
@end example
@end defun

@defun $many1 p :optional max
@defunx $many1_ p :optional max
@c MOD parser.peg
Returns a parser that accepts one or more occurences of @var{p}.
On success, @code{$many1} yields a list of results of @var{p},
while @var{$many_} discards the results of @var{p} and faster.
If @var{max} is given, it specifies the maximum number of matches.

Same as @code{($many p 1 max)} and @code{($many_ p 1 max)}.
Provided as a common pattern.
@end defun

@defun $repeat p n
@defunx $repeat_ p n
@c MOD parser.peg
Returns a parser that accepts exaclty @var{n} occurences of @var{p}.
On success, @code{$repeat} yields a list of results of @var{p},
while @var{$repeat_} discards the results of @var{p} and faster.

Same as @code{($many p n n)} and @code{($many_ p n n)}.
Provided as a common pattern.
@end defun

@defun $many-till p pe :optional min max
@defunx $many-till_ p pe :optional min max
@c MOD parser.peg
Returns a parser that accepts repetition of @var{p}, until it
sees input that accepts @var{pe}.
On success, @code{$many-till} yields a list of results of @var{p},
while @var{$many-till_} discards the results of @var{p} and faster.

@example
(define comment ($seq ($.";") ($many-till ($any) ($."\n"))))
@end example
@end defun

@defun $sep-by p psep :optional min max
@defunx $end-by p psep :optional min max
@defunx $sep-end-by p psep :optional min max
@c MOD parser.peg
These combinators match repetition of @var{p} separated by @var{psep},
such as comma-separated values.
Returns the list of results of @var{p}.
Optional @var{min} and @var{max} are integers that limits the
number of repetitions.

These three differ only on treatment of the last separator; @code{$sep-by}
accepts strictly infix syntax, that is, the input must not end
with the separator; while @code{$end-by} accepts strictly suffix syntax,
that is, the input must end with the separator; @code{$sep-end-by}
makes the last separator optional.
@end defun

@defun $chain-left p op
@defunx $chain-right p op
@c MOD parser.peg
Returns a parser that parsers left-assosiative and right-associative operators,
respectively.

The term of expression is parsed by a parser @var{p}, and the
operator is parsed by @var{op}.
@end defun

@node PEG miscellaneous combinators, PEG performance tips, PEG repetition combinators, PEG parser combinators
@subsection Miscellaneous combinators

@defmac $parameterize ((param expr) @dots{}) parser @dots{}
@c MOD parser.peg
Returns a parser that runs @var{parser} @dots{}, while altering
the parameter values of @var{param} @dots{} with the reuslt of
@var{expr} @dots{}, like @code{parameterize}.
The @var{parser} @dots{} are run as if in @code{$seq}, so only the value
of them is returned on success.

You can't use ordinary @code{parameterize}, since such parameterization
takes effect on parser construction time, and not when the parser
parsing the input.
@end defmac

@defun $debug name p
@c MOD parser.peg
Parses the same input as @var{p}, but reports when it is parsing
the input, and the result, just like @code{debug-print}.

You can't use @code{debug-print} directly, for it will take effect
on the parser construction time, not when the input is parsed.
@end defun

@defmac $lazy p
@c MOD parser.peg
Returns a parser that works the same as @var{p}, but delays evaluation
of @var{p} until needed.  It is useful when you define mutually
recursive parsers.
@end defmac



@node PEG performance tips,  , PEG miscellaneous combinators, PEG parser combinators
@subsection Performance



@c ----------------------------------------------------------------------
@node RFC822 message parsing, Base64 encoding/decoding, PEG parser combinators, Library modules - Utilities
@section @code{rfc.822} - RFC822 message parsing
@c NODE RFC822メッセージ形式, @code{rfc.822} - RFC822メッセージ形式

@deftp {Module} rfc.822
@mdindex rfc.822
@c EN
Defines a set of functions that parses and constructs the ``Internet
Message Format'', a text format used to exchange e-mails.
The most recent specification can be found in
RFC5322.
The format was originally defined in RFC 822, and people still
call it ``RFC822 format'', hence I named this module.
In the following document, I also refer to the format as ``RFC822 format''.
@c JP
電子メールを交換する際に使用されるテキストのフォーマットである、``インターネット・
メッセージ・フォーマット''をパーズ/生成する手続きを定義しています。
最新の仕様は、RFC5322にあります。
このフォーマットは最初 RFC 822 で定義されたため、未だに``RFC822形式''と
呼ばれています。それがこのモジュール名の由来です。
以下では、このフォーマットを``RFC822形式''と呼びます。
@c COMMON
@end deftp

@c EN
@subheading Parsing message headers
@c JP
@subheading メッセージヘッダのパーズ
@c COMMON

@defun rfc822-read-headers iport :key strict? reader
@c MOD rfc.822
@c EN
Reads RFC822 format message from an input port @var{iport},
until it reaches the end of the message header.
The header fields are broken into a list of the following
format:
@c JP
入力ポート @var{iport} から、メッセージ・ヘッダの終わりに達するまで、
RFC822 形式のメッセージを読み込みます。
ヘッダ・フィールドは以下のフォーマットのリストに展開、分離されます。
@c COMMON
@example
((name body) @dots{})
@end example
@c EN
@var{Name} @dots{} are the field names, and @var{body} @dots{} are
the corresponding field body, both as strings.
Field names are converted to lower-case characters.
Field bodies are not modified, except the folded line is unfolded.
The order of fields are preserved.
@c JP
@var{Name} @dots{} はフィールド名で、@var{body} @dots{} は対応するフィールドの
ボディ、ともに文字列です。
フィールド名は小文字に変換されます。フィールドのボディは、行折り返しが
取り除かれる以外は変更されません。
フィールドの順番は保存されます。
@c COMMON

@c EN
By default, the parser works permissively.  If EOF is encountered
during parsing header, it is taken as the end of the message.
And if a line that doesn't consist neither continuing (folded) line
nor start a new header field, it is simply ignored.
You can change this behavior by giving true value to
the keyword argument @var{strict?}; then the parser raises an error
for such a malformed header.

The keyword argument @var{reader} takes a procedure that reads
a line from @var{iport}.  Its default is @code{read-line}, which
should be enough for most cases.
@c JP
デフォルトでは、パーザの動作は寛容です。ヘッダをパーズ中に EOF に
出会うとそれをメッセージの終端とみなします。継続(折り返し)行でもなく、
新しいヘッダフィールドの始端でもない行は無視します。このふるまいは
キーワード引数 @var{strict?} に真の値を渡すことで変更することができます。
真を渡すと、このような不正な形式のヘッダに対してエラーを発生させるように
なります。

キーワード引数 @var{reader} は @var{iport} から一行読み込む手続きを
とります。デフォルトは @code{read-line} です。ほとんどの場合これで
十分のはずです。
@c COMMON
@end defun

@defun rfc822-header->list iport :key strict? reader
@c MOD rfc.822
@c EN
This is an old name of @code{rfc822-read-headers}.  This is kept
for the backward compatibility.  The new code should use
@code{rfc822-read-headers} instead.
@c JP
これは@code{rfc822-read-headers}の古い名前です。
互換性のために残してありますが、新しいコードは
@code{rfc822-read-headers}を使って下さい。
@c COMMON
@end defun


@defun rfc822-header-ref header-list field-name :optional default
@c MOD rfc.822
@c EN
An utility procedure to get a specific field from the parsed
header list, which is returned by @code{rfc822-read-headers}.

@var{Field-name} specifies the field name in a lowercase string.
If the field with given name is in @var{header-list}, the procedure
returns its value in a string.  Otherwise, if @var{default} is given,
it is returned, and if not, @code{#f} is returned.

This procedure can actually be used not only for the result of
@code{rfc822-read-headers}, but for retrieving a value keyed
by strings in a list-of-list structure: @code{((name value option ...) ...)}.
For example, the return value of @code{parse-cookie-string}
can be passed to @code{rfc-822-header-ref} 
(@pxref{HTTP cookie handling}, for @code{parse-cookie-string}).
@c JP
@code{rfc822-read-headers} が返すパーズ済みのヘッダリストから
特定のフィールドを得るためのユーティリティ手続きです。

@var{Field-name} は小文字の文字列でフィールド名を指定します。
与えられた名前をもつフィールドが @var{header-list} 中にあれば、
その値を文字列で返します。そうでない場合、もし @var{default} が
与えられていればそれが返り、与えられていなければ @code{#f} が返されます。

この手続きは@code{rfc822-read-headers}の結果だけでなく、
文字列をキーにしたリストのリスト @code{((name value option ...) ...)}
という構造からvalue部分を取り出すのに使えます。
例えば@code{parse-cookie-string}の結果を@code{rfc-822-header-ref}に渡せます。
(@code{parse-cookie-string}については@pxref{HTTP cookie handling}参照。)
@c COMMON

@example
(rfc822-header-ref 
  '(("from" "foo@@example.com") ("to" "bar@@example.com"))
  "from")
 @result{} "foo@@example.com"

;; If no entry matches, #f is returned by default
(rfc822-header-ref 
  '(("from" "foo@@example.com") ("to" "bar@@example.com"))
  "reply-to")
 @result{} #f

;; You can give the default value for no-match case
(rfc822-header-ref 
  '(("from" "foo@@example.com") ("to" "bar@@example.com"))
  "reply-to" 'none)
 @result{} none

;; By giving the default value, you can distinguish
;; the no-match case and there's actually an entry with value #f.
(rfc822-header-ref 
  '(("from" "foo@@example.com") ("reply-to" #f))
  "reply-to" 'none)
 @result{} #f
@end example
@end defun

@c EN
@subheading Basic field parsers
@c JP
@subheading 基本的なフィールドパーザ
@c COMMON

@c EN
Several procedures are provided to parse "structured" header fields
of RFC2822 messages.  These procedures deal with the body of
a header field, i.e. if the header field is
"@code{To: Wandering Schemer <schemer@@example.com>}",
they parse "@code{Wandering Schemer <schemer@@example.com>}".

Most of procedures take an input port.  Usually you first parse
the entire header fields by @code{rfc822-read-headers},
obtain the body of the header by @code{rfc822-header-ref},
then open an input string port for the body and use those
procedures to parse them.

The reason for this complexity is because you need
different tokenization schemes depending on the type of the field.
Rfc2822 also allows comments to appear between tokens for most cases,
so a simple-minded regexp won't do the job,
since rfc2822 comment can be nested
and can't be represented by regular grammar.
So, this layer of procedures are designed flexible enough
to handle various syntaxes.  For the standard header types,
high-level parsers are also provided; see "specific field parsers" below.
@c JP
RFC2822メッセージの「構造化」されたヘッダフィールドをパーズするために、
いくつかの手続きが提供されています。これらの手続きはヘッダフィールドの
本体部を処理します。たとえば、ヘッダフィールドが、
"@code{To: Wandering Schemer <schemer@@example.com>}" であれば、これらの
手続きは "@code{Wandering Schemer <schemer@@example.com>}" をパーズします。

ほとんどの手続きは入力ポートを引数にとります。通常は最初に、ヘッダフィールド
全部を @code{rfc822-read-headers} でパーズし、ヘッダの本体を
@code{rfc822-header-ref} で取得してから、その本体用に入力文字列ポートを
オープンして、それをこれらの手続きを用いてパーズします。

このように複雑になっているのは、フィールドのタイプによって別々の
トークン化スキームが必要になるからです。RFC2822 では多くの場合
トークン間にコメントがあらわれことを許しているので、初心な正規表現では
うまくいきません。RFC2822 のコメントはネスト可能で、正規表現では表現
しきれないからです。
そういうわけで、このレイヤの手続きは、いろいろな構文に対応できるよう
十分な柔軟性があるように設計されています。標準的なタイプのヘッダについては
高水準のパーザも提供されています。後述の「特定フィールド用パーザ」を
参照してください。
@c COMMON

@defun rfc822-next-token iport :optional tokenizer-specs
@c MOD rfc.822
@c EN
A basic tokenizer.  First it skips whitespaces and/or
comments (@code{CFWS}) from @var{iport}, if any.  Then
reads one token according to @var{tokenizer-specs}.  If @var{iport}
reaches EOF before any token is read, EOF is returned.

@var{Tokenizer-specs} is a list of tokenizer spec, which is
either a char-set or a cons of a char-set and a procedure.

After skipping @code{CFWS}, the procedure peeks a character
at the head of @var{iport}, and checks it
against the char-sets in @var{tokenizer-specs} one by one.
If a char-set that contains the character belongs to is found,
then a token is retrieved as follows:
If the tokenizer spec is just a char-set, a sequence of characters
that belong to the char-set consists a token.
If it is a cons, the procedure is called with @var{iport} to
read a token.

If the head character doesn't match any char-sets,
the character is taken from @var{iport} and returned.

The default @var{tokenizer-specs} is as follows:
@c JP
基本的なトークナイザです。まず、もしあれば、白空白および/または
コメント (@code{CFWS}) を @var{iport} から読み飛ばします。それから、
@var{tokenizer-specs} にしたがってトークンをひとつ読み込みます。
トークンを読み込む前に、@var{iport} が EOF に到達したら、EOF が
返されます。

@var{tokenizer-specs} はトークナイザ仕様のリストです。
トークナイザ仕様は、文字集合または文字集合と手続きのペアのどちらかです。

@code{CFWS} を読み飛ばしたあと、この手続きは @var{iport} の先頭の一文字
を見て、@var{tokenizer-specs} のひとつひとつに対してチェックします。
その文字が含まれている文字集合がみつかれば、トークンを次のようにして
引き出します。トークナイザ仕様が文字集合だけの場合、その文字集合に
属している文字の並びがトークンを構成します。トークナイザ仕様が文字集合と
手続きのペアだったら、その手続きを @var{iport} とともに呼びだし、
トークンを読み込みます。

もし、先頭の文字がどの文字集合ともマッチしなければ、その文字が
@var{iport} から取り出され、それが返されます。

デフォルトの @var{tokenizer-specs} は以下のようになっています。
@c COMMON
@example
(list (cons #["] rfc822-quoted-string)
      (cons *rfc822-atext-chars* rfc822-dot-atom))
@end example
@c EN
Where @code{rfc822-quoted-string} and @code{rfc822-dot-atom}
are tokenizer procedures described below, and @code{*rfc822-atext-chars*}
is bound to a char-set of @code{atext} specified in rfc2822.
This means @code{rfc822-next-token} retrieves a token
either @code{quoted-string} or @code{dot-atom} specified in rfc2822
by default.

Using @var{tokenizer-specs}, you can customize how the header
field is parsed.  For example, if you want to retrieve a token
that is either (1) a word constructed by alphabetic characters, or
(2) a quoted string, then you can call @code{rfc822-next-token}
by this:
@c JP
ここで @code{rfc822-quoted-string} および @code{rfc822-dot-atom} は
後述するトークナイザ手続きで、@code{*rfc822-atext-chars*} は RFC2822 で
規定された @code{atext} の文字集合に束縛されています。
つまり、@code{rfc822-next-token} はデフォルトでは RFC2822 で規定された
@code{quoted-string} あるいは @code{dot-atom} のトークンを引き出します。

@var{tokenizer-specs} をつかって、ヘッダフィールドのパーズ方法を
カスタマイズすることができます。たとえば、(1) 英字で構成された単語、または
(2) クウォート文字列、のトークンを取り出したいときには、
@code{rfc822-next-token} をこんなふうに呼べます。
@c COMMON

@example
(rfc822-next-token iport
   `(#[[:alpha:]] (#["] . ,rfc822-quoted-string)))
@end example
@end defun

@defun rfc822-field->tokens field :optional tokenizer-specs
@c MOD rfc.822
@c EN
A convenience procedure.  Creates an input string port for
a field body @var{field}, and calls @code{rfc822-next-token}
repeatedly on it until it consumes all input, then returns
a list of tokens.   @var{Tokenizer-specs} is passed to
@code{rfc822-next-token}.
@c JP
これは便利関数です。フィールド本体 @var{field} に対応する入力文字列ポート
を生成し、それに対して、@code{rfc822-next-token} を全入力を消費するまで、
繰り返しよび、トークンのリストを返します。@var{Tokenizer-specs} は、
@code{rfc822-next-token} に渡されます。
@c COMMON
@end defun

@defun rfc822-skip-cfws iport
@c MOD rfc.822
@c EN
A utility procedure that consumes any comments and/or whitespace
characters from @var{iport}, and returns the head character
that is neither a whitespace nor a comment.  The returned character
remains in @var{iport}.
@c JP
@var{iport} から、すべてのコメントおよび/または白空白文字を消費し、
白空白でもコメントでもない、先頭の文字を返します。返された文字は、
@var{iport}に残ります。
@c COMMON
@end defun

@defvr {Constant} *rfc822-atext-chars*
@c MOD rfc.822
@c EN
Bound to a char-set that is a valid constituent of @code{atom}.
@c JP
@code{atom} を構成する有効な文字集合に束縛されています。
@c COMMON
@end defvr

@defvr {Constant} *rfc822-standard-tokenizers*
@c MOD rfc.822
@c EN
Bound to the default @var{tokenizer-specs}.
@c JP
デフォルトの @var{tokenizer-specs} に束縛されています。
@c COMMON
@end defvr

@defun rfc822-atom iport
@defunx rfc822-dot-atom iport
@defunx rfc822-quoted-string iport
@c MOD rfc.822
@c EN
Tokenizers for @code{atom}, @code{dot-atom} and @code{quoted-string},
respectively.  The double-quotes and escaping backslashes within
@code{quoted-string} are removed by @code{rfc822-quoted-string}.
@c JP
それぞれ、@code{atom}、@code{dot-atom} および @code{quoted-string} に
対応するトークナイザです。@code{quoted-string} 中の二重引用符および
エスケープのためのバックスラッシュは @code{rfc822-quoted-string} に
よって取り除かれます。
@c COMMON
@end defun

@c EN
@subheading Specific field parsers
@c JP
@subheading 特定フィールド用パーザ
@c COMMON

@defun rfc822-parse-date string
@c MOD rfc.822
@c EN
Takes RFC-822 type date string, and returns eight values:
@c JP
RFC822 形式の日付文字列を取り、8つの値を返します。
@c COMMON
@example
year, month, day-of-month, hour, minutes, seconds, timezone,
day-of-week.
@end example

@c EN
@emph{Timezone} is an offset from UT in minutes.
@emph{Day-of-week} is a day from sunday,
and may be #f if that information is not available.
@emph{Month} is an integer between 1 and 12, inclusive.
If the string is not parsable, all the elements are #f.
@c JP
@emph{timezone} は UT(グリニッジ標準時)からの分単位のオフセットです。
@emph{day-of-week} は日曜日から数えた曜日で、情報が不足している場合は #f です。
@emph{month}は1から12までの整数です。
文字列がパーズ不可能ならば、全ての要素が #f になります。
@c COMMON
@end defun

@defun rfc822-date->date string
@c MOD rfc.822
@c EN
Parses RFC822 type date format and returns SRFI-19 @code{<date>} object
(see @ref{SRFI-19 Date}).  If @var{string} can't be parsed,
returns @code{#f} instead.

To construct rfc822 date string from SRFI-19 date, you can use
@code{date->rfc822-date} below.
@c JP
RFC822形式の日付フォーマットをパーズし、SRFI-19 の @code{<date>} オブジェクト
(@ref{SRFI-19 Date} 参照) を返します。@var{string} がパーズできないときは
かわりに @code{#f} を返します。

SRFI-19の日付からRFC822形式の日付文字列を作成するには、
後で述べる@code{date->rfc822-date}が使えます。
@c COMMON
@end defun

@c EN
@subheading Message constructors
@c JP
@subheading メッセージの構築
@c COMMON

@defun rfc822-write-headers headers :key output continue check
@c MOD rfc.822
This is a sort of inverse function of @code{rfc822-read-headers}.
It receives a list of header data, in which each header data
consists of @code{(<name> <body>)}, and writes them out in RFC822 header
field format to the output port specified by the @var{output} keyword
argument.  The default output is the current output port.

By default, the procedure assumes @var{headers} contains all the
header fields, and adds an empty line in the end of output
to indicate the end of the header.  You can pass a true value to
the @var{continue} keyword argument to prevent this, enabling
more headers can be added later.

I said ``a sort of'' above.  That's because this function doesn't
(and can't) do the exact inverse.
Specifically, the caller is responsible for line folding and
make sure each header line doesn't exceed the ``hard limit'' defined
by RFC2822 (998 octets).  This procedure cannot do the line
folding on behalf of the caller, because the places where
line folding is possible depend on the semantics of each
header field.

It is also the caller's responsibility to make sure header
field bodies don't have any characters except non-NUL US-ASCII
characters.  If you want to include characters outside of that
range, you should convert them in the way allowed by the
protocol, e.g. MIME.  The @code{rfc.mime} module
(@pxref{MIME message handling}) provides a convenience procedure
@code{mime-encode-text} for such purpose.
Again, this procedure cannot do the encoding automatically,
since the way the field
should be encoded depends on header fields.

What this procedure can do is to check and report such violations.
By default, it runs several checks and signals an error if it finds any
violations of RFC2822.  You can control this checking behavior
by the @var{check} keyword argument.  It can take one of the
following values:

@table @code
@item :error
Default.  Signals an error if a violation is found.
@item #f, :ignore
Doesn't perform any check.  Trust the caller.
@item @var{procedure}
When @code{rfc822-write-headers} finds a violation, the procedure
is called with three arguments; the header field name,
the header field body, and the type of violation explained below.
The procedure may correct the problem and return two values,
the corrected header field name and body.  The returned values
are checked again.  If the procedure returns the
header field name and body unchanged, an error is signaled
in the same way as @code{:error} is specified.
@end table

The third argument passed to the procedure given to the @var{check}
argument is one of the following symbols.  New symbols may be
added in future versions for more checks.

@table @code
@item incomplete-string
Incomplete string is passed.
@item bad-character
Header field contains characters outside of US-ASCII or NUL.
@item line-too-long
Line length exceeds 998 octet limit.
@item stray-crlf
The string contains CR and/or LF character that doesn't consist of
proper line folding.
@end table

@end defun

@defun date->rfc822-date date
@c MOD rfc.822
@c EN
Takes SRFI-19 @code{<date>} object (see @ref{SRFI-19 Date})
and returns a string of its rfc822 date representation.
This is a reverse operation of @code{rfc822-date->date}.
@c JP
SRFI-19の@code{<date>}オブジェクト(@ref{SRFI-19 Date}参照)
を取り、そのrfc822日付形式表現の文字列を返します。
@code{rfc822-date->date}の逆関数です。
@c COMMON
@end defun


@c ----------------------------------------------------------------------
@node Base64 encoding/decoding, HTTP cookie handling, RFC822 message parsing, Library modules - Utilities
@section @code{rfc.base64} - Base64 encoding/decoding
@c NODE Base64エンコーディング, @code{rfc.base64} - Base64エンコーディング

@deftp {Module} rfc.base64
@mdindex rfc.base64
@c EN
This module defines a few functions to encode/decode Base64 format,
defined in RFC 2045 (@uref{https://www.ietf.org/rfc/rfc2045.txt}), section 6.3
and RFC 4648 (@uref{https://www.ietf.org/rfc/rfc4648.txt}).
@c JP
このモジュールでは、RFC 2045 (@uref{https://www.ietf.org/rfc/rfc2045.txt}) の6.3節
およびRFC 4648 (@uref{https://www.ietf.org/rfc/rfc4648.txt}) で
定義されている Base64 フォーマットへエンコード/デコードするいくつかの
手続きを定義しています。
@c COMMON
@end deftp

@defun base64-encode :key line-width url-safe
@c MOD rfc.base64
@c EN
Reads byte stream from the current input port, encodes it in Base64
format and writes the result character stream to the current output port.
The conversion ends when it reads EOF from the current input port.

Newline characters can be inserted to keep the maximum line width to
the value given to the @var{line-width} keyword argument.  The default
value of @var{line-width} is 76, as specified in RFC2045.  You can give
@code{#f} or zero to @var{line-width} to suppress line splitting.
@c JP
現在の入力ポートからバイト・ストリームを読み込み、それを Base64 フォーマットに
エンコードし、現在の出力ポートに文字ストリームとして書き出します。
現在の入力ポートから EOF を読み込むと変換を終了します。

一行あたりの文字数が@var{line-width}に与えられた文字数を越えないように、
改行文字が適切に出力に挿入されます。@var{line-width}のデフォルト値は
RFC2045に従い76となっています。@var{line-width}に@code{#f}または@code{0}
を与えることで改行を抑制することができます。
@c COMMON

@c EN
If a true value is given to @var{url-safe},
the input bytes will be encoded with an
alternative encoding table, which substitutes @code{+} instead of
@code{-} and @code{/} instead of @code{_}. The result will contain
filename and url safe characters only.  Default value of @var{url-safe}
is false.
@c JP
@var{url-safe}に真の値を与えると、標準の Base64 と異なったエンコーディングテーブルを使って
入力をエンコードします。このエンコーディングでは、@code{+}の代わりに
@code{-}が、@code{/}の代わりに@code{_}が使われます。このエンコーディングは
ファイル名やURLの一部として使うのに適しています。@var{url-safe}の
デフォルト値は偽です。
@c COMMON
@end defun

@defun base64-encode-string string :key line-width url-safe
@c MOD rfc.base64
@c EN
Converts contents of @var{string} to Base64 encoded format.
Input string can be either complete or incomplete string;
it is always interpreted as a byte sequence.
@c JP
@var{string} の内容を Base64 でエンコードされたフォーマットに変換します。
入力となる文字列は、完全文字列でも不完全文字列でも良いです。
常にバイト・シーケンスとして扱われます。
@c COMMON
@end defun

@defun base64-decode :key url-safe
@c MOD rfc.base64
@c EN
Reads character stream from the current input port, decodes it from Base64
format and writes the result byte stream to the current output port.
The conversion ends when it reads EOF or the termination character
(@code{=}).  The characters which does not in legal Base64 encoded character
set are silently ignored.
@c JP
現在の入力ポートから文字ストリームを読み込み、それを Base64 フォーマットとして
デコードし、現在の出力ポートにバイトストリームとして書き出します。
変換は EOF か、終端文字 (@code{=}) を読み込むと終了します。
Base64 でエンコードされた文字として適当でない文字は沈黙のまま無視されます。
@c COMMON
@end defun

@defun base64-decode-string string :key url-safe
@c MOD rfc.base64
@c EN
Decodes a Base64 encoded string @var{string} and returns
the result as a string.
The conversion terminates at the end of @var{string} or
the termination character (@code{=}).
The characters which does not in legal Base64 encoded character
set are silently ignored.
@c JP
Base64 でエンコードされた文字列 @var{string} をデコードして文字列を返します。
変換は @var{string} の終わりか、終端文字 (@code{=}) で終了します。
Base64 でエンコードされた文字として適当でない文字は沈黙のまま無視されます。
@c COMMON
@end defun

@c ----------------------------------------------------------------------
@node HTTP cookie handling, FTP, Base64 encoding/decoding, Library modules - Utilities
@section @code{rfc.cookie} - HTTP cookie handling
@c NODE HTTPクッキー, @code{rfc.cookie} - HTTPクッキー

@deftp {Module} rfc.cookie
@mdindex rfc.cookie
@c EN
Defines a set of functions to parse and construct a ``cookie'' information
defined in RFC 6265.
@c JP
RFC 6265で定義されている「クッキー」情報を
パースしたり構築したりするための手続きを定義しています。
@c COMMON
@end deftp

@defun parse-cookie-string string :optional version
@c MOD rfc.cookie
@c EN
Parse a cookie string @var{string}, which is the value of ``Cookie''
request header.  Usually, the same information is available to CGI
program via the environment variable @code{HTTP_COOKIE}.

If the cookie version is known, via ``Cookie2'' request header,
the integer version must be passed to @var{version}.  Otherwise,
@code{parse-cookie-string} figures out the version from @var{string}.

The result has the following format.
@c JP
リクエスト・ヘッダの Cookie の値のクッキー文字列 @var{string} を
パースします。通常、CGI プログラムでは、同じ情報は環境変数
@var{HTTP_COOKIE} を通して利用できます。

リクエスト・ヘッダ Cookie2 を通してクッキーのバージョンが分かる
場合は、@var{version} へ整数のバージョンとして渡されなければなりません。
そうでなければ、@code{parse-cookie-string} は @var{string} からバージョンを
取り出します。

結果は以下のフォーマットを持ちます。
@c COMMON
@example
((<name> <value> [:path <path>] [:domain <domain>] [:port <port>])
 @dots{})
@end example
@c EN
where @var{<name>} is the attribute name, and @var{<value>} is
the corresponding value.  If the attribute doesn't have value,
@var{<value>} is @code{#f}.  (Note that it differs from the attribute
having null value, @code{""}.)
If the attribute has path, domain or port options, it is given
as a form of keyword-value pair.
@c JP
@var{<name>} は属性名で、@var{<value>} は対応する値です。
属性が値を持たない場合、@var{<value>} は @code{#f} になります。
(属性が NULL 値を持つ場合は、@code{""} となることに注意。)
属性がパスやドメイン、ポート番号のオプションを持つ場合は、
キーワード-値のペアの形式で与えられます。
@c COMMON

@c EN
Note: To retrieve the value of a specific cookie conveniently, you can use
@code{rfc822-header-ref} (@pxref{RFC822 message parsing}).
@c JP
註: 特定のクッキーの値を簡単に取り出すには
@code{rfc822-header-ref}が使えます (@ref{RFC822 message parsing}参照)。
@c COMMON
@end defun

@defun construct-cookie-string specs :optional version
@c MOD rfc.cookie
@c EN
Given list of cookie specs, creates a cookie string suitable for
@code{Set-cookie2} or @code{Set-cookie} header.

Optional @var{version} argument specifies cookie protocol version.
0 for the old Netscape style format, and 1 for RFC2965 style format.
When omitted, version 1 is assumed.

Each cookie spec has the following format.
@c JP
与えられたクッキーの仕様のリストから、@code{Set-cookie2} か
@code{Set-cookie} ヘッダに適切なクッキー文字列を作ります。

オプションの @var{version} 引数は、クッキー・プロトコルのバージョンを
指定するものです。0 は古い Netscape スタイルのフォーマットで、1 は
RFC2965 スタイルのフォーマットです。省略された場合、1 が指定されたものと
されます。

クッキーの仕様は以下のフォーマットを持ちます。
@c COMMON
@example
(<name> <value> [:comment <comment>] [:comment-url <url>]
                [:discard <bool>] [:domain <domain>]
                [:max-age <age>] [:path <path>]
                [:port <port-list>] [:secure <bool>] [:http-only <bool>]
                [:version <version>] [:expires <date>])
@end example
@c EN
Where,
@table @code
@item <name>
A string.  Name of the cookie.
@item <value>
Value of the cookie.  May be a string, or @code{#f} if no value is needed.
@item <comment> <url> <domain> <path> <port-list>
Strings.
@item <bool>
Boolean value
@item <age> <version>
Integers
@item <date>
Either an integer (seconds since Epoch) or a formatted date string
following the netscape cookie specification.
@end table
@c JP
@table @code
@item <name>
文字列。クッキーの名前。
@item <value>
クッキーの値。文字列か、値が必要なければ @code{#f} 。
@item <comment> <url> <domain> <path> <port-list>
文字列。
@item <bool>
真偽値。
@item <age> <version>
整数。
@item <date>
整数(エポックからの秒数)か、Netscape のクッキー仕様に従うフォーマットされた
日付文字列。
@end table
@c COMMON

@c EN
The attribute values are quoted appropriately.  If the specified attribute
is irrelevant for the @var{version}, it is ignored.  So you can pass
the same specs to generate both old-style and new-style cookie strings.

Return value is a list of cookie strings, each of which stands for
each cookie.  For old-style protocol (using @code{Set-cookie} header)
you must send each of them by individual header.  For new-style
protocol (using @code{Set-cookie2} header), you can join them
with comma and send it at once.  See RFC6265 for further details.

Some examples:
@c JP
属性値は適切にクォートされます。指定された属性が @var{version} に不適切な
場合は無視されます。古いスタイルと新しいスタイルの両方のクッキー文字列を
作るために同じ仕様を渡すことができます。

戻り値はそれぞれのクッキー文字列のリストです。(@code{Set-cookie} を使う)
古いスタイルのプロトコルでは、それぞれを独立したヘッダとして送らなければ
なりません。(@code{Set-cookie2} ヘッダを使う)新しいプロトコルでは、
それらをカンマで繋ぎ、一度に送ることができます。詳細は RFC6265 を見て下さい。

いくつかの例を示します。
@c COMMON
@example
(construct-cookie-string
   `(("name" "foo" :domain "foo.com" :path "/"
                   :expires ,(+ (sys-time) 86400) :max-age 86400)))
 @result{} ("name=foo;Domain=foo.com;Path=/;Max-age=86400")

(construct-cookie-string
   `(("name" "foo" :domain "foo.com" :path "/"
                   :expires ,(+ (sys-time) 86400) :max-age 86400))
   0)
 @result{}
 ("name=foo;Domain=foo.com;Path=/;Expires=Sun, 09-Sep-2001 01:46:40 GMT")
@end example
@end defun

@c ----------------------------------------------------------------------
@node FTP, HMAC keyed-hashing, HTTP cookie handling, Library modules - Utilities
@section @code{rfc.ftp} - FTP client
@c NODE FTPクライアント, @code{rfc.ftp} - FTPクライアント

@deftp {Module} rfc.ftp
@mdindex rfc.ftp
@c EN
This module provides a set of convenient functions to access ftp
servers.
@c JP
このモジュールはFTPサーバーにアクセスするための便利関数群を提供します。
@c COMMON
@end deftp

@deftp {Class} <ftp-connection>
@clindex ftp-connection
@c MOD rfc.ftp
@c EN
An object to keep FTP connection to a server.  It has the following
public slots.
@c JP
ひとつのサーバーへのFTPコネクションを保持するオブジェクト。以下の公開
スロットがあります。
@c COMMON

@defivar {<ftp-connection>} transfer-type
@c EN
FTP transfer type.  Must be one of the following symbols:
@code{ascii}, @code{binary} (default), and @code{image}.
@c JP
FTPの転送タイプ。以下のシンボルのどれかひとつでなければなりません。
@code{ascii}、@code{binary} (デフォルト)、および@code{image}。
@c COMMON
@end defivar

@defivar {<ftp-connection>} passive
@c EN
True if the client uses passive connection.c
@c JP
パッシブコネクションを使うとき真。
@c COMMON
@end defivar

@defivar {<ftp-connection>} log-drain
@c EN
This slot must hold a @code{<log-drain>} instance (@pxref{User-level logging})
or @code{#f}.  If it has a @code{<log-drain>} instance, ftp communication
logs are put to it.
@c JP
このスロットは@code{<log-drain>}のインスタンス(@ref{User-level logging}参照)
を保持しているかあるいは@code{#f}でなければなりません。@code{<log-drain>}
のインスタンスを保持している場合、FTP通信のログがそこに記録されます。
@c COMMON

@end defivar
@end deftp

@deftp {Condition Type} <ftp-error>
@clindex ftp-error
@c MOD rfc.ftp
@c EN
This type of exception is thrown when the ftp server returns an error code.
Inherits @code{<error>}.  The message field contains the server reply,
including the status code.
@c JP
このタイプの例外はFTPサーバーがエラーコードを返したときに投げられます。
@code{<error>}を継承しています。メッセージフィールドにはステータスコー
ドを含むサーバーからの返答が含まれます。
@c COMMON
@end deftp

@defun call-with-ftp-connection host proc :key passive port username password account log-drain
@c MOD rfc.ftp
@c EN
A high-level convenience routine to open an ftp connection to
an ftp server and calls the given procedure.
@c JP
高水準の便利関数で、ひとつのFTPサーバーへのFTPコネクションをオープンし、
与えられた手続きを呼びます。
@c COMMON

@c EN
The server is specified by @var{host}.  Optionally, you can add user
name and/or port number by the form
@code{@var{user}@@@var{servername}:@var{port}}.
If present, user and port portion in @var{host} supersedes the
keyword arguments.
@c JP
接続するサーバーは@var{host}で指定します。オプションでユーザー名、ポー
ト番号を@code{@var{user}@@@var{servername}:@var{port}}という形式で指定
できます。もしあれば、@var{host}の部分をキーワード引数にすることもでき
ます。
@c COMMON

@c EN
If ftp connection to @var{host} is established successfully,
@var{proc} is called with one argument, which is an instance
of @code{<ftp-connection>}.  When @var{proc} returns,
the connection is closed and the return value(s) of @var{proc}
is/are returned from @code{call-with-ftp-connection}.
When an exception is thrown, the ftp connection is closed
before the exception escapes from @code{call-with-ftp-connection}.
@c JP
@var{host}へのFTPコネクション確立が成功したら、@var{proc}が引数を1つとっ
て呼ばれます。この引数は@code{<ftp-connection>}のインスタンスです。
@var{proc}から返ったときにこのコネクションはクローズされ、@var{proc}の
返り値が@code{call-with-ftp-connection}から返されます。例外がなげられ
たら、その例外が@code{call-with-ftp-connection}から外へでる前にFTPコネ
クションはクローズされます。
@c COMMON

@c EN
When a true value is given to the keyword argument @var{passive},
created ftp connection will use passive mode to send/receive
data.  The default is the active mode.
@c JP
キーワード引数@var{passive}に真値を与えると、FTPコネクションはパッシブ
モードになります。デフォルトではアクティブモードです。
@c COMMON

@c EN
The keyword argument @var{port}, @var{username}, and @var{password}
specify the port number, username, and password, respectively.
When omitted, the port number defaults to 21, @var{username} to
@code{"anonymous"}, and @var{password} to @code{"anonymous@@"}.
Note that the port number and/or username are ignored when
those information is given in the @var{host} argument.
@c JP
キーワード引数@var{port}、@var{username}および@var{password}は
それぞれ、ポート番号、ユーザー名、パスワードを指定するのに使います。
省略された場合のデフォルトは、ポート番号が21,@var{username}が
@code{"anonymous"}、@var{password}が@code{"anonymous@@"}にセットされま
す。ポート番号とユーザー名は@var{host}引数で指定されたものが優先されま
す。
@c COMMON

@c EN
If the keyword argument @var{account} is given, its value
is passed to ftp @code{ACCT} command when requested by
the server at login time.  The default value is a null string @code{""}.
@c JP
キーワード引数@var{account}が与えられた場合には、その値が、ログイン時
にサーバーからの要求でFTPの@code{ACCT}コマンドに渡されます。デフォルト
では空文字列@code{""}です。
@c COMMON

@c EN
The keyword argument @var{log-drain} is set to the created
ftp connection's @code{log-drain} slot.
@c JP
キーワード引数@var{log-drain}が生成したFTPコネクションの
@code{log-drain}スロットに設定されます。
@c COMMON
@end defun

@defun ftp-transfer-type conn
@c MOD rfc.ftp
@c EN
Returns the transfer type of the ftp connection @code{conn}.
Can be used with setter, e.g. @code{(set! (ftp-transfer-type conn) 'ascii)}.
@c JP
指定したFTPコネクション@code{conn}の転送タイプを返します。セッターを適
用することもできます。たとえば、@code{(set! (ftp-transfer-type conn) 'ascii)}
とします。
@c COMMON
@end defun

@defun ftp-passive? conn
@c MOD rfc.ftp
@c EN
Returns true iff ftp connection uses passive data retrieval.
@c JP
指定したFTPコネクションがパッシブモードである場合でその場合に限り真を
返します。
@c COMMON
@end defun

@defun ftp-login host :key passive port username password account log-drain
@c MOD rfc.ftp
@c EN
Connects to the ftp server specified by @var{host}, authenticate the user,
and returns a newly created @code{<ftp-connection>} instance.
This procedure is called implicitly when you use
@code{call-with-ftp-connection}.  The semantics of
the @var{host} argument and the keyword arguments are
the same as @code{call-with-ftp-connection}.
@c JP
@var{host}で指定されたFTPサーバーに接続し、ユーザー認証をすませ、新し
く生成した@code{<ftp-connection>}のインスタンスを返します。この手続き
は@code{call-with-ftp-connection}を使ったときに暗黙の内に呼ばれます。
@var{host}引数およびキーワード引数のセマンティクスは
@code{call-with-ftp-connection}と同じです。
@c COMMON
@end defun

@defun ftp-quit conn
@c MOD rfc.ftp
@c EN
Sends ftp @code{QUIT} command to the connection @var{conn} and
shutdown the connection.
This procedure is called implicitly when you use
@code{call-with-ftp-connection}.
@c JP
FTPの@code{QUIT}コマンドをコネクション@var{conn}に送り、コネクションを
シャットダウンします。この手続きは@code{call-with-ftp-connection}を使っ
たときに暗黙の内に呼ばれます。
@c COMMON

@c EN
Once a connection is shut down, you cannot communicate through
this connection.
@c JP
いったんシャットダウンしたコネクションをつかっての通信はできません。
@c COMMON
@end defun

@defun ftp-chdir conn dirname
@c MOD rfc.ftp
@c EN
Changes the remote directory to @var{dirname}.
@c JP
リモートディレクトリを@var{dirname}に変更します。
@c COMMON
@end defun

@defun ftp-remove conn path
@c MOD rfc.ftp
@c EN
Removes the remote file named by @var{path}.
@c JP
@var{path}で指定したリモートファイルを削除します。
@c COMMON
@end defun

@defun ftp-help conn :optional option @dots{}
@c MOD rfc.ftp
@c EN
Sends ftp @code{HELP} commands.  @var{Option}s must be strings,
and will be passed to the @code{HELP} command arguments.
@c JP
FTPコマンド@code{HELP}を送ります。@var{Option}は文字列でなければなりま
せん。これは@code{HELP}コマンドの引数にわたされます。
@c COMMON
@end defun

@defun ftp-mkdir conn dirname
@c MOD rfc.ftp
@c EN
Creates a directory @var{dirname}.  Returns the created directory
name.
@c JP
ディレクトリ@var{dirname}を作成します。作成されたディレクトリ名が返り
ます。
@c COMMON
@end defun

@defun ftp-current-directory conn
@c MOD rfc.ftp
@c EN
Returns the current remote directory.
@c JP
現在のリモートディレクトリを返します。
@c COMMON
@end defun

@defun ftp-site conn arg
@c MOD rfc.ftp
@c EN
Sends ftp @code{SITE} command with the argument @var{arg}.
The @code{SITE} command's semantics depends on the server.
Returns the server reply.
@c JP
FTPコマンド@code{SITE}を引数@var{arg}とともに送ります。@code{SITE}コマ
ンドのセマンティクスはサーバーに依存します。返り値はサーバーのリプライ
です。
@c COMMON
@end defun

@defun ftp-rmdir conn dirname
@c MOD rfc.ftp
@c EN
Removes remote directory specified by @var{dirname}.
Returns the server reply.
@c JP
@var{dirname}で指定したリモートディレクトリを削除します。返り値はサー
バーのリプライです。
@c COMMON
@end defun

@defun ftp-stat conn :optional pathname
@c MOD rfc.ftp
@c EN
Sends ftp @code{STAT} command to the server.
RFC959 defines several different semantics of this command.
See RFC959 for the details.
Returns the server reply.
@c JP
FTPコマンド@code{STAT}をサーバーに送信します。
RFC959ではこのコマンドのセマンティクスをいくつか定義しています。詳細は
RFC959を見てください。返り値はサーバーのリプライです。
@c COMMON
@end defun

@defun ftp-system conn
@c MOD rfc.ftp
@c EN
Queries the server's operating system by ftp @code{SYST} command.
Returns the server reply without status code.
@c JP
FTPコマンド@code{SYST}をつかってサーバーのオペレーティングシステムを問
合せます。返り値はステータスコードを含まないサーバーのリプライです。
@c COMMON

@example
(call-with-ftp-connection "localhost" ftp-system)
  @result{} "UNIX Type: L8"
@end example
@end defun

@defun ftp-size conn path
@c MOD rfc.ftp
@c EN
Queries the size of the remote file specified by @var{path}.
Returns the integer value.

Note: The size may differ whether the connection is in ascii mode
or binary mode; furthermore, some ftp server may returns the value
only if the connection is in binary mode.  Make sure you have
desired transfer type in the connection.
@c JP
@var{path}で指定したリモートファイルのサイズを問合せます。
整数値が返ります。

註：コネクションがasciiモードかbinaryモードかによって、返されるサイズは
異なるかもしれません。ftpサーバによっては、binaryモードでしか
sizeリクエストに答えないものもあります。この関数を呼ぶ際には、
コネクションに望みのtransfer typeがセットされているようにしてください。
@c COMMON
@end defun

@defun ftp-mdtm conn path
@c MOD rfc.ftp
@c EN
Queries the modification time of the remote file specified by @var{path}.
This function returns the server's reply as is, including the status
code.  Use @code{ftp-mtime} below to obtain a parsed result.
@c JP
@var{path}で指定したリモートファイルの更新時刻を問合せます。この関数は
サーバーからのリプライをステータスコードも含めそのまま返します。解析済
みの結果が欲しいときは後述の@code{ftp-mtime}を使ってください。
@c COMMON
@end defun

@defun ftp-mtime conn path :optional local-time?
@c MOD rfc.ftp
@c EN
Queries the modification time of the remote file specified by @var{path},
and returns the result in a @code{<date>} object
(@pxref{Time data types and procedures}).
If a true value is given to @code{local-time?}, the returned date is
in local time.  Otherwise, the returned date is in UTC.
@c JP
@var{path}で指定したリモートファイルの更新日時を問合せます。結果は
@code{<date>}オブジェクト(@ref{Time data types and procedures}参照)で
返ります。@code{local-time?}が真値に設定されている場合、日付はローカル
時刻で返ります。そうでない場合は日付はUTCです。
@c COMMON
@end defun

@defun ftp-noop conn
@c MOD rfc.ftp
@c EN
Sends ftp @code{NOOP} command and returns the server's reply.
@c JP
FTPコマンド@code{NOOP}を送り、サーバーからのリプライを返します。
@c COMMON
@end defun

@defun ftp-list conn :optional path
@c MOD rfc.ftp
@c EN
Returns the information about the files within the remote file
or directory specified by @var{path}, or the current remote directory,
much like @code{ls(1)} format.  Returns a list of strings, where
each string is for each line of the server's reply.  The exact
format depends on the server.
@c JP
@var{path}で指定されたリモートディレクトリあるいはリモートファイル内の
ファイルに関する情報を返します。@var{path}指定がない場合は現在のリモー
トディレクトリで、結果のフォーマットは@code{ls(1)}のフォーマットと非常
によく似ています。文字列のリストが返り、それぞれの文字列はサーバーのリ
プライの行に対応します。正確なフォーマットについてはサーバーに依存しま
す。
@c COMMON
@end defun

@defun ftp-name-list conn :optional path
@defunx ftp-ls conn :optional path
@c MOD rfc.ftp
@c EN
Return the list of names in the specified @var{path}, or the current
remote directory, without any other information.  @code{ftp-ls}
is just an alias of @code{ftp-name-list} for the convenience.
@c JP
@var{path}で指定したパスもしくは現在のリモートディレクトリにあるファイ
ル名リストを返します。ただし、他の情報は含みません。@code{ftp-ls}は
@code{ftp-name-list}の別名です。便利なので定義してあります。
@c COMMON

@c EN
Note that the server may return an error if there's no files
in the remote directory.
@c JP
リモートディレクトリにファイルが含まれていないときにはサーバーはエラー
を返すことがあることに注意してください。
@c COMMON
@end defun

@defun ftp-get conn path :key sink flusher
@c MOD rfc.ftp
@c EN
Retrieves a remote file @var{path}.  The retrieved data is
sent to an output port given to @var{sink}.  Once all the data
is retrieved, a procedure given to @var{flusher} is called
with the port @var{sink} as an argument, and its return value(s)
is/are returned from @code{ftp-get}.
@c JP
リモートファイル@var{path}を検索します。検索データは@var{sink}で与えら
れた出力ポートに送られます。すべてのデータが検索されたあと、
@var{flusher}で与えられた手続きをポート@var{sink}を引数として呼びます。
返り値は@code{ftp-get}から返されたものです。
@c COMMON

@c EN
The default values of @var{sink} and @var{flusher} are
a newly created string port and @code{get-output-string}, respectively.
That is, @code{ftp-get} returns the retrieved data as a string
by default.
You don't want this behavior if the retrieved file is huge.
@c JP
@var{sink}および@var{flusher}のデフォルト値はそれぞれ、新しく作成され
た文字列ポートと@code{get-output-string}です。すなわち、@code{ftp-get}
はデフォルトでは検索データを文字列として返します。巨大なファイルの場合
このデフォルトの挙動ではありがたくありません。
@c COMMON
@end defun

@defun ftp-put conn from-file :optional to-file
@c MOD rfc.ftp
@c EN
Sends the local file specified by @var{from-file} to the remote
server as the name specified by @var{to-file}.  If @var{to-file}
is omitted, the basename of @var{from-file} is used.
Returns the server response.
@c JP
@var{from-file}で指定したローカルファイルを@var{to-file}で指定した名前
でリモートサーバーに送信します。@var{to-file}が省略された場合にはベー
ス名として@var{from-file}が使われます。返り値はサーバーのレスポンスで
す。
@c COMMON
@end defun

@defun ftp-put-unique conn from-file
@c MOD rfc.ftp
@c EN
Sends the local file specified by @var{from-file} to the
remote server.  The remote side filename is guaranteed to
be unique.  Returns two values---the final server response,
and the remote file name.  The second value can be @code{#f}
if the remote host doesn't support RFC1123 (which must be rare).
@c JP
@var{from-file}で指定したローカルファイルをリモートサーバーへ送信しま
す。リモート側のファイル名重複しないことを保証します。返り値は2つで、
最終的なリモートサーバーからのレスポンスとリモートファイル名です。2つ
めの値は、リモートサーバーがRFC1123をサポートしていない(ほとんどない)
場合に@code{#f}になります。
@c COMMON
@end defun

@defun ftp-rename conn from-name to-name
@c MOD rfc.ftp
@c EN
Renames the remote file specified by @var{from-name} to the
name @var{to-name}.  Returns the final response of the server.
@c JP
@var{from-name}で指定したリモートファイル名を@var{to-name}に変更する。
返り値は最終的なサーバーのレスポンスです。
@c COMMON
@end defun

@c ----------------------------------------------------------------------
@node HMAC keyed-hashing, HTTP, FTP, Library modules - Utilities
@section @code{rfc.hmac} - HMAC keyed-hashing
@c NODE HMAC鍵付きハッシング, @code{rfc.hmac} - HMAC鍵付きハッシング

@deftp {Module} rfc.hmac
@mdindex rfc.hmac
@c EN
This module implements HMAC algorithm,
Keyed-hashing for message authentication, defined in RFC 2104.

For simple batched keyed hashing, you can use high-level API
@code{hmac-digest} and @code{hmac-digest-string}.
Or you can create @code{<hmac>} object and update its state
as the data coming in.
@c JP
このモジュールは、RFC 2104で定義されている、メッセージ認証のための
鍵付きハッシングのHMACアルゴリズムを実装しています。

シンプルなバッチ処理での鍵付きハッシングでは、高レベルなAPIである
@code{hmac-digest}と@code{hmac-digest-string}が使えます。
あるいは、@code{<hmac>}オブジェクトを作成して、入力となるデータで
その状態を更新することもできます。
@c COMMON
@end deftp

@deftp {Class} <hmac>
@clindex hmac
@c MOD rfc.hmac
@c EN
Keeps state information of HMAC algorithm.
Key and the hashing algorithm should be given at the construction
time, using @code{:key} and @code{:hasher} keyword-arguments respectively.
You can pass any class object that implements message digest
interface (@pxref{Message digester framework}),
such as @code{<md5>} (@pxref{MD5 message digest})
or @code{<sha256>} (@pxref{SHA message digest}).

Example:
@c JP
HMACアルゴリズムの状態情報を保持します。
鍵とハッシングアルゴリズムは、キーワード引数@code{:key}と@code{:hasher}を
それぞれ使って、生成時に与えます。
@code{<md5>} (@ref{MD5 message digest}参照)や
@code{<sha256>} (@ref{SHA message digest}参照)などのような
ダイジェストインタフェース(@ref{Message digester framework}参照)を
実装するいかなるクラスオブジェクトを渡すこともできます。

例:
@c COMMON
@example
(make <hmac> :key (make-byte-string 16 #x0b) :hasher <md5>)
@end example
@end deftp

@deffn {Method} hmac-update! (hmac <hmac>) data
@c MOD rfc.hmac
@c EN
Updates the internal state of @var{hmac} by @var{data},
which must be represented by a (possibly incomplete) string.
@c JP
(不完全かもしれない)文字列で表現される@var{data}により、
@var{hmac}の内部状態を更新します。
@c COMMON
@end deffn

@deffn {Method} hmac-final! (hmac <hmac>)
@c MOD rfc.hmac
@c EN
Finalizes the internal state of @var{hmac} and returns the
hashed string in incomplete string.
You can use @code{digest-hexify}
(@pxref{Message digester framework}) to obtain "hexified"
result.
Once finalized, you can't call @code{hmac-update!} or @code{hmac-final!}
on @var{hmac}.
@c JP
@var{hmac}の内部状態を終了させ、不完全文字列でハッシュされた文字列を
返します。
``hexified''(16進化)された結果を得るために、@code{digest-hexify}
(@ref{Message digester framework}参照)を使うことが
できます。
一旦終了されると、@var{hmac}に対しては@code{hmac-update!}や
@code{hmac-final!}を呼ぶことはできません。
@c COMMON
@end deffn

@deffn {Method} hmac-digest :key key hasher
@c MOD rfc.hmac
@c EN
Creates an @code{<hmac>} object and hash the data stream
from the current input port, then returns the hashed result
in an incomplete string.
@c JP
@code{<hmac>}オブジェクトを作り、現在の入力ポートからの
データストリームをハッシュし、不完全文字列でそのハッシュされた
結果を返します。
@c COMMON
@end deffn

@deffn {Method} hmac-digest-string string :key key hasher
@c MOD rfc.hmac
@c EN
Creates an @code{<hmac>} object and hash the data in @var{string},
then returns the hashed result in an incomplete string.
@c JP
@code{<hmac>}オブジェクトを作り、@var{string}にあるデータをハッシュし、
不完全文字列でそのハッシュされた結果を返します。
@c COMMON
@end deffn

@c ----------------------------------------------------------------------
@node HTTP, ICMP packets, HMAC keyed-hashing, Library modules - Utilities
@section @code{rfc.http} - HTTP

@deftp {Module} rfc.http
@mdindex rfc.http
@c EN
This module provides a simple client API for
HTTP/1.1, defined in RFC2616, "Hypertext Transfer Protocol -- HTTP/1.1"
@c JP
このモジュールは、RFC2616 "Hypertext Transfer Protocol -- HTTP/1.1"
で定義されているHTTP/1.1に対する簡単なクライアントAPIを提供します。
@c COMMON
(@uref{https://www.ietf.org/rfc/rfc2616.txt}).

@c EN
Current API implements only a part of the protocol.
It doesn't talk with HTTP/1.0 server yet,
and it doesn't support HTTP/1.1 advanced features
such as persistent connection.
Support for those features may be added in the future versions.
@c JP
現在のAPIは、プロトコルの一部のみ実装されています。
HTTP/1.0のサーバーとはうまく通信できません。
また、HTTP/1.1の先進的機能、例えば永続的接続などはサポートしていません。
これらの機能は、将来のバージョンで追加されるでしょう。
@c COMMON
@end deftp

@deftp {Condition Type} <http-error>
@clindex http-error
@c MOD rfc.http
@c EN
This type of condition is raised when the server terminates
connection prematurely or server's response has invalid
header fields.  Inherits @code{<error>}.
@c JP
サーバから接続が切られた場合や、サーバの返したHTTPレスポンスのフォーマットが
正しくない場合に投げられるコンディションです。@code{<error>}を継承します。
@c COMMON
@end deftp

@defun http-get server request-uri :key sink flusher redirect-handler secure @dots{}
@defunx http-head server request-uri :key redirect-handler secure @dots{}
@defunx http-post server request-uri body :key sink flusher redirect-handler secure @dots{}
@defunx http-put server request-uri body :key sink flusher redirect-handler secure @dots{}
@defunx http-delete server request-uri :key sink flusher redirect-handler secure @dots{}
@c MOD rfc.http
@c EN
Send http GET, HEAD, POST, PUT and DELETE requests to the http @var{server},
respectively, and returns the server's reply.

By default, if the server returns 300, 301, 302, 303, 305 and 307 status,
these procedures attempts to fetch the redirected URL by the
"location" reply message header if it is allowed by RFC2616.
This behavior can be turned off or customized by the @var{redirect-handler}
keyword argument;
see the "keyword arguments" heading below for the details.
@c JP
@var{server}に、それぞれHTTPのGET、HEAD、POST、PUT、DELETEリクエストを送り、
サーバの応答を返します。

デフォルトでは、
サーバがステータスコード 300, 301, 302, 303, 305 の応答を返し、
RFC2616による自動リダイレクトが許されている場合は、
これらの手続きは自動的に応答のメッセージヘッダの "location" で返されるURIに対して
リクエストを再送します。
この動作は@var{redirect-handler}キーワード引数でカスタマイズしたり
抑制したりできます。下の"キーワード引数"を参照してください。
@c COMMON

@c EN
@strong{Required arguments:}
The @var{server} argument specifies http server name in a string.
A server name can be optionally followed by colon and a port number.
You can use IP address, too; for IPv6, you have to surround the
address in brackets.

Additionally, you can specify @code{"unix:/path"} where @code{/path}
is the absolute path to the unix domain socket; this allows to connect
to httpd listening on unix domain sockets.
@c JP
@strong{必須の引数:}
@var{server}引数では、文字列でHTTPサーバ名を指定します。
サーバ名は、オプションでコロンに続いてポート番号を付加できます。
IPアドレスも使えます。IPv6アドレスは角括弧で囲んでください。

また、@code{"unix:/path"}という形式でUnixドメインソケットに接続することもできます。
@code{/path}部分にはソケットへの絶対パスを指定します。
@c COMMON
Examples: @code{"w3c.org"}, @code{"mycompany.com:8080"}, 
@code{"192.168.0.1:8000"}, @code{"[::1]:8000"}

@c EN
The @var{request-uri} argument can be a string or a list.
If it is a string, it's @emph{request-uri} specified in
RFC2616; usually, this is the path part of http url.
The string is passed to the server as is, so the caller must
properly convert character encodings and perform necessary
url encodings.

If @var{request-uri} is a list, it must be in the following form:
@c JP
@var{request-uri}引数は文字列かリストです。
文字列の場合、RFC2616で規定されているリクエストURIと解釈されます。
通常これはHTTP URLのパス部分です。
文字列はそのままサーバに渡されるので、呼び出し側で必要な
文字コード変換やurlエンコーディングを行う必要があります。

@var{request-uri}がリストの場合は、次の形式でなければなりません。
@c COMMON

@example
(@var{path} (@var{name} @var{value}) ...)
@end example

@c EN
Here, @var{path} is a string specifying up to the path component
of the request-uri.
From provided alist of @var{name}s and @var{value}s,
http procedures compose a query string in
@code{application/x-www-form-urlencoded} format
as defined in HTML4, and append it to @var{path}.
For example, the following two requests have the same effect.
Note that url escaping is automatically handled in the second call.
@c JP
ここで@var{path}はリクエストURIのパスコンポーネントまでを指定する
文字列です。与えられた@var{name}と@var{value}のalistから、
httpリクエスト手続きはHTML4で定められた
@code{application/x-www-form-urlencoded}形式の
クエリ文字列を構成し、@var{path}にアペンドします。
例えば次のふたつのリクエストは同じ効果を持ちます。
二番目の呼び出しではurlエスケープが自動的に行われることに注目してください。
@c COMMON

@example
(http-get "example.com" "/search?q=foo%20bar&n=20")

(http-get "example.com" '("/search" (q "foo bar") (n 20)))
@end example

@c EN
If @var{request-encoding} keyword argument is also given,
@var{name}s and @var{value}s
are converted into the specified character encoding before url escaping.
If it is omitted, gauche's internal character encoding is used.
@c JP
@var{request-encoding}キーワード引数が与えられた場合、
@var{name}と@var{value}はまずその文字エンコーディングに変換されたのちに
urlエスケープされます。そうでない場合はgaucheの内部
エンコーディングがそのまま使われます。
@c COMMON

@c EN
Some procedures take the third argument, @var{body},
to specify the body of the request message.
It can be a string, which will be copied verbatim to the request body,
or a list, which will be encoded in @code{multipart/form-data} message.

If @var{body} is a list, it is a list of parameter specs.  Each parameter
spec is either a list of name and value, e.g.
@code{("submit" "OK")} or a name followed by keyword-value list,
e.g. @code{("upload" :file "logo.png" :content-type "image/png")}.

The first form is for the convenience.  It is also compatible to the
query parameter list in @var{request-uri}, so that you can use the
same format for GET and POST request.  Each value is put
in a MIME part with @code{text/plain} media type, with the
character encoding specified by @code{request-encoding} keyword argument
described below.

The second form allows further control over each MIME part's attributes.
The following keywords are treated specially.

@table @code
@item :value
Specifies the value of the parameter.  The convenience form,
@code{(@var{name} @var{val})}, is just an abbreviation of
@code{(@var{name} :value @var{val})}.
@item :file
Specifies the pathname of the file, whose content is inserted
as the value of the parameter.  Useful to upload a file.
This option has precedence over @code{:value}.
MIME type of the part is set to @code{application/octet-stream}
unless specified otherwise.
@item :content-type
Overrides the MIME type of the part.  A charset parameter is
added to the content-type if not given in this argument.
@item :content-transfer-encoding
Specifies the value of content-transfer-encoding; currently the
following values are supported: @code{7bit},
@code{binary}, @code{quoted-printable} and @code{base64}.
If omitted, @code{binary} is used.
@end table

Other keywords are used as the header of the MIME part.
@c JP
いくつかの手続きは、リクエストメッセージのボディを指定する@var{body}を第3引数として
取ります。@var{body}は文字列かリストで、文字列の場合はそのまま送られ、
リストの場合は@code{multipart/form-data}形式にエンコードされて送られます。

@var{body}がリストの場合、それはパラメータ指定のリストです。
各パラメータ指定は、@code{("submit" "OK")}のような名前と値のリスト、
もしくは@code{("upload" :file "logo.png" :content-type "image/png")}
のように名前の後にキーワード-値リストを付加したものです。

最初の形式は使うのが簡単で、また@var{request-uri}のクエリパラメータリストと
同じ形式なのでGETとPOSTでルーチンを共有したい場合にも便利でしょう。
この形式では、各値はMIMEパートに@code{text/plain}として置かれます。
文字コードは下に述べる@code{request-encoding}キーワード引数により変換されます。

二番目の形式では、MIMEパートの属性についてより細かな指定を行うことができます。
以下のキーワードが特別に扱われます。

@table @code
@item :value
パラメータの値を指定します。簡潔な@code{(@var{name} @var{val})}形式は
@code{(@var{name} :value @var{val})}の省略形です。
@item :file
指定された名前のファイルの中身をパラメータの値として挿入します。
ファイルのアップロードに便利です。このオプションは@code{:value}より
優先されます。MIMEタイプは、指定が無ければ
@code{application/octet-stream}となります。
@item :content-type
MIMEタイプをオーバライドします。与えられた値にcharsetパラメータが
ついていない場合は自動的に付加されます。
@item :content-transfer-encoding
content-transfer-encodingを
@code{7bit}、@code{binary}、@code{quoted-printable}、@code{base64}の
いずれかで指定します。指定が無ければ@code{binary}が使われます。
@end table

残りのキーワードはMIMEパートのヘッダにそのまま使われます。
@c COMMON

@c EN
@strong{Return values:}
All procedures return three values.

The first value is the status code defined in RFC2616
in a string (such as "200" for success, "404" for "not found").
@c JP
@strong{戻り値:}
全ての手続きは3つの値を返します。

1つ目は、RFC2616で定義されているステータスコードの文字列値(例えば、成功時の
200、"Not found"の404など)です。
@c COMMON

@c EN
The second value is a list of parsed headers---each element of list
is a list of @code{(@var{header-name} @var{value} @dots{})},
where @var{header-name} is a string name of the header
(such as "content-type" or "location"), and @var{value} is
the corresponding value in a string.  The header name is converted
to lowercase letters.  The value is untouched except that "soft line breaks"
are removed, as defined in RFC2822.   If the server returns
more than one headers with the same name, their values are
consolidated to one list.  Except that, the order of the header list
in the second return value is the same as the order in the server's reply.
@c JP
2つ目は、パーズされたヘッダのリストで、リストの要素は@code{(@var{header-name}
@var{value} @dots{})}です。@var{header-name}はヘッダの文字列名(例えば、
"content-type"や"location"など)で、@var{value}は対応する値の文字列値です。
ヘッダ名は小文字に変換されます。値は、RFC2822で定義されている無指定行区切
(ソフト・ライン・ブレイク)が除かれる以外はそのままです。
サーバが同じ名前のヘッダを1つ以上返した場合は、
1つのリストに統合されます。それ以外では、2つ目の戻り値に
おけるヘッダのリストの順番は、サーバの応答での順番と同じです。
@c COMMON

@c EN
The third value is for the message body of the server's reply.
By default, it is a message body itself in a string.   If the server's
reply doesn't have a body, the third value is @code{#f}.  You can
change how the message body is handled by keyword arguments; for example,
you can directly store the returned message body to a file without
creating intermediate string.  The details are explained below.
@c JP
3つ目の戻り値は、サーバの応答におけるメッセージボディです。
デフォルトでは、文字列で表現されたメッセージボディそのものです。
サーバの応答がボディを持たない場合、3つ目の戻り値は@code{#f}です。
キーワード引数によって、メッセージボディがどのように扱われるかを制御できます。
例えば、中間的な文字列を作らずに、返されたメッセージボディを直接ファイルに
格納することが出来ます。詳細は以下で説明しています。
@c COMMON

@c EN
@strong{Keyword arguments:}
By default, these procedures only attaches @code{"Host"} header
field to the request message.  You can give keyword arguments
to add more header fields.
@c JP
@strong{キーワード引数:}
デフォルトで、これらの手続きはリクエストメッセージに@code{"Host"}ヘッダ・フィールドを
追加するだけです。他のヘッダ・フィールドを追加するためにキーワード引数を
与えることができます。
@c COMMON
@example
(http-get "foo.bar.com" "/index.html"
  :accept-language "ja"
  :user-agent "My Scheme Program/1.0")
@end example

@c EN
The following keyword arguments are recognized by the procedure
and do not appear in the request headers.
@c JP
以下のキーワード引数は手続きによって解釈され、リクエストヘッダには現れません。
@c COMMON

@table @code
@item request-encoding
@c EN
When a list is given to the @var{request-uri} or @var{body} arguments,
the characters in names and values of the parameters are first
converted to the character encoding specified by this keyword
argument, then encoded into @code{application/x-www-form-urlencoded}
or @code{multipart/form-data} MIME formats.
If this argument is omitted, Gauche's internal character encoding is used.

For @code{multipart/form-data}, you can override character encodings
for individual parameters by giving @code{content-type} header.
See the description of @var{body} arguments above.

If you give a string to @var{request-uri} or @var{body},
it is used without encoding conversion.  It is caller's responsibility
to ensure desired character encodings are used.
@c JP
@var{request-uri}や@var{body}がリストで与えられた場合、パラメータの
名前や値はまずこの引数で指定される文字エンコーディングへと変換され、
その後、@code{application/x-www-form-urlencoded}や
@code{multipart/form-data} MIME形式にしたがったエンコーディングが行われます。
この引数が省略された場合はGaucheの内部文字エンコーディングが使われます。

@code{multipart/form-data}については、パラメータに@code{content-type}ヘッダを
与えることでパラメータごとに文字エンコーディングの設定をオーバライドできます。
詳しくは上の@var{body}引数の説明を参照してください。

@var{request-uri}や@var{body}に文字列を与えた場合は、文字エンコーディング変換は
行われません。呼び出し側で望みの文字コードにあらかじめ変換しておいてください。
@c COMMON
@item proxy
@c EN
Specify http proxy server in a string of a form @code{hostname} or
@code{hostname:port}.  If omitted, the value of the parameter
@code{http-proxy} is used.
@c JP
httpプロキシサーバを、@code{hostname}または@code{hostname:port}形式の
文字列で指定します。省略された場合、パラメータ@code{http-proxy}の値が
使われます。
@c COMMON
@item redirect-handler
@c EN
Specifies how the redirection is handled when the server responds with
3xx status code.
You can pass @code{#f}, @code{#t} or a procedure.  The default is @code{#t}.

If @code{#f} is given, no redirect attempt will be made; the 3xx status
code and response is just returned from @code{http-*} procedures as they are.

If a procedure is given, it is called when the response status code
is 3xx.  The procedure takes four arguments, the request method (in symbol,
e.g. @code{GET}), the response status code (in string, e.g. @code{"302"}),
the parsed response headers and the response body (a string
if there's a body, or @code{#f} if the response doesn't have a body).

The procedure can return a pair or @code{#f}.
If it is a pair, it should be @code{(method . url)}, where @var{method}
is a symbol (e.g. @code{GET}) and @var{url} is a string representing url.
If a pair is returned, the @code{http-*} procedures tries to send
the request with the given method (it allows a redirection of POST request
to be GET, for example).  If it is @code{#f}, no further attempt of
redirection is made.

If @var{redirect-handler} is @code{#t}, which is the default,
then it works as if the value of the parameter
@code{http-default-redirect-handler} is passed to @var{redirect-handler}.
The parameter contains a procedure with reasonable default behavior.
See the @code{http-default-redirect-handler} entry below for the details.

A loop in redirection is detected automatically and @code{<http-error>}
is thrown.
@c JP
サーバが3xxステータスコードを返した場合のリダイレクトの処理を指定します。
@code{#f}, @code{#t}もしくは手続きを渡すことができます。省略時は@code{#t}となります。

@code{#f}が渡された場合は、リダイレクトは処理されません。3xxステータスコードを
持つレスポンスもそのまま@code{http-*}から返されます。

手続きが渡された場合は、サーバが3xxステータスコードを返すとその手続きが4つの引数で
呼ばれます。最初の引数はリクエストメソッド(シンボル、例:@code{GET})、
次がレスポンスステータスコード(文字列、例:@code{"302"})、
次がパーズされたレスポンスヘッダ、そして最後がレスポンスボディです(レスポンスボディが
あれば文字列、なければ@code{#f})。

この手続きは、ペアか@code{#f}を返さねばなりません。ペアの場合、それは
@code{(method . url)}という形で、@var{method}がシンボルによるリクエストメソッド、
@var{url}が文字列で次にリクエストすべきURLを表します。
ペアが返されれば、@code{http-*}手続きはそのURLへ、指定されたメソッドでリクエストを
再送します。(メソッドを返すことで、例えばPOSTリクエストのリダイレクトをGETリクエストに
置き換えることが可能です)。
手続きが@code{#f}を返した場合、リダイレクトは行われません。

@var{redirect-handler}が@code{#t}(デフォルト値)の場合、
パラメータ@code{http-default-redirect-handler}の値が
@var{redirect-handler}に渡されたかのように振る舞います。
このパラメータの初期値は、標準的なリダイレクトの振る舞いをする手続きになっています。
下の@code{http-default-redirect-handler}の項目を参照してください。

リダイレクトのループは自動的に検出され、@code{<http-error>}が投げられます。
@c COMMON
@item no-redirect
@c EN
This is an obsoleted keyword argument kept only for the backward
compatibility.  If a true value is given, it has the same effect
as specifying @code{#f} to @var{redirect-handler}.
@c JP
これは互換性のためだけに残されている、古い引数です。真の値を与えると、
@var{redirect-handler}に@code{#f}を渡したのと同じ効果を持ちます。
@c COMMON
@item secure
@c EN
If a true value is given, the secure connection is used.  The value
specifies the secure transport agent to establish https connection.
It can be @code{#t} or a symbol @code{tls} or @code{stunnel}.
If @code{#f} is given (default), non-secure plain http is used.
See the ``Secure connection'' section below.
@c JP
真の値が与えられた場合、セキュアな接続が使われます。
値によってhttps接続につかうトランスポートエージェントを指定できます。
有効な値は@code{#t}もしくはシンボルの@code{tls}か@code{stunnel}です。
@code{#f}が与えられた場合(デフォルト)はセキュアでない通常のhttpが使われます。
詳しくは下の「セキュアな接続」の項を参照してください。
@c COMMON
@item auth-user, auth-password
@c EN
If given, the authorization header using Basic Authentication
(RFC2617) is added to the request.
In future, we might add support for other authentication scheme.
@c JP
これらのキーワード引数が与えられた場合、Basic認証用のAuthorizationヘッダが
リクエストに付加されます。将来はBasic認証以外の認証方式もサポートするかもしれません。
@c COMMON
@item sink, flusher
@c EN
You can customize how the reply message body is handled by these
keyword arguments.  You have to pass an output port to @var{sink},
and a procedure that takes two arguments to @var{flusher}.

When the procedure starts receiving the message body, it
feeds the received chunk to @var{sink}.  When the procedure
receives entire message body, @var{flusher} method is called
with @var{sink} and a list of message header fields (in the
same format to be returned in the second value from the procedure).
The return value of @var{flusher} becomes the third return value
from the procedure.

So, the default value of @var{sink} is a newly opened string
port and the default value of @var{flusher} is
@code{(lambda (sink headers) (get-output-string sink))}.

The following example saves the message body directly to a file,
without allocating (potentially very big) string buffer.
@c JP
これらのキーワード引数によりリプライメッセージ・ボディがどのように扱われるかを
カスタマイズできます。@var{sink}には出力ポートを、@var{flusher}には2引数を
取る手続きを渡さなければなりません。

手続きがメッセージ・ボディを受信し始めると、@var{sink}へ受け取った
データ片をフィードします。手続きがメッセージ・ボディを受信し終わると、
@var{flusher}に与えられた手続きが、@var{sink}と(手続きからの2つ目の
戻り値と同じフォーマットの)メッセージ・ヘッダ・フィールドのリストとともに
呼び出されます。@var{flusher}の戻り値が、手続きからの3つ目の戻り値と
なります。

したがって、@var{sink}のデフォルト値は、新しく開かれた文字列ポートで、
@var{flusher}のデフォルト値は@code{(lambda (sink headers) (get-output-string sink))}
とも言えます。

以下のサンプルは、(とても大きい可能性のある)文字列バッファを作らずに、
メッセージ・ボディを直接ファイルに保存します。
@c COMMON
@example
(call-with-output-file "page.html"
  (lambda (out)
    (http-get "www.schemers.org" "/"
       :sink out :flusher (lambda _ #t))))
@end example

@end table

@end defun

The module also provides some utility procedures.

@deffn {Parameter} http-user-agent :optional value
@c MOD rfc.http
@c EN
The value of this parameter is used as a default value
to pass to the user-agent header.
The default value is something like @code{gauche.http/*},
where @code{*} is Gauche's version.
An application is encouraged to set this parameter appropriately.
@c JP
user-agentヘッダに渡される値のデフォルト値を指定するパラメータです。
デフォルトの値は@code{gauche.http/*} (@code{*}部分はGaucheのバージョン)
になっています。
各アプリケーションは適切な値を設定するようにしてください。
@c COMMON
@end deffn

@deffn {Parameter} http-proxy :optional value
@c MOD rfc.http
@c EN
This value is used as the default http proxy name by @code{http-get} etc.
The default value is @code{#f} (no proxy).
@c JP
このパラメータの値が@code{http-get}等のhttpプロキシのデフォルトの値として
使われます。デフォルトの値は@code{#f} (プロキシを使用しない) です。
@c COMMON
@end deffn

@deffn {Parameter} http-default-redirect-handler :optional value
@c MOD rfc.http
@c EN
Specifies the behavior of redirection if no @code{redirect-handler} keyword
argument is given to the @code{http-*} procedures.
If you change this value, it must be a procedure that follows the
protocol of @code{redirect-handler}; see the description of @code{http-*}
procedures above.
@c JP
@code{http-*}手続きに@code{redirect-handler}キーワード引数が与えられなかった
場合のデフォルトの動作を指定します。この値を変える場合、それは
@code{redirect-handler}引数のプロトコルに従う手続きでなければなりません。
上の@code{http-*}手続きの項目を参照してください。
@c COMMON

@c EN
The default behavior is as follows:
@c JP
デフォルトの動作は以下の通りです。
@c COMMON

@table @asis
@item @code{300}, @code{301}, @code{305}, @code{307}
@c EN
Redirect to the url given to the @code{location} header only if
the original request method is @code{GET} or @code{HEAD}.
@c JP
元のリクエストが@code{GET}か@code{HEAD}の場合に限り、同じリクエストを使って
@code{location}ヘッダに与えられたURLにリダイレクトします。
@c COMMON
@item @code{302}
@c EN
Redirect to the url given to the @code{location} header.  If
the original request method is @code{HEAD}, it is used again.
Otherwise, @code{GET} method is used.

Strictly speaking, this is a violation of RFC2616.  However, as the note
in RFC2616 says, many user agent do this, so we follow the flock.
(We may change this in future.)
@c JP
@code{location}ヘッダに与えられたURLにリダイレクトします。
元が@code{HEAD}リクエストなら@code{HEAD}を、それ以外なら@code{GET}リクエストを
使います。

厳密に言えばこれはRFC2616違反ですが、RFC2616の注記にもあるように、
多くのユーザエージェントがこの振る舞いをするので、それに合わせてあります。
(将来は変えるかもしれません。)
@c COMMON
@item @code{303}
@c EN
Redirect to the url given to the @code{location} header.  If
the original request method is @code{HEAD}, it is used again.
Otherwise, @code{GET} method is used.
@c JP
@code{location}ヘッダに与えられたURLにリダイレクトします。
元が@code{HEAD}リクエストなら@code{HEAD}を、それ以外なら@code{GET}リクエストを
使います。
@c COMMON
@item other than above
@c EN
No redirection is made.
@c JP
リダイレクトしません。
@c COMMON
@end table

@c EN
The following code is an example of intercepting the default
behavior in a specific request:
@c JP
次のコードは、デフォルトの振る舞いを特定のリクエストでインターセプトする例です。
@c COMMON

@example
(http-get server uri
  :redirect-handler
  (^[method status headers body]
    (if (and (equal? status "302")
             (not (member method '(GET HEAD))))
        #f
        ((http-default-request-handler) method status headers body))))
@end example
@end deffn


@defun http-compose-query path params :optional encoding
@c MOD rfc.http
@c EN
A helper procedure to create a request-uri from
a list of query parameters.  @var{Encoding} specifies
the character encodings to be used.
@c JP
クエリパラメータのリストからリクエストURIを生成する補助関数です。
@var{encoding}引数はクエリパラメータの文字エンコーディングを指定します。
@c COMMON

@example
(http-compose-query "/search" '((q "$foo") (n 20)))
 @result{} "/search?q=%24foo&n=20"

(http-compose-query "" '((x "a b") (x 2)))
 @result{} "?x=a%20b&x=2"
@end example

@c EN
If @var{path} is @code{#f}, only the query parameter part
is returned (compare the following example and the last
example):
@c JP
@var{path}が@code{#f}の場合は、クエリパラメータの部分だけが返されます
(次の例と直前の例を比べてみてください)。
@c COMMON

@example
(http-compose-query #f '((x "a b") (x 2)))
 @result{} "x=a%20b&x=2"
@end example
@end defun

@defun http-compose-form-data params port :optional encoding
@c MOD rfc.http
@c EN
A helper procedure to create @code{multipart/form-data}
from a list of parameters.  The format of @var{params} argument
is the same as the list format of @var{body} argument of
http request procedures.  The result is written to an output
port @var{port}, and the boundary string used to compose
MIME message is returned.  Alternatively you can pass @code{#f}
to the @var{port} to get the result in a string.
In that case, two values are returned, the MIME message string
and the boundary string.
@c JP
@code{multibyte/form-data}形式にエンコードされたデータを
パラメータのリストから組み立てるための補助手続きです。
@var{params}の形式はhttpリクエスト手続きの@var{body}部にリストを渡す場合の形式と同様です。
結果は出力ポート@var{port}に書き出され、
MIMEメッセージを構築するのに必要なboundary stringが返されます。
@var{port}に@code{#f}を渡した場合は、
boundary stringとデータをエンコードした文字列の二つの値が返されます。
@c COMMON

@c EN
@var{Encoding} specifies the character encodings to be used.
When omitted, Gauche's native encoding is used.
@c JP
@var{encoding}は文字エンコーディングを指定します。
省略時はGaucheのネイティブエンコーディングが使われます。
@c COMMON

@example
(define p (open-output-string))

(http-compose-form-data '((name "Preludes and Fugues")
                          (composer "Shostakovich, Dmitri")
                          (opus "87"))
                         p)
  @result{} "boundary-fh87o52rp6zkubp2uhdmo"

(get-output-string p)
  @result{}
  "\r\n--boundary-fh87o52rp6zkubp2uhdmo\r\nContent-type: te
   xt/plain; charset=utf-8\r\nContent-transfer-encoding: bi
   nary\r\ncontent-disposition: form-data; name=title\r\n\r\n
   Preludes and Fugues\r\n--boundary-fh87o52rp6zkubp2uhdmo...
@c EN
;; (result is truncated)
@c JP
;; (以下省略)
@c COMMON
@end example
@end defun

@defun http-status-code->description code
@c MOD rfc.http
@c EN
Returns a brief description of http status code @code{code},
which may be an integer or a string (e.g. @code{"404"}).
If @code{code} isn't one of known code, @code{#f} is returned.
@c JP
HTTPステータスコード@code{code}の簡単な説明を返します。
@code{code}は整数か、整数を表す文字列です(例: @code{"404"})。
@code{code}が知られているものでなかった場合は@code{#f}が返されます。
@c COMMON

@example
(http-status-code->description 404)
  @result{} "Not Found"
@end example
@end defun


@c EN
@subheading Secure connection
@c JP
@subheading セキュアな接続
@c COMMON

@c EN
When you pass a true value to @code{secure} keyword argument,
the request-making APIs such as @code{http-get} use a secure
connection.  That is, it connects with @code{https} instead of
@code{http}.  The actual value for the keyword argument can be one of the
followings:
@c JP
@code{http-get}等httpリクエスト発行APIの@code{secure}キーワード引数に、
真の値を渡した場合、セキュアなコネクションが使われます。
すなわち、@code{http}ではなく@code{https}で接続されるということです。
実際に@code{secure}キーワード引数に渡せる値は以下の通りです。
@c COMMON

@table @code
@item #t
@itemx tls
@c EN
The @code{rfc.tls} module is used for the secure connection.
@xref{Transport layer security}, for the details---you might need to
set CA certificate bundle path.
@c JP
@code{rfc.tls}モジュールを使ってセキュアな接続を行います。
詳しくは@ref{Transport layer security}を参照してください。
CA証明書のパスを設定する必要があるかもしれません。
@c COMMON
@item stunnel
@c EN
The external process @code{stunnel} is spawned and used for the
secure connection.
@c JP
@code{stunnel}プロセスをサブプロセスとして起動してそれを通じてセキュアな接続を作ります。
@c COMMON
@item #f
@c EN
Secure connection is not used.
@c JP
セキュアな接続を行いません。
@c COMMON
@end table

@c EN
If specified secure connection subsystem isn't available in the running Gauche,
an error is signaled.
Use the following procedure to check if you can use secure
connections:
@c JP
指定されたセキュア接続を行うサブシステムが実行中のGaucheでは使えない場合は、
エラーが報告されます。
サブシステムが使えるかどうかをチェックしたい場合は次の手続きを使ってください。
@c COMMON

@defun http-secure-connection-available? :optional type
@c MOD rfc.http
@c EN
The @var{type} argument may be @code{tls} or @code{stunnel}.
If omitted, @code{tls} is assumed.
Returns @code{#t} if running Gauche can use secure connection of the given type,
@code{#f} otherwise.
@c JP
@var{type}引数は@code{tls}か@code{stunnel}でなければなりません。
省略時は@code{tls}とみなされます。
指定のセキュア接続を行うサブシステムが実行中のGaucheで使える場合は@code{#t}が、
使えない場合は@code{#f}が返されます。
@c COMMON
@end defun

@c ----------------------------------------------------------------------
@node ICMP packets, IP packets, HTTP, Library modules - Utilities
@section @code{rfc.icmp} - ICMP packets
@c NODE ICMPパケット, @code{rfc.icmp} - ICMPパケット

@deftp {Module} rfc.icmp
@mdindex rfc.icmp
@c MOD rfc.icmp
@c EN
This module provides some basic utilities to construct and parse ICMP
packets.
@c JP
このモジュールではICMPパケットの構築および解析用の基本的ユーティリティ
を提供しています。
@c COMMON
@end deftp

@c EN
For the functions below, @var{buffer} should be a writable
u8vector of the enough size.
@c JP
以下の関数の@var{buffer}は十分なサイズの書き込み可能なu8vectorでなけれ
ばなりません。
@c COMMON

@c EN
Parsing functions takes @var{offset} as well as @var{buffer},
which specifies the beginning of the ICMP packet.  Using the offset
you can carry the whole IP packet in @var{buffer}, without
creating a new buffer to extract ICMP portion.
@c JP
解析用の関数は@var{buffer}のほかに@var{offset}を引数としてとります。こ
れはICMPパケットの開始位置を示すものです。このオフセットを用いて、ICMP
部分を取り出して新しいバッファを作るということなしに、IPパケット全体を
@var{buffer}内に格納できます。
@c COMMON

@defun icmp4-fill-echo! buffer ident sequence data
@c MOD rfc.icmp
@c EN
Fills @var{buffer} with the ICMPv4 Echo Request packet.
@var{Data} must be a u8vector.  The checksum field is
left to be zero, which can be filled by @code{icmp4-fill-checksum!}.
@c JP
@var{buffer}にICMPv4のエコーリクエストパケットを詰め込みます。
@var{Data}はu8vectorでなければなりません。チェックサムフィールドはゼロ
のままです。チェックサムは@code{icmp4-fill-checksum!}を使って埋め込み
ます。
@c COMMON
@end defun

@defun icmp4-fill-checksum! buffer size
@c MOD rfc.icmp
@c EN
Calculates the ICMPv4 checksum of the packet in the @var{buffer},
of @var{size} length (the size of the packet, not the buffer),
and fills the checksum field of the packet.
@c JP
@var{buffer}中の@var{size}(バッファではなくパケットの長さ)分のパケット
のICMPv4チェックサムを計算し、そのパケットのチェックサムフィールドをう
めます。
@c COMMON
@end defun

@defun icmp6-fill-echo! buffer ident sequence data
@c MOD rfc.icmp
@c EN
Fills @var{buffer} with the ICMPv6 Echo Request packet.
@var{Data} must be a u8vector.  The checksum field is
left to be zero, which is to be filled by the kernel
(so you don't need to fill by yourself).
@c JP
@var{buffer}にICMPv6のエコーリクエストパケットを詰め込みます。
@var{Data}はu8vectorでなければなりません。チェックサムフィールドは
ゼロのままで、ここはカーネルが埋めることになっています。したがって、
ユーザーが自分で埋める必要はありません。
@c COMMON
@end defun

@defun icmp-packet-type buffer offset
@defunx icmp-packet-code buffer offset
@defunx icmp-packet-ident buffer offset
@defunx icmp-packet-sequence buffer offset
@c MOD rfc.icmp
@c EN
Extracts type, code, ident and sequence fields of ICMP packet.
These functions are common to both ICMPv4/v6.
@c JP
それぞれICMPパケットのタイプ、コード、識別子、シーケンスフィールドを抜
き出します。これらの関数はICMPv4/v6で共通です。
@c COMMON
@end defun

@defun icmp4-describe-packet buffer offset
@defunx icmp6-describe-packet buffer offset
@c MOD rfc.icmp
@c EN
Prints out a simple text description of the given ICMPv4 and v6 packet,
respectively.
@c JP
それぞれ与えられたICMPv4およびICMPv6パケットの簡単な説明を印字します。
@c COMMON
@end defun

@defun icmp4-message-type->string type
@defunx icmp4-unreach-code->string code
@defunx icmp4-redirect-code->string code
@defunx icmp4-router-code->string code
@defunx icmp4-exceeded-code->string code
@defunx icmp4-parameter-code->string code
@defunx icmp4-security-code->string code
@defunx icmp6-message-type->string type
@defunx icmp6-unreach-code->string code
@defunx icmp6-exceeded-code->string code
@defunx icmp6-parameter-code->string code
@c MOD rfc.icmp
@c EN
Returns a text description of ICMPv4 and ICMPv6 types and codes.
@c JP
ICMPv4およびICMPv6のタイプとコードの説明テキストを返します。
@c COMMON
@end defun

@c ----------------------------------------------------------------------
@node IP packets, JSON parsing and construction, ICMP packets, Library modules - Utilities
@section @code{rfc.ip} - IP packets
@c NODE IPパケット, @code{rfc.ip} - IPパケット

@deftp {Module} rfc.ip
@mdindex rfc.ip
@c EN
This module provides some basic utilities to parse raw IP packets.
@c JP
このモジュールは生のIPパケットを解析する基本的なユーティリティを提供し
ます。
@c COMMON
@end deftp

@c EN
The @var{packet} argument in the following functions must be
any type of uniform vector (@pxref{Uniform vectors}), containing
a raw IP packet including its IP header.
Those functions work for both IPv4 and IPv6 packets; however,
reading from a raw IPv6 socket returns a packet without IPv6 header,
so you usually don't need to use these functions.
@c JP
次からの関数における@var{packet}引数はユニフォームベクタ
(@ref{Uniform vectors}参照)型でなければなりません。これにはIPヘッダを
含む生のIPパケットが入ります。以下の関数はIPv4およびIPv6パケットの両方
で動きます。しかしながら、生のIPv6ソケットから読むときは、IPv6ヘッダを
含まないパケットが返ります。とうわけで、通常これらの関数が必要になるこ
とはないでしょう。
@c COMMON

@c EN
The @var{offset} argument specifies the beginning of the IP packet
in @var{packet}.  If @var{packet} contains only one IP packet
you can pass 0.  It is not an optional argument, since these routines
may be used in speed-sensitive inner loop.
@c JP
@c COMMON

@defun ip-version packet offset
@c MOD rfc.ip
@c EN
Returns the IP version number (either 4 or 6) of the given IP packet.
@c JP
与えられたIPパケットのIPバージョン番号(4または6)が返ります。
@c COMMON
@end defun

@defun ip-header-length packet offset
@c MOD rfc.ip
@c EN
Returns the size of IP header of the given packet in octets,
including any IP header options.
@c JP
与えられたパケットのIPヘッダ(IPヘッダオプションもすべて含む)のオクテッ
トで数えたサイズを返します。
@c COMMON
@end defun

@defun ip-protocol packet offset
@c MOD rfc.ip
@c EN
Returns the IP protocol number of the given packet.
@c JP
与えられたパケットのIPプロトコル番号を返します。
@c COMMON
@end defun

@defun ip-source-address packet offset
@defunx ip-destination-address packet offset
@c MOD rfc.ip
@c EN
Returns the source and destination address in the given packet
in an integer, respectively.
@c JP
与えられたパケットの送信元アドレスと送信先アドレスをそれぞれ整数で返し
ます。
@c COMMON
@end defun


@c ----------------------------------------------------------------------
@node JSON parsing and construction, MD5 message digest, IP packets, Library modules - Utilities
@section @code{rfc.json} - JSON parsing and construction
@c NODE JSONのパーズと構築, @code{rfc.json} - JSONのパーズと構築

@deftp {Module} rfc.json
@mdindex rfc.json
@c EN
Procedures to parse JSON (RFC7159) data to S-expressions,
and convert S-expressions to JSON representation, are provided.
@c JP
RFC7159で規定される、JSON形式をパーズしてS式に直す手続きと、
S式をJSON形式に変換する手続きが提供されます。
@c COMMON
@end deftp

@deftp {Condition type} <json-parse-error>
@c MOD rfc.json
@c EN
The parser @code{parse-json} and @code{parse-json-string} raise
this condition when they encounter
invalid JSON syntax.  It inherits @code{<error>}, and adds the following
slot.
@c JP
パーズ手続き@code{parse-json}と@code{parse-json-string}は、
無効なJSON構文に出会った時にこのコンディションを投げます。
@code{<error>}を継承し、次のスロットを追加で持ちます。
@c COMMON

@defivar {<json-parse-error>} position
@c EN
The input position, counted in characters, where the error occurred.
@c JP
エラーが起きた入力位置(文字数)。
@c COMMON
@end defivar
@end deftp

@deffn {Parameter} json-nesting-depth-limit
[SRFI-180]
@c MOD rfc.json
@c EN
Its value must be a real number, specifying the maximum nesting depth
of JSON text that can be parsed by @code{parse-json}.  If the input
exceeds the value, an @code{<json-parse-error>} is thrown.
The default value is @code{+inf.0}.
@c JP
このパラメータの値は実数でなければなりません。
@code{parse-json}がパーズするJSONテキストに許される最大のネストの深さを指定します。
入力のネスト深さがこのパラメータの値を越えた場合、@code{<json-parse-error>}が
投げられます。
デフォルトは@code{+inf.0}です。
@c COMMON
@end deffn


@defun parse-json :optional input-port
@c MOD rfc.json
@c EN
Reads and parses the JSON representation from @var{input-port} (default is
the current input port), and returns the result in an S-expression.
May raise a @code{<json-parse-error>} condition when parse error occurs,
or the nesting level exceeds the value of @code{json-nesting-depth-limit}.
@c JP
JSON表記を@var{input-port} (省略された場合はcurrent-input-port)から
読み込みパーズして、結果をS式で返します。
パーズエラーが起きたり、ネストレベルが@code{json-nesting-depth-limit}の
値を超過した場合は@code{<json-parse-error>}コンディションを投げます。
@c COMMON

@c EN
The following table shows how JSON datatypes are
mapped to Scheme objects.
@c JP
下のテーブルに、JSONのデータ型がどのようにSchemeにマップされるかを示します。
@c COMMON

@table @asis
@c EN
@item @code{true}, @code{false}, @code{null}
Symbols @code{true}, @code{false} and @code{null}.
(Customizable by @code{json-special-handler})
@item Arrays
Scheme vectors.  (Customizable by @code{json-array-handler})
@item Objects
Scheme assoc-lists, in which keys are strings, and values
are Scheme objects.  (Customizable by @code{json-object-handler})
@item Numbers
Scheme inexact real numbers.
@item Strings
Scheme strings.
@c JP
@item @code{true}, @code{false}, @code{null}
シンボル@code{true}, @code{false} and @code{null}。
(@code{json-special-handler}で変更可能)
@item 配列
Schemeのベクタ。 (@code{json-array-handler}で変更可能)
@item オブジェクト
Schemeの連想リスト。キーは文字列で、値はSchemeオブジェクト。
(@code{json-object-handler}で変更可能)
@item 数値
Schemeの不正確な実数。
@item 文字列
Schemeの文字列。
@c COMMON
@end table

@c EN
Since the parser used internally in @code{parse-json} prefetches
characters, some characters after the parsed JSON expression
may already been read from @var{port} when @code{parse-json} returns.
That is, you cannot call @code{parse-json} repeatedly on @var{port}
to read subsequent JSON expressions.  Use @code{parse-json*} if you
need to read multiple JSON expressions.
@c JP
@code{parse-json}内で使っているパーザは文字の先読みを行う可能性があるので、
@code{parse-json}が戻って来た時点で、パーズされたJSON式以降のいくつかの文字が
@var{port}から既に読まれてしまっている可能性があります。
すなわち、複数のJSON式を読み出すのに、@var{port}に対して@code{parse-json}
を繰り返し呼び出すのはうまくいきません。複数のJSON式をパーズしたい場合は
@code{parse-json*}を使ってください。
@c COMMON
@end defun

@defun parse-json* :optional input-port
@c MOD rfc.json
@c EN
Read JSON repeatedly from @var{input-port} until it reaches EOF,
and returns parsed results as a list.
@c JP
@var{input-port}から、EOFに達するまでJSON式を繰り返し読み取り、
パーズ結果をリストにして返します。
@c COMMON
@end defun

@defun parse-json-string str
@c MOD rfc.json
@c EN
Parses the JSON string and returns the result in an S-expression.
May raise a @code{<json-parse-error>} condition when parse error occurs.

See @code{parse-json} above for the mappings from JSON datatypes
to Scheme types.
@c JP
文字列@var{str}をJSONとしてパーズし、結果をS式で返します。
パーズエラーが起きた場合は@code{<json-parse-error>}コンディションを投げます。

JSONのデータ型とSchemeの型とのマッピングについては上の@code{parse-json}
を参照してください。
@c COMMON
@end defun

@deffn {Parameter} json-array-handler
@deffnx {Parameter} json-object-handler
@deffnx {Parameter} json-special-handler
@c MOD rfc.json
@c EN
The value of these parameters must be a procedure that takes
one argument: for @code{json-array-handler}, it is a list of
elements of a JSON array, for @code{json-object-handler},
it is a list of conses of key and value of a JSON object,
and for @code{json-special-handler}, it is one of the
symbols @code{false}, @code{true} or @code{null}.

Whenever @code{parse-json} reads a JSON array, a JSON object,
or one of those special values,
it calls corresponding parameter to get a Scheme object.

The default value of these parameters are @code{list->vector},
@code{identity}, and @code{identity}, respectively.

The following example maps JSON objects to hash tables.
@c JP
これらのパラメータの値は、引数をひとつ取る手続きでなければなりません。
@code{json-array-handler}の値の手続きに渡される引数は、
JSON配列の要素のリストです。
@code{json-object-handler}では
JSONオブジェクトのキーと値をconsしたもののリスト、
@code{json-special-handler}では
シンボル@code{false}, @code{true}, @code{null}のいずれかです。

@code{parse-json}はJSON配列やオブジェクト、false、true、nullに
出会う度に、
このパラメータの値の手続きを起動して、JSONに対応するSchemeオブジェクトを
得ます。

これらのパラメータのデフォルト値はそれぞれ@code{list->object}、
@code{identity}、@code{identity}です。

次の例では、JSONオブジェクトをハッシュテーブルに変換しています。
@c COMMON

@example
(parameterize ([json-object-handler (cut alist->hash-table <> 'string=?)])
  (parse-json-string "@{\"a\":1, \"b\":2@}"))
 @result{} #<hash-table ...>
@end example
@end deffn


@deftp {Condition type} <json-construct-error>
@c MOD rfc.json
@c EN
The converters @code{construct-json} and
@code{construct-json-string} raise this condition
when they cannot convert given Scheme object to JSON.
It inherits @code{<error>}, and adds the following slot.
@c JP
@code{construct-json}と@code{construct-json-string}は、
JSONに変換できないSchemeオブジェクトを見つけるとこのコンディションを投げます。
@code{<error>}を継承し、次のスロットを追加で持ちます。
@c COMMON

@defivar {<json-construct-error>} object
@c EN
The Scheme object that cannot convert to JSON representation.
@c JP
JSON表現に変換できなかったSchemeオブジェクト。
@c COMMON
@end defivar
@end deftp

@defun construct-json obj :optional output-port
@defunx construct-json-string obj
@c MOD rfc.json
@c EN
Creates JSON representation of Scheme object @var{obj}.
@code{construct-json} writes out the result to @var{output-port},
whose default is the current output port.  @code{construct-json-string}
returns the result in a string.

If @var{obj} contains a Scheme object that cannot be mapped
to JSON representation, a @code{<json-construct-error>} condition
is raised.

Scheme objects are mapped to JSON as follows:
@c JP
Schemeオブジェクト@var{obj}のJSON表現を作ります。
@code{construct-json}は結果を@var{output-port}に書き出します。デフォルトは
current-output-portです。@code{construct-json-string}は結果を文字列で返します。

@var{obj}がJSONにマップできないオブジェクトを含んでいた場合は
@code{<json-construct-error>}コンディションが投げられます。

Schemeオブジェクトは以下のようにJSONへと変換されます。
@c COMMON

@table @asis
@c EN
@item symbol @code{false}, @code{#f}
@code{false}
@item symbol @code{true}, @code{#t}
@code{true}
@item symbol @code{null}
@code{null}
@item list, instance of @code{<dictionary>}
JSON object (list must be an assoc list of key and value).
@item string
string
@item real number
number
@item instance of @code{<sequence>} (except strings and lists)
JSON array
@c JP
@item シンボル@code{false}, @code{#f}
@code{false}
@item シンボル@code{true}, @code{#t}
@code{true}
@item シンボル@code{null}
@code{null}
@item リスト、 @code{<dictionary>}のインスタンス
JSONオブジェクト (リストはキーと値の連想リストでなければならない)
@item 文字列
文字列
@item 実数
数値
@item @code{<sequence>}のインスタンス (文字列とリストを除く)
JSON配列
@c COMMON
@end table

@end defun

@c ----------------------------------------------------------------------
@node MD5 message digest, MIME message handling, JSON parsing and construction, Library modules - Utilities
@section @code{rfc.md5} - MD5 message digest
@c NODE MD5メッセージダイジェスト, @code{rfc.md5} - MD5メッセージダイジェスト

@deftp {Module} rfc.md5
@mdindex rfc.md5
@c EN
This module implements MD5 message digest algorithm, defined in
RFC 1321 (@uref{https://www.ietf.org/rfc/rfc1321.txt}).
The module extends util.digest
(@pxref{Message digester framework}).
@c JP
このモジュールは、RFC 1321 (@uref{https://www.ietf.org/rfc/rfc1321.txt}) で
定義されている、MD5メッセージダイジェストアルゴリズムを実装しています。
このモジュールは、util.digest (@ref{Message digester framework}参照)
を拡張しています。
@c COMMON
@end deftp

@deftp {Class} <md5>
@clindex md5
@c MOD rfc.md5
@c EN
The instance of this class keeps internal state of MD5 digest algorithm.

This class implements @code{util.digest} framework interface,
@code{digest-update!}, @code{digest-final!},
@code{digest}, and @code{digest-string}.
@xref{Message digester framework}, for detailed explanation
of these methods.
@c JP
このクラスのインスタンスは、MD5ダイジェストアルゴリズムの内部状態を
保持しています。

このクラスは、@code{util.digest}フレームワークのインターフェースである、
@code{digest-update!}、@code{digest-final!}、@code{digest}、
@code{digest-string}を実装しています。
これらのメソッドの詳細な説明は、@ref{Message digester framework}
を参照して下さい。
@c COMMON
@end deftp

@c EN
Besides the digester framework, this module provides to
short-cut procedures.
@c JP
ダイジェスタフレームワークに加えて、このモジュールはショートカット手続きを
提供します。
@c COMMON

@defun md5-digest
@c MOD rfc.md5
@c EN
Reads data from the current input port until EOF, and returns
its digest in an incomplete string.
@c JP
現在の入力ポートからEOFまで読み込み、そのダイジェストを不完全文字列で
返します。
@c COMMON
@end defun

@defun md5-digest-string string
@c MOD rfc.md5
@c EN
Digest the data in @var{string}, and returns the result
in an incomplete string.
@c JP
@var{string}にあるデータをダイジェストし、その結果を不完全文字列で
返します。
@c COMMON
@end defun

@c ----------------------------------------------------------------------
@node MIME message handling, Quoted-printable encoding/decoding, MD5 message digest, Library modules - Utilities
@section @code{rfc.mime} - MIME message handling
@c NODE MIMEメッセージ処理, @code{rfc.mime} - MIMEメッセージ処理

@deftp {Module} rfc.mime
@mdindex rfc.mime
@c EN
This module provides utility procedures to handle
Multipurpose Internet Mail Extensions (MIME) messages,
defined in RFC2045 thorough RFC2049.
Provided APIs include procedures to parse or compose MIME-specific
header fields, and parse or compose MIME-encoded message bodies.
@c JP
RFC2045からRFC2049で定義されている、
多目的インターネットメール拡張(Multipurpose Internet Mail Extensions; MIME)
メッセージを扱う便利な手続きです。MIME特有のヘッダフィールドやメッセージボディを
パーズしたり作成したりするAPIが提供されます。
@c COMMON

@c EN
This module mainly focuses on providing low-level building-block procedures,
on top of which application-specific modules are to be built.
For example, @code{rfc.http} uses this module to compose
@code{multipart/form-data} message for the body of POST requests
(@pxref{HTTP}).
@c JP
このモジュールは主としてビルディングブロックとなる低レベルの手続きに
フォーカスしており、アプリケーション特有のモジュールがこの上に
構築されることを意図しています。例えば@code{rfc.http}はPOSTリクエストの
ボディを@code{multipart/form-data}として構築する際にこのモジュールを
利用します(@ref{HTTP}参照)。
@c COMMON

@c EN
This module is supposed to be used with @code{rfc.822} module
(@pxref{RFC822 message parsing}).
@c JP
このモジュールは、@code{rfc.822}モジュールと一緒に使うことを
想定しています(@ref{RFC822 message parsing}参照)。
@c COMMON
@end deftp

@subheading Utilities for header fields

@c EN
A few utility procedures to parse and generate MIME-specific header fields.
@c JP
MIME特有のヘッダフィールドをパーズしたり生成したりする便利な手続き。
@c COMMON

@defun mime-parse-version field
@c MOD rfc.mime
@c EN
If @var{field} is a valid header field for MIME-Version, returns
its major and minor versions in a list.  Otherwise, returns @code{#f}.
It is allowed to pass @code{#f} to @var{field}, so that
you can directly pass the result of @code{rfc822-header-ref} to it.
Given parsed header list by @code{rfc822-read-headers}, you can
get mime version (currently, it should be @code{(1 0)}) by the
following code.
@c JP
@var{field}がそのMIMEバージョンのヘッダフィールドとして有効であれば、
そのメジャーバージョン番号とマイナーバージョン番号をリストにして
返します。そうでなければ、@code{#f}を返します。
@var{field}には@code{#f}を渡せるので、@code{rfc822-header-ref}の
戻り値を直接渡すこともできます。@code{rfc822-read-headers}により
返されるパーズ済みヘッダのリストを渡すことで、以下のように
MIMEのバージョンを得ることができます。(現在は、@code{(1 0)}です。)
@c COMMON
@example
(mime-parse-version (rfc822-header-ref headers "mime-version"))
@end example

@c EN
Note: simple regexp such as @code{#/\d+\.\d+/} doesn't do this job,
for @var{field} may contain comments between tokens.
@c JP
注意: @var{field}はトークンの間にコメントを含むかもしれないので、
@code{#/\d+\.\d+/}のような単純な正規表現では不十分です。
@c COMMON
@end defun

@defun mime-parse-content-type field
@c MOD rfc.mime
@c EN
Parses the "content-type" header field, and returns a list such as:
@c JP
``content-type''ヘッダフィールドをパーズし、次のようなリストを
返します。
@c COMMON
@example
(@i{type} @i{subtype} (@i{attribute} . @i{value}) @dots{})
@end example
@c EN
where @i{type} and @i{subtype} are MIME media type and
subtype in a string, respectively
@c JP
ここで、@i{type}と@i{subtype}はそれぞれ、MIMEメディアタイプと
サブタイプを文字列で表したものになります。
@c COMMON

@example
(mime-parse-content-type "text/html; charset=iso-2022-jp")
 @result{} ("text" "html" ("charset" . "iso-2022-jp"))
@end example

@c EN
If @var{field} is not a valid content-type field, @code{#f} is
returned.
@c JP
@var{field}が有効なcontent-typeフィールドでない場合は、
@code{#f}が返ります。
@c COMMON
@end defun

@defun mime-parse-content-disposition field
@c MOD rfc.mime
@c EN
Parses Content-disposition header field as specified in RFC2183.
@c JP
RFC2183に定められたContent-Dispositionヘッダフィールドをパーズします。
@c COMMON
(mime-parse-content-disposition "attachment; filename=genome.jpeg;\
  modification-date=\"Wed, 12 Feb 1997 16:29:51 -0500\";")
 @result{} ("attachment"
      ("filename" . "genome.jpeg")
      ("modification-date" . "Wed, 12 Feb 1997 16:29:51 -0500"))
@end defun


@defun mime-parse-parameters :optional iport
@defunx mime-compose-parameters params :optional oport :key start-column
@c MOD rfc.mime
@c EN
These are low-level utility procedures to parse and compose @emph{parameter}
part of header fields (as appeared in RFC2045 Section 5.1 etc).

@code{Mime-parse-parameters} reads the parameter
part of the header body from an input port @var{iport}, and
returns an assoc list of the parameter names and values.
Conversely, @code{mime-compose-parameters} takes an assoc
list of names and values, compose parameter part and
emit it to @var{oport}.   When omitted, the current input
port and the current output port are used for @var{iport}
and @var{oport}, respectively.  You can pass @code{#f} to
@var{oport} and @code{mime-compose-parameters} returns the
result in a string instead of emitting it to a port.
@c JP
これらは、(RFC2045の5.1節にあるような)ヘッダフィールドの値の@emph{parameter}
部分をパーズしたり作成したりするための低レベルのユーティリティ手続きです。

@code{mime-parse-parameters}はヘッダフィールドの値のパラメータ部分を
入力ポート@var{iport}から読んでパーズし、パラメータの名前と値の
連想リストを返します。
@code{mime-compose-parameters}はその逆で、連想リストをとり、
パラメータ部分を構成して@var{oport}へと書き出します。
@var{iport}、@var{oport}はそれぞれ省略された場合、
@code{current-input-port}と@code{current-output-port}を
デフォルトとします。また、@var{oport}に@code{#f}を渡すと
@code{mime-compose-parameters}は結果をポートに書き出すかわりに
文字列として返します。
@c COMMON

@example
(call-with-input-string
   "; name=foo; filename=\"foo/bar/baz\""
   mime-parse-parameters)
 @result{} (("name" . "foo") ("filename" . "foo/bar/baz"))

(mime-compose-parameters
 '(("name" . "foo") ("filename" . "foo/bar/baz"))
 #f)
 @result{} "; name=foo; filename=\"foo/bar/baz\""
@end example

@c EN
@code{Mime-compose-parameters} tries to insert folding line breaks
between parameters to avoid the header line becomes too long.
You can pass the beginning column position of the parameter
part via @var{start-column} argument.
@c JP
@var{mime-compose-parameters}はヘッダ行が長くなりすぎる場合に
パラメータ間に折り返し改行を入れようとします。パラメータ部分が始まる
カラム数は@var{start-column}で与えることができます。
@c COMMON

@c EN
We plan to make these procedures handle RFC2231's parameter value
extension transparently in future.
@c JP
将来は、これらの手続きにRFC2231のパラメータ値拡張を透過的に処理させる予定です。
@c COMMON
@end defun


@defun mime-decode-word word
@c MOD rfc.mime
@c EN
Decodes RFC2047-encoded word.  If @var{word} isn't an encoded word,
it is returned as is.

Note that this procedure decodes only if the entire @var{word} is
an ``encoded word'' defined in RFC2047.  If you are dealing with
a field that may contain multiple encoded word and/or unencoded parts,
use @code{mime-decode-text} below.
@c JP
RFC2047でエンコードされた@var{word}をデコードします。
@var{word}がRFC2047でエンコードされたものでない場合は、そのまま
返されます。

この手続きは@var{word}全体がRFC2047の規定する``encoded-word''である場合にのみ
デコードを行うことに注意してください。複数のエンコードされた部分や
エンコードされていない部分が混ざっているフィールドを扱う場合は、
下に示す@code{mime-decode-text}を使います。
@c COMMON

@example
(mime-decode-word "=?iso-8859-1?q?this=20is=20some=20text?=")
 @result{} "this is some text"
@end example

@end defun
@defun mime-decode-text text
@c MOD rfc.mime
@c EN
Returns a string in which
all encoded words contained within @var{text} are decoded.
This procedure can deal with a header field body that may contain
mixture of non-encoded and encoded parts, and/or multiple encoded
parts.  One of such header field is the Subject field of email.

@example
(mime-decode-text "This is =?US-ASCII?q?some=20text?=")
 @result{} "This is some text"
@end example
@c JP
@var{text}中に含まれるすべてのencoded wordをデコードした文字列を返します。
この手続きは、エンコードされていない部分とエンコードされている部分が混ざっていたり、
複数のエンコードされている部分を持つヘッダフィールドボディを処理することが
できます。そのようなフィールドの例はemailのSubjectフィールドです。

@example
(mime-decode-text "Yamada Taro (=?utf-8?B?5bGx55SwIOWkqumDjg==?=)")
 @result{} "Yamada Taro (山田 太郎)"
@end example
@c COMMON

@c EN
Care should be taken if you apply this procedure to a ``structured''
header field body (see RFC2822 section 2.2.2).
The proper way of parsing a structured header field body is
to tokenize it first, then to decode each word using @code{mime-decode-word}.
since the decoded text may contain characters that affects the tokenization.
(However, if you can just show the header field in human readable way
for informational purposes, you may just use @code{mime-decode-text}
on entire header field for the convenience).
@c JP
この手続きを「構造化された」ヘッダフィールドボディ (RFC2822 2.2.2節参照)
に適用する際には注意が必要です。
構造化されたヘッダフィールドボディをパーズする正式な方法は、
最初にトークンに分割して、それから各wordを
@code{mime-decode-word}を使ってデコードするというものです。
なぜならデコード後のテキスト中に、パージングに影響を与える文字が含まれている
かもしれないからです。
(ただし、単に参考情報を人間にわかりやすいように表示するだけの目的の場合は、
簡便のためにヘッダフィールド全体をこの手続きで一度にデコードしてしまっても
良いでしょう)。
@c COMMON
@end defun

@defun mime-encode-word word :key charset transfer-encoding
@c MOD rfc.mime
@c EN
Encodes @var{word} in the RFC2047 format.  The keyword
argument @var{charset} specifies the character encoding scheme
in string or symbol.
whose default is @code{utf-8}.  If @var{charset} differs from
Gauche's internal encoding and @var{word} is a complete string,
the procedure converts the character encoding to @var{charset},
then performs transfer encoding.
@c JP
@var{word}をRFC2047フォーマットにエンコードします。キーワード引数
@var{charset}は文字列かシンボルで文字エンコーディングスキームを指定します。
デフォルトは@code{utf-8}です。@var{charset}の指定がGaucheの
内部文字エンコーディングと異なっており、@var{word}が完全な文字列である場合は、
まず@var{word}が@var{charset}のエンコーディングへと変換され、
その上でトランスファーエンコーディングがかけられます。
@c COMMON

@example
(mime-encode-word "this is some text")
 @result{} "=?utf-8?B?dGhpcyBpcyBzb21lIHRleHQ=?="
@end example

@c EN
The keyword argument @var{transfer-encoding} specifies how
the octets are encoded to transfer-safe characters.  You can
give a symbol @code{b}, @code{B} or @code{base64} for Base64,
and @code{Q}, @code{q}, @code{quoted-printable} for Quoted-printable
transfer encodings.  An error is raised if you pass values other
than those.  The default is Base64 encoding.
@c JP
キーワード引数@var{transfer-encoding}は各オクテットを伝達上安全な
文字列へどエンコードする方法を指定します。サポートされている値は、
Base64を指定するシンボル@code{b}、@code{B}、@code{base64}、
およびQuoted printableを指定する
@code{Q}、@code{q}、@code{quoted-printable}です。
これ以外の値を渡した場合はエラーが通知されます。デフォルトはBase64です。
@c COMMON

@c EN
This procedure does not consider the length of the resulting
encoded word, which RFC2047 recommends to be less than 75 octets.
Use @code{mime-encode-text} below to conform the line length limit.
@c JP
この手続きは結果のencoded wordの長さを気にしませんが、
RFC2047によればencoded wordは75オクテットまでに収めることが
要請されています。この要請に対応するには下に示す
@code{mime-encode-text}を使って下さい。
@c COMMON

@c EN
(Note: In most Gauche procedures, a keyword argument @code{encoding}
is used to specify character encodings.  In this context we have
two encodings, however, and to avoid the confusion we chose to use
the terms ``charset'' and ``transfer-encoding'' that appear in
RFC documents.)
@c JP
(註：ほとんどのGaucheの手続きでは、キーワード引数@code{encoding}により
文字エンコーディングを指定します。しかしこの手続きの文脈では
2つの「エンコーディング」が存在しているので、混乱を避けるために
RFC文書で使われている``charset''および``transfer-encoding''の用語を
使うこととしました。)
@c COMMON
@end defun

@defun mime-encode-text text :key charset transfer-encoding line-width start-column force
@c MOD rfc.mime
@c EN
Encode @var{text} in RFC2047 format if necessary, and considering
line folding if the result gets too long.

The keyword arguments @var{charset} and @var{transfer-encoding} are the same
as @code{mime-encode-word}.
@c JP
@var{text}を、必要ならばRFC2047フォーマットに従いエンコードします。
また、結果が長すぎる場合の行の折り返しも考慮します。

キーワード引数@var{charset}と@var{transfer-encoding}の意味は
@code{mime-encode-word}と同じです。
@c COMMON

@c EN
If the @var{text} only consists of printable ASCII characters,
no encoding is done, and only line folding is considered.
However, if a true value is given to the @var{force} argument,
even ASCII-only @var{text} is encoded.
@c JP
もし@var{word}が印字可能なASCII文字のみで構成されていた場合は
エンコーディングは行われず、行の折り返しのみが処理されます。
但し、@var{force}引数に真の値が与えられた場合はASCIIのみの@var{text}も
エンコードされます。
@c COMMON

@c EN
The @var{line-width} specifies the maximum line width of the result.
Its default is 76.
If the encoded word gets too long, it is splitted to multiple encoded
words and CR LF SPC sequence (``folding white space'' defined in RFC2822)
are inserted inbetween.
You can suppress this behavior by passing @code{#f} or @code{0} to
@var{line-width}.
Since encoded word needs some overhead characters, it doesn't make much sense
to specify small value to @code{line-width}.  Current implementation
rejects @code{line-width} smaller than 30.
@c JP
@var{line-width}は結果に現れる行の最大値を指定します。デフォルトは76です。
encoded wordがこれを越える場合は、複数のencoded wordへと結果は分割され、
間にCR LF SPCシーケンス(RFC2822で定義される``folding white space'')が挿入されます。
@var{line-width}に@code{#f}か@code{0}を渡すことで
行の折り返しを抑制することができます。
encoded wordには文字数でいくらかのオーバヘッドがあるため、
あまり小さい@code{line-width}には意味がありません。現在の実装では
30以下の値は拒否されます。
@c COMMON

@c EN
The @var{start-column} keyword argument can be used to
shorten the first of folded
lines to make room for header field name.  For example, if
you want to encode the body of a Subject header field,
you can pass the value of @code{(string-length "Subject: ")} so that
the encoded result can directly concatenated after the header
field name.  The default value is 0.
@c JP
@var{start-column}キーワード引数は、ヘッダフィールド名を入れるために
エンコード結果の最初の行だけを短くするのに使えます。
例えばSubjectヘッダフィールドのボディをエンコードする際に、
@code{(string-length "Subject: ")}の値を渡してやれば、
結果を直接"Subject: "の後に連結することができるわけです。
デフォルトの値は0です。
@c COMMON

@c EN
This procedure is not designed to encode parts of structured
header fields, which have further restrictions such as which parts
can be encoded and where the folding white spaces can be inserted.
The robust way is to encode some parts first, then construct
a structured header fields, considering line folding.
@c JP
この手続きはstructured header fieldをエンコードするようには設計
されていません。structured header fieldには、どの部分がエンコード
可能でどの部分にfolding white spaceが挿入可能かについてさらなる
制約があるためです。安全な方法は、まず必要な部分をエンコードし、
それから折り返しを考慮しつつstructured header fieldを組み立てることです。
@c COMMON
@end defun

@subheading Streaming parser

@c EN
The streaming parser is designed so that you can decide how
to do with the message body before the entire message is read.
@c JP
メッセージ全体が読み込まれる前にメッセージボディをどのように
扱うかをコントロールできるように、ストリームパーザが用意されて
います。
@c COMMON

@defun mime-parse-message port headers handler
@c MOD rfc.mime
@c EN
The fundamental streaming parser.  @var{Port} is an input port
from where the message is read.  @var{Headers} is a list of headers
parsed by @code{rfc822-read-headers}; that is, this procedure
is supposed to be called after the header part of the message
is parsed from @var{port}:
@c JP
基本的なストリームパーザです。@var{port}は、メッセージを読み込む
入力ポートです。@var{headers}は@code{rfc822-read-headers}により
パーズされたヘッダのリストです。つまり、この手続きは、
@var{port}から読み込まれたメッセージのヘッダ部分がパーズされた
後に使われることを想定しています。
@c COMMON
@example
(let* ((headers (rfc822-read-headers port)))
  (if (mime-parse-version (rfc822-header-ref headers "mime-version"))
     ;; parse MIME message
     (mime-parse-message port headers handler)
     ;; retrieve a non-MIME body
     ...))
@end example

@c EN
@code{Mime-parse-message} analyzes @var{headers}, and calls
@var{handler} on each message body with two arguments:
@c JP
@code{mime-parse-message}は@var{headers}を解析し、
メッセージボディのそれぞれについて、2引数をもって
@var{handler}を呼び出します。
@c COMMON

@example
(handler @var{part-info} @var{xport})
@end example

@c EN
@var{Part-Info} is a @code{<mime-part>} structure described below
that encapsulates the information of this part of the message.
@c JP
@var{part-info}は、以下で説明するような、メッセージのこのパートの
情報をカプセル化した@code{<mime-part>}ストラクチャです。

@c EN
@var{Xport} is an input port, initially points to the beginning
of the body of message.  The handler can read from the port
as if it is reading from the original @var{port}.  However,
@var{xport} recognizes MIME boundary internally, and returns EOF
when it reaches the end of the part.
(Do not read from the original @var{port} directly, or it will mess up
the internal state of @var{vport}).
@c JP
@var{xport}は入力ポートで、最初はメッセージボディの先頭を指しています。
ハンドラはこのポートからメッセージボディを読み込むことが出来ます。
@var{xport}はMIMEバウンダリを認識し、パートの最後に到達したら
EOFを返します。
(元の@var{port}から直接読み込まないようにして下さい。
そうしてしまうと、@var{vport}の内部状態がおかしくなります)。
@c COMMON

@c EN
@var{Handler} can read the part into the memory, or
save it to the disk, or even discard the part.
Whatever it does, it has to read from @var{vport} until it
returns EOF.

The return value of @var{handler} will be set in
the @code{content} slot of @var{part-info}.
@c JP
@var{handler}は、パートをメモリに読み込んだり、ディスクに保存したり、
あるいはそのパートを無視したりできます。ただ、何をするにせよ、
@var{vport}がEOFを返すまでデータを読まなければなりません。

@var{handler}の戻り値は、@var{part-info}の@code{content}スロットに
セットされます。

@c EN
If the message has nested multipart messages, @var{handler} is
called for each "leaf" part, in depth-first order.  @var{Handler}
can know its nesting level by examining @var{part-info} structure.
@c JP
メッセージが、ネストしたマルチパートメッセージを含んでいる場合は、
@var{handler}は深さ優先でそれぞれの``葉''のパートに対して呼ばれます。
@var{handler}は、@var{part-info}ストラクチャを調べることで、
そのネストのレベルを知ることができます。

@c EN
The message doesn't need to be a multipart type; if it is a
MIME @code{message} type, @var{handler} is called on the body
of enclosed message.  If it is other media types such as @code{text}
or @code{application}, @var{handler} is called on the (only) message body.
@c JP
メッセージはマルチパートである必要はありません。メッセージが
MIME @code{message}タイプである場合は、@var{handler}は囲まれたメッセージの
ボディに対して呼ばれます。メッセージが、@code{text}や@code{application}
などの他のメディアタイプの場合は、@var{handler}は単にメッセージボディに
対して呼ばれます。
@c COMMON
@end defun

@deftp {Class} <mime-part>
@clindex mime-message
@c MOD rfc.mime
@c EN
A structure that encloses metainformation about a MIME part.
It is constructed when the header of the part is read, and
passed to the handler that reads the body of the part.

It has the following slots:
@c JP
MIMEパートのメタ情報を含むストラクチャです。
これは、そのパートのヘッダが読み込まれた時点で構築され、
そのパートのボディを読み込むハンドラに渡されます。

以下のスロットを持ちます。
@c COMMON

@defivar {<mime-part>} type
@c EN
MIME media type string.  If @code{content-type} header is omitted
to the part, an appropriate default value is set.
@c JP
MIMEメディアタイプの文字列。そのパートの@code{content-type}ヘッダが
省略された場合は、適切なデフォルト値がセットされます。
@c COMMON
@end defivar

@defivar {<mime-part>} subtype
@c EN
MIME media subtype string.  If @code{content-type} header is omitted
to the part, an appropriate default value is set.
@c JP
MIMEメディアのサブタイプの文字列。そのパートの@code{content-type}
ヘッダが省略された場合は、適切なデフォルト値がセットされます。
@c COMMON
@end defivar

@defivar {<mime-part>} parameters
@c EN
Associative list of parameters given to @code{content-type} header field.
@c JP
@code{content-type}ヘッダフィールドに渡されるパラメータの連想リスト。
@c COMMON
@end defivar

@defivar {<mime-part>} transfer-encoding
@c EN
The value of @code{content-transfer-encoding} header field.
If the header field is omitted, an appropriate default value is set.
@c JP
@code{content-transfer-encoding}ヘッダフィールドの値。
このヘッダフィールドが省略された場合は、適切なデフォルト値が
セットされます。
@c COMMON
@end defivar

@defivar {<mime-part>} headers
@c EN
The list of header fields, as parsed by @code{rfc822-read-headers}.
@c JP
@code{rfc822-read-headers}によりパーズされた、ヘッダフィールドのリスト。
@c COMMON
@end defivar

@defivar {<mime-part>} parent
@c EN
If this is a part of multipart message or encapsulated message,
points to the enclosing part's @code{<mime-part>} structure.
Otherwise @code{#f}.
@c JP
それがマルチパートメッセージあるいはカプセル化されたメッセージの
パートである場合は、それを含んでいるパートの@code{<mime-part>}
ストラクチャを指します。そうでなければ@code{#f}を返します。
@c COMMON
@end defivar

@defivar {<mime-part>} index
@c EN
Sequence number of this part within the same parent.
@c JP
同じ親を持つパートの中でのそのパートのシーケンス番号。
@c COMMON
@end defivar

@defivar {<mime-part>} content
@c EN
If this part is multipart/* or message/* media type,
this slot contains a list of parts within it.
Otherwise, the return value of @var{handler} is stored.
@c JP
そのパートのメディアタイプがmultipart/*あるいはmessage/*で
ある場合は、このスロットにはそれに含まれるパートのリストが
入っています。そうでなければ、@var{handler}の戻り値が
格納されています。
@c COMMON
@end defivar

@defivar {<mime-part>} source
@c EN
This slot is only used when composing a MIME message.
The caller can set this slot a name of the file to be inserted
into this part, instead of setting the entire content of the
file to the @code{content} slot.   See
@code{mime-compose-message} below for the more details.
@c JP
このスロットはMIMEメッセージを作成する時のみ使われます。
呼び出し元は、このスロットにファイル名をセットすることで、
MIMEメッセージのこのパートにファイルの内容を挿入することができます。
詳しくは下の@code{mime-compose-message}の項を参照してください。
@c COMMON
@end defivar
@end deftp

@defun mime-retrieve-body part-info xport outp
@c MOD rfc.mime
@c EN
A procedure to retrieve message body.  It is intended to
to be a building block of @var{handler} to be passed to
@code{mime-parse-message}.

@var{Part-info} is a @code{<mime-part>} object.
@var{Xport} is an input port passed to the handler,
from which the MIME part can be read.
@c JP
メッセージボディを取得するための手続きです。
@code{mime-parse-message}へ渡される、@var{handler}の
ビルディングブロックとなることを意図しています。

@var{part-info}は、@code{<mime-part>}のオブジェクトです。
@var{xport}はハンドラに渡された入力ポートで、
そこからMIMEパートが読みこまれるものです。

@c EN
This procedure read from @var{xport}
until it returns EOF.  It also looks at the
@code{transfer-encoding} of @var{part-info}, and decodes
the body accordingly; that is, base64 encoding and
quoted-printable encoding is handled.  The result is
written out to an output port @var{outp}.

This procedure does not handle charset conversion.
The caller must use CES conversion port as @var{outp}
(@pxref{Character code conversion}) if desired.
@c JP
この手続きは、@var{xport}からEOFに達するまで読み込み、
@var{part-info}の@code{transfer-encoding}も見て、
ボディを適切にデコードします。つまり、base64やquoted-printable
のエンコーディングは適切に処理されます。結果が出力ポート@var{outp}へと
出力されます。

この手続きは文字集合の変換は扱いません。
必要であれば、呼び出し側が@var{outp}としてCES変換ポートを
使う必要があります(@ref{Character code conversion}参照)。

@c COMMON
@end defun

@c EN
A couple of convenience procedures are defined for typical
cases on top of @code{mime-retrieve-body}.
@c JP
典型的なケースのために、いくつかの便利な手続きが@code{mime-retrieve-body}
の上に定義されています。
@c COMMON

@defun mime-body->string part-info xport
@defunx mime-body->file part-info xport filename
@c MOD rfc.mime
@c EN
Reads in the body of mime message, decoding transfer encoding,
and returns it as a string or writes it to a file, respectively.
@c JP
MIMEメッセージのボディを読み込み、転送(transfer)エンコーディングを
デコードし、それぞれ文字列として返すか、ファイルへ書き出します。
@c COMMON
@end defun

@c EN
The simplest form of MIME message parser would be like this:
@c JP
MIMEメッセージパーザの最もシンプルな使い方は次のように
なります。
@c COMMON

@example
(let ((headers (rfc822-read-headers port)))
  (mime-parse-message port headers
                      (cut mime-body->string <> <>)))
@end example

@c EN
This reads all the message on memory (i.e. the "leaf" @code{<mime-part>}
objects' @code{content} field would hold the part's body as a string),
and returns the top @code{<mime-part>} object.  Content transfer encoding
is recognized and handled, but character set conversion isn't done.

You may want to feed the message body to a file directly,
or even want to skip some body according to mime media types and/or
other header information.  Then you can put the logic in the handler
closure.  That's the reason that this module provides building
blocks, instead of all-in-one procedure.
@c JP
これは、メッセージの全てをメモリに読み込み、
一番上層の@code{<mime-part>}オブジェクトを返します。
(``葉''である@code{<mime-part>}オブジェクトの@code{content}フィールドは、
そのパートのボディを文字列として保持しています。)
内容の転送エンコーディング(content transfer encoding)は認識され処理
されますが、文字集合の変換は行われません。

メッセージボディを直接ファイルに書き出したり、MIMEメディアタイプや
他のヘッダ情報に基づいていくつかのボディをスキップしたいかもしれません。
その場合は、ロジックをハンドラのクロージャに入れることができます。
それが、このモジュールが、オールインワンの手続きではなく、
ビルディングブロックを提供している理由です。
@c COMMON

@subheading Message composer

@defun mime-compose-message parts :optional port :key boundary
@defunx mime-compose-message-string parts :key boundary
@c MOD rfc.mime
Composes a MIME multipart message.  @code{Mime-compose-message}
emits the result to an output port @var{port}, whose default
is the current output port.  @code{Mime-compose-message-string}
makes the result into a string.   You can give a boundary string
via @var{boundary} argument; when omitted, a fresh boundary string
is automatically generated by @code{mime-make-boundary} below.

@code{Mime-compose-message} returns the boundary string.
@code{Mime-compose-message-string} returns two values, the result
string and the boundary string.

The content of the message is provided by the @var{parts} argument,
which can be a list of instances of @code{<mime-part>} (see above)
or lists that describe parts.  The list form is supported for
the caller's convenience, and internally it is converted to
a list of @code{<mime-part>}s.

The syntax of each part element in @var{parts} are defined as follow.

@example
<part>           : <mime-part> | <mime-part-desc>

<mime-part>      : @r{an instance of the class} <mime-part>

<mime-part-desc> : (<content-type> (<header> ...) <body>)
<content-type>   : (<type> <subtype> <header-param> ...)
<header-param>   : (<key> . <value>) ...
<header>         : (<header-name> <encoded-header-value>)
                 | (<header-name> (<header-value> <header-param> ...))
<body>           : @r{a string}
                 | (file <filename>)
                 | (subparts <part> ...)
@end example

Note: In the first form of @code{<header>},
@code{<encoded-header-value>} must already be encoded using RFC2047
or RFC2231 if the original value contains non-ascii characters.
In the second form, we plan to do RFC2231 encoding on behalf of
the caller; but the current version does not implement it.  The
caller should not pass encoded words in this form, since it may
result double-encoding when we implement the auto encoding feature;
for the time being, the second form restricts ASCII-only values.

If @code{<body>} is a string, it is used as the part's content.
If @code{<body>} is @code{(file @var{filename})}, the content is
read from the named file.   If @code{<body>} is
@code{(subparts @var{part} @dots{})}, the part becomes nested
MIME part.

It is the caller's responsibility to give the proper content.
For example, if @code{<body>} is in the third form, the
part must have @code{multipart} content type.

The caller needs to provide proper @code{content-transfer-encoding}
header, depending on the application.  If none is given, the content
is inserted into the message as is, which may be appropriate for
some applications, but if you want to use the result in email
message you certainly want to encode binary part with base64,
for example.
@end defun

@defun mime-make-boundary
@c MOD rfc.mime
@c EN
Returns a unique string that can be used as a boundary of a MIME multipart
message.
@c JP
MIMEマルチパートメッセージのboundaryとして使えるユニークな文字列を返します。
@c COMMON
@end defun


@c ----------------------------------------------------------------------
@node Quoted-printable encoding/decoding, SHA message digest, MIME message handling, Library modules - Utilities
@section @code{rfc.quoted-printable} - Quoted-printable encoding/decoding
@c NODE Quoted-printableエンコーディング, @code{rfc.quoted-printable} - Quoted-printableエンコーディング

@deftp {Module} rfc.quoted-printable
@mdindex rfc.quoted-printable
@c EN
This module defines a few functions to encode/decode Quoted-printable format,
defined in RFC 2045 (@uref{https://www.ietf.org/rfc/rfc2045.txt}), section 6.7.
@c JP
このモジュールでは、RFC 2045 (@uref{https://www.ietf.org/rfc/rfc2045.txt}) の
セクション6.7で定義されている、Quoted-printableフォーマットにエンコード/から
デコードするためのいくつかの関数を定義しています。
@c COMMON
@end deftp

@defun quoted-printable-encode :key line-width binary
@c MOD rfc.quoted-printable
@c EN
Reads byte stream from the current input port, encodes it in Quoted-printable
format and writes the result character stream to the current output port.
The conversion ends when it reads EOF from the current input port.
@c JP
現在の入力ポートからバイトストリームを読み込み、それをQuoted-printable
フォーマットにエンコードし、現在の出力ポートへ結果の文字ストリームを
書き出します。この変換は、現在の入力ポートからEOFを読み出すと終了します。
@c COMMON
@c EN
The keyword argument @var{line-width} specifies the maximum
line width of the generated output in characters.  If the encoded
output creates a long line, the procedure inserts a ``soft line break''
so that the each line is equal to or shorter than this number.
Soft line breaks are removed when quoted-printable text is
decoded.
The default line width is 76.  (The minimum meaningful number of
line-width is 4).  You can suppress soft line breaks by
giving @code{#f} or @code{0} to @var{line-width}.
@c JP
キーワード引数@var{line-width}は、出力に現れる行の最大長を指定します。
エンコードされた行の長さがこの値を越えそうな場合は、「ソフトラインブレーク」が
適宜挿入され、各行の長さがこの値を越えないように調整されます。
ソフトラインブレークはquoted-printableフォーマットのデコード時に
取り除かれます。
@var{line-width}のデフォルト値は76です。(最小の意味のある値は4です。)
@var{line-width}に@code{#f}または@code{0}を渡せば、
ソフトラインブレークは挿入されません。
@c COMMON
@c EN
By default, @code{quoted-printable-encode} generates @code{CR-LF} sequence
for each line break in the input (``hard line break'').
When a true value is given to the keyword argument @var{binary},
however, octets @code{#x0a} and @code{#x0d} in the input are encoded
as @code{=0A} and @code{=0D}, respectively.  See RFC2045 section 6.7
for the details.
@c JP
デフォルトでは、@code{quoted-printable-encode}は入力中の改行に対して
@code{CR-LF}シーケンスを出力します(「ハードラインブレーク」)。
しかし、@var{binary}キーワード引数に真の値が与えられた場合、
入力中のオクテット@code{#x0a}および@code{#x0d}はそれぞれ
@code{=0A}、@code{=0D}のようにエンコードされます。
詳しくはRFC2045の6.7節を参照してください。
@c COMMON
@end defun

@defun quoted-printable-encode-string string :key line-width binary
@c MOD rfc.quoted-printable
@c EN
Converts contents of @var{string} to Quoted-printable encoded format.
Input string can be either complete or incomplete string;
it is always interpreted as a byte sequence.

The keyword arguments are the same as @code{quoted-printable-encode}.
@c JP
@var{string}の内容をQuoted-printableエンコードされたフォーマットに
変換します。入力の文字列は、完全文字列でも不完全文字列でも構いません。
常にバイトシーケンスとして処理されます。

キーワード引数は@code{quoted-printable-encode}と同じです。
@c COMMON
@end defun

@defun quoted-printable-decode
@c MOD rfc.quoted-printable
@c EN
Reads character stream from the current input port,
decodes it from Quoted-printable
format and writes the result byte stream to the current output port.
The conversion ends when it reads EOF.
If it encounters illegal character sequence (such as '=' followed
by non-hexadecimal characters), it copies them literally to the output.
@c JP
現在の入力ポートから文字ストリームを読み込み、それをQuoted-printable
フォーマットからデコードし、結果のバイトストリームを現在の出力ポートへ
書き出します。
この変換は、EOFを読み出すと終了します。
不正なシーケンス('='の後に16進文字が続かない、など)に出会うと、それらを
リテラルのまま出力へコピーします。
@c COMMON
@end defun

@defun quoted-printable-decode-string string
@c MOD rfc.quoted-printable
@c EN
Decodes a Quoted-printable encoded string @var{string} and returns
the result as a string.
@c JP
Quoted-printableエンコードされた文字列@var{string}をデコードし、
その結果を文字列で返します。
@c COMMON
@end defun

@c ----------------------------------------------------------------------
@node SHA message digest, Transport layer security, Quoted-printable encoding/decoding, Library modules - Utilities
@section @code{rfc.sha} - SHA message digest
@c NODE SHAメッセージダイジェスト, @code{rfc.sha} - SHAメッセージダイジェスト

@deftp {Module} rfc.sha
@mdindex rfc.sha
@c EN
This module implements US Secure Hash Algorithm
defined in RFC 4634.  It provides SHA-1, SHA-224, SHA-256,
SHA-384 and SHA-512 (the latter four are sometimes referred
as SHA-2 collectively).

The module extends util.digest
(@pxref{Message digester framework}).
@c JP
このモジュールは、RFC 4634で定義されている
US Secure Hash Algorithmを実装しています。
提供されるアルゴリズムはSHA-1, SHA-224, SHA-256, SHA-384および
SHA-512です (後の4つを総称してSHA-2と呼ぶこともあります)。

このモジュールは、util.digest (@ref{Message digester framework}参照)
を拡張しています。
@c COMMON
@end deftp

@deftp {Module} rfc.sha1
@mdindex rfc.sha1
@c EN
This is the old module that provided only SHA-1.  It is kept as
an alias of @code{rfc.sha} for the backward compatibility.  New code
should use @code{rfc.sha}.
@c JP
これはSHA-1だけを提供していた古いモジュールです。互換性のため、
この名前は@code{rfc.sha}の別名として残されています。
新たに書くコードは@code{rfc.sha}を使ってください。
@c COMMON
@end deftp


@deftp {Class} <sha1>
@deftpx {Class} <sha224>
@deftpx {Class} <sha256>
@deftpx {Class} <sha384>
@deftpx {Class} <sha512>
@clindex sha1
@clindex sha224
@clindex sha256
@clindex sha384
@clindex sha512
@c MOD rfc.sha
@c EN
An instance of these class keeps internal state of SHA digest algorithm.

This class implements @code{util.digest} framework interface,
@code{digest-update!}, @code{digest-final!},
@code{digest}, and @code{digest-string}.
@xref{Message digester framework}, for detailed explanation
of these methods.
@c JP
これらのクラスのインスタンスは、SHAダイジェストアルゴリズムの内部状態を
保持しています。

このクラスは、@code{util.digest}フレームワークのインターフェース、
@code{digest-update!}、@code{digest-final!}、@code{digest}、
@code{digest-string}を実装しています。
これらのメソッドの詳細な説明は、@ref{Message digester framework}を
参照して下さい。
@c COMMON
@end deftp

@c EN
Besides the digester framework, this module provides to
short-cut procedures.
@c JP
ダイジェスタフレームワークに加えて、このモジュールはショートカット
手続きを提供します。
@c COMMON

@defun sha1-digest
@defunx sha224-digest
@defunx sha256-digest
@defunx sha384-digest
@defunx sha512-digest
@c MOD rfc.sha
@c EN
Reads data from the current input port until EOF, and returns
its digest in an incomplete string.
@c JP
現在の入力ポートからデータをEOFまで読み込み、そのダイジェストを
不完全文字列で返します。
@c COMMON
@end defun

@defun sha1-digest-string string
@defunx sha224-digest-string string
@defunx sha256-digest-string string
@defunx sha384-digest-string string
@defunx sha512-digest-string string
@c MOD rfc.sha
@c EN
Digest the data in @var{string}, and returns the result
in an incomplete string.
@c JP
@var{string}のデータをダイジェストし、その結果を不完全文字列で
返します。
@c COMMON
@end defun

@c ----------------------------------------------------------------------
@node Transport layer security, URI parsing and construction, SHA message digest, Library modules - Utilities
@section @code{rfc.tls} - Transport layer security
@c NODE トランスポート・レイヤ・セキュリティ, @code{rfc.tls} - トランスポート・レイヤ・セキュリティ

@deftp {Module} rfc.tls
@mdindex rfc.tls
@c EN
This module handles secure connection over TCP socket.
This module is used by @code{rfc.http} to realize https connection
(@pxref{HTTP}).
@c JP
このモジュールはTCPソケット上のセキュアな接続を処理します。
@code{rfc.http}で、https接続を実現するのに使われています
(@ref{HTTP}参照)。
@c COMMON
@end deftp

@subheading CA certificates

@c EN
You need CA certificates to verify server certificates properly.
Gauche doesn't have its own CA certificates, and relies on the
system's certificate store by default.  On Unix-based systems,
we search several known locations: On popular Linux distributions
we recommend you to install @code{ca-certificates} package (or similar one).
On OSX, we recommend to install openssl via Homebrew.  On Windows,
we use system's certificate store via Wincrypt API.
@c JP
サーバの認証を適切に行うためには、CA証明書が必要です。
Gaucheは自前でCA証明書を持っておらず、デフォルトでシステムのCA証明書バンドルを利用します。
Unixベースのシステムでは、いくつかのよくあるパスを探索します。
例えばLinuxディストリビューションなら@code{ca-certificates}やそれに類する
パッケージをインストールしておくと良いでしょう。
OSXではopensslをHomebrewでインストールしておくのをおすすめします。
WindowsではWincrypt API経由でシステムの証明書ストアを使います。
@c COMMON

@c EN
With the default configuration, Gauche checks the availability of the system's
certificate store at initilization and use one if available.  You can explicitly
give the path of CA certificate bundle, or disable it and provide
individual certificate per connection.
@c JP
デフォルトのコンフィグレーションでは、Gaucheは初期化時にシステムのCA証明書バンドルを探し、
見つかればそれを使うようになっています。かわりとなるCA証明書バンドルのパスを指定したり、
接続毎に独自の証明書を与えることもできます。
@c COMMON

@c EN
If, for some reasons, you cannot install system-wide CA certificate bundle,
you can also download Curl's CA certificate bundle 
@url{https://curl.haxx.se/ca/cacert.pem}, and install it in
Gauche installation directory.  We have a convenience script.
After installing Gauche, run the following command:
@c JP
もし、何らかの理由で、システム全体で使えるCA証明書バンドルがインストールできない場合、
独自にCurlのCA証明書バンドルを@url{https://curl.haxx.se/ca/cacert.pem}から
ダウンロードしてGaucheのインストールディレクトリに置いておくことができます。
便利なスクリプトが用意してあります。
Gaucheをインストールした後、次のコマンドを実行してください。
@c COMMON

@example
gosh rfc/tls/get-cacert.scm
@end example

@c EN
You need curl installed on your system.  If you've installed
Gauche with root priviledge, you'll be asked sudo password to install
the CA bundle file.

If you decided to do this, make sure you run the above command occasionally
to get updated CA certificate bundles, for certificates may expire or
be revoked.
@c JP
curlがシステムにインストールされている必要があります。また、Gaucheをインストールする時に
root権限で行ったのであれば、このコマンドがCA証明書バンドルをインストールする時に
sudoのパスワードを尋ねるでしょう。

もしこの方法を取ることに決めたなら、時々このコマンドを実行してCA証明書バンドルを
最新版に更新するのを忘れないようにしてください。
CA証明書は期限が切れたり無効化されることがあります。
@c COMMON

@deffn {Parameter} tls-ca-bundle-path :optional path
@c MOD rfc.tls
@c EN
Holds CA certificate bundle to be used.  The value
can be either a string path to a CA bundle file, a symbol @code{system},
or @code{#f}.
@c JP
CA証明書バンドルのパスを保持しています。値は、CA証明書バンドルファイルの
パス名、シンボル@code{system}、あるいは@code{#f}のいずれかです。
@c COMMON

@c EN
If it is @code{system}, Gauche uses system's default bundle.  
An error is signaled on connection
if Gauche can't find one.
@c JP
この値が@code{system}の場合、Gaucheはシステムのデフォルトの証明書バンドルを
使おうとします。もしそれが見つからなければ接続時にエラーが報告されます。
@c COMMON

@c EN
If it is @code{#f}, CA certificate won't be loaded automatically,
and you have to manually load one using @code{tls-load-object}.
(Note: This option is only valid with @code{<ax-tls>}.  If you're using
@code{<mbed-tls>}, you need valid CA certificate bundle.)
@c JP
この値が@code{#f}の場合、CA証明書は自動的にロードされないので、
@code{tls-load-object}を使って自分で適切な証明書をロードしてやる必要があります。
(このオプションは@code{<ax-tls>}のみ有効です。
@code{<mbed-tls>}を使う場合は、必ず有効なCA証明書バンドルが必要です。)
@c COMMON

@c EN
With the default configuration, Gauche scans the system CA bundle
when @code{rfc.tls} module is initialized, and if it finds one,
@code{tls-ca-bundle-path} is set to @code{system}; otherwise,
@code{tls-ca-bundle-path} is set to @code{#f}.  So if you're using
with default configuration and you see its value is @code{system},
you can count on the system CA certificate bundle.
@c JP
デフォルトのコンフィグレーションでは、Gaucheは@code{rfc.tls}モジュール初期化時に
システムのCA証明書バンドルが使えるかどうか調べて、使えるなら@code{tls-ca-bundle-path}の
初期値を@code{system}に、使えないなら@code{#f}にセットします。
したがって、デフォルトのコンフィグレーションで使っている限り、
この値が@code{system}であればシステムのCA証明書を使えると考えて良いでしょう。
@c COMMON

@c EN
This default behavior may be altered if Gauche is configured
with @code{--with-ca-bundle} option.  You can execute
@code{gauche-config --reconfigure} command to see if
special @code{--with-ca-bundle} option is given.
@c JP
このデフォルトの振る舞いはconfigure時に@code{--with-ca-bundle}オプションで
変えられます。使っているGaucheのコンフィグレーションが変えられているかどうかは、
@code{gauche-config --reconfigure}コマンドを実行して@code{--with-ca-bundle}
オプションがあるかどうかを見ればわかります。
@c COMMON
@end deffn


@subheading Supported TLS subsystems

@c EN
Gauche supports two TLS subsystems - one based on AxTLS
(@url{http://axtls.sourceforge.net/}), and the other based on
MbedTLS (@url{https://tls.mbed.org/}).  Whether they're included
depends on the configuration options.  By default, AxTLS support
is compiled in, and MbedTLS support is included if the build
platform has MbedTLS library installed. 
@c JP
Gaucheは二つのTLSサブシステムをサポートしています。
ひとつはAxTLS(@url{http://axtls.sourceforge.net/})、
もうひとつはMbedTLS(@url{https://tls.mbed.org/})です。
configureのオプションによって組み込まれるものが変わりますが、
デフォルトではAxTLSは常に組み込まれ、
MbedTLSはビルド時にシステムにインストールされていれば組み込まれます。
@c COMMON

@c EN
AxTLS library has advanage of being included in Gauche, so that
it won't depend on external library, however, its supported ciphers
are limited, and it can't connect to some https sites.  MbedTLS has
wider cipher support, but it requires MbedTLS dynamic libraries
(e.g. @file{libmbedtls.so}) at runtime.
@c JP
AxTLSライブラリはGaucheの一部としてコンパイルされるので、
使うのに外部ライブラリに依存しないという利点がありますが、
サポートしている暗号スイートが限られていて、時々接続できないhttpsサイトがあります。
一方、MbedTLSは幅広い暗号スイートをサポートしていますが、実行時に
MbedTLSの動的ライブラリ(@file{libmbedtls.so}など)を必要とします。
@c COMMON

@c EN
Gauche chooses available TLS subsystem at runtime, so the user usually
does not need to worry about the difference.  If you're building Gauche
by yourself, we recommend to use the default configuration, on a system
that has MbedTLS installed.   That will give you the most flexible choice.
@c JP
Gaucheは実行時に使える範囲で適切なTLSサブシステムを選択するので、
ユーザが違いを意識する必要はほとんどありません。自分でGaucheをビルドする場合は、
MbedTLSがインストールされた環境で、デフォルトのコンフィグレーションでビルドすることを
推奨します。それが最も柔軟な選択となるでしょう。
@c COMMON

@c EN
Whether the running Gauche has any of TLS support can be checked with
a feature identifier @code{gauche.net.tls}.  Availability of each
individual subsystems can be checked with feature identifiers
@code{gauche.net.tls.axtls} and @code{gauche.net.tls.mbedtls}, respectively.
@xref{Feature conditional}, for more about feature identifiers.
@c JP
Gaucheに何らかのTLSサポートが組み込まれているかどうかは機能識別子
@code{gauche.net.tls}で、それぞれのサブシステムが使えるかどうかは
機能識別子@code{gauche.net.tls.axtls}と@code{gauche.net.tls.mbedtls}で
検査できます。機能識別子については@ref{Feature conditional}を参照してください。
@c COMMON

@deftp {Class} <tls>
@clindex tls
@c MOD rfc.tls
An abstract base class of TLS implementations.
@end deftp

@deftp {Class} <ax-tls>
@clindex ax-tls
@c MOD rfc.tls
A class that implements axTLS subsystem interface.
@end deftp

@deftp {Class} <mbed-tls>
@clindex mbed-tls
@c MOD rfc.tls
A class that implements mbedTLS subsystem interface.
@end deftp

@deffn {Parameter} default-tls-class :optional class
@c MOD rfc.tls
Set/get the default TLS subsystem to be used.  Without arguments, it
return a class (either @code{<ax-tls>} or @code{<mbed-tls>} to be used.
With one argument, which must be either @code{<ax-tls>} or @code{<mbed-tls>},
changes the default and returns the previous value.
@end deffn

@subheading TLS interface

@defun make-tls initargs @dots{}
@c MOD rfc.tls
Creates and returns a new TLS instance of the class @code{default-tls-class}.
The returned TLS instance can be used for the tls procedures below.

The arguments must be a keyword-value list, and passed to the constructor
of the TLS class.

@table @code
@item :server-name
Server name to be used for TLS Server Name Indication extension.
@item :num-sessions
[AxTLS only]
The number of sessions ot be used for session caching.
0 indicates no sessino caching. 
@item :options
[AxTLS only]
Bitflags of options.  Logical OR of the following numeric constants.
@end table

@table @code
@item SSL_SERVER_VERIFY_LATER
(client only) Let handshake success even the server authentication fails.
@item SSL_CLIENT_AUTHENTICATION
(server only) Request client sertificate to be authenticated.
@end table
@end defun

@defun tls-connect tls socket
@c MOD rfc.tls
Establishes TLS connection as a client.  The @var{tls} argument must
be an unconnected TLS object, and the @var{socket} argument must
be a @emph{connected} socket.  On success, it returns @var{tls},
which is in connected state.  It can be used to read/write data
from/to the connected peer.

The @var{socket} is owned by @var{tls} object and should not be directly
accessed after calling this procedure.
@end defun

@defun tls-accept tls socket
@c MOD rfc.tls
Establishes TLS connection as a server.  The @var{tls} argument must
be an unconnected TLS object, and the @var{socket} argument must
be a @emph{listening} socket.  On success, it returns @var{tls},
which is in connected state.  It can be used to read/write data
from/to the connected peer.
@end defun

@defun tls-close tls
@c MOD rfc.tls
Shuts down the underling connection.  The peer will notified
the connection is closed.
Once @var{tls} is closed, it can no longer be used, but the reosurces
won't be collected until @var{tls} is GC-ed or @code{tls-destroy} is
called.  We recommend the user call @code{tls-destroy} explicitly.
@end defun

@defun tls-destroy tls
@c MOD rfc.tls
Releases resources associated to @var{tls}.
@end defun

@defun tls-input-port tls
@defunx tls-output-port tls
@c MOD rfc.tls
If @var{tls} is connected, it returns input and output port to communicate
with the peer, respectively.

If @var{tls} is not connected, @code{#f} is returned.
@end defun

@defun tls-load-object tls type filename :optional password
@c MOD rfc.tls
This procedure is only meaningful for @code{<axl-tls>}.  For @code{<mbed-tls>},
this procedure does nothing.

Load private keys or certificates stored in a file specified by
@var{filenames}.  The type of object is specified by @var{type}
argument with one of the following numberic constants.  If the file
requires a password, it should be given to @var{password}.

@table @code
@item SSL_OBJ_X509_CERT
@item SSL_OBJ_X509_CACERT
@item SSL_OBJ_RSA_KEY
@item SSL_OBJ_PKCS8
@item SSL_OBJ_PKC12
@end table
@end defun

@defvr {Constant} SSL_OBJ_X509_CERT
@defvrx {Constant} SSL_OBJ_X509_CACERT
@defvrx {Constant} SSL_OBJ_RSA_KEY
@defvrx {Constant} SSL_OBJ_PKCS8
@defvrx {Constant} SSL_OBJ_PKCS12
@c MOD rfc.tls
@end defvr

@c ----------------------------------------------------------------------
@node URI parsing and construction, UUID, Transport layer security, Library modules - Utilities
@section @code{rfc.uri} - URI parsing and construction
@c NODE URIの解析と作成, @code{rfc.uri} - URIの解析と作成

@deftp {Module} rfc.uri
@mdindex rfc.uri
@c EN
Provides a set of procedures to parse and construct Uniform Resource Identifiers
defined in RFC 2396 (@uref{https://www.ietf.org/rfc/rfc2396.txt}),
as well as Data URI scheme defined in RFC2397.
@c JP
RFC 2396 (@uref{https://www.ietf.org/rfc/rfc2396.txt})で定義されている
Uniform Resource Identifiers、
またRFC 2397で定義されているData URI Schemeをパーズおよび構築する
手続き群を提供します。
@c COMMON
@end deftp

First, lets review the structure of URI briefly.
The following graph shows how the URI is constructed:

@example
URI-+-scheme
    |
    +-specific--+--authority-+--userinfo
                |            +--host
                |            +--port
                +--path
                +--query
                +--fragment
@end example

Not all URIs have this full hierarchy.  For example,
@code{mailto:admin@@example.com} has only @emph{scheme} (@code{mailto})
and @emph{specific} (@code{admin@@example.com}) parts.

Most popular URI schemes, however, organize resources
in a tree, so they adopt @emph{authority} (which usually identifies
the server) and the hierarchical @emph{path}.  In the URI
@code{http://example.com:8080/search?q=key#results}, the authority
part is @code{example.com:8080}, the path is @code{/search},
the query is @code{key} and the fragment is @code{results}.
The userinfo can be provided before hostname, such as @code{anonymous}
in @code{ftp://anonymous@@example.com/pub/}.

We have procedures that decompose a URI into those parts,
and that compose a URI from those parts.

@c EN
@subheading Parsing URI
@c JP
@subheading URIのパーズ
@c COMMON

@defun uri-ref uri parts
@c MOD rfc.uri
Extract specific part(s) from the given URI.  You can fully
decompose URI by the procedures described below, but in actual
applications, you often need only some of the parts.  This procedure
comes handy for it.

The @var{parts} argument may be a symbol, or a list of symbols,
to name the desired parts.  The recognized symbos are as follows.

@table @code
@item scheme
The scheme part, as string.
@item authority
The authority part, as string.
If URI doesn't have the part, @code{#f}.
@item userinfo
The userinfo part, as string.  If URI doesn't have the part, @code{#f}.
@item host
The host part, as string.  If URI doesn't have the part, @code{#f}.
@item port
The port part, as integer.  If URI doesn't have the part, @code{#f}.
@item path
The path part, as string.  If URI isn't hierarchical, this returns
the specific part.
@item query
The query part, as string. If URI doesn't have the part, @code{#f}.
@item fragment
The fragment part, as string.  If URI doesn't have the part, @code{#f}.
@item scheme+authority
The scheme and authority part.
@item host+port
The host and port part.
@item userinfo+host+port
The userinfo, host and port part.
@item path+query
The path and query part.
@item path+query+fragment
The path, query and fragment part.
@end table

@example
(define uri "http://foo:bar@@example.com:8080/search?q=word#results")

(uri-ref uri 'scheme)             @result{} "http"
(uri-ref uri 'authority)          @result{} "//foo:bar@@example.com:8080/"
(uri-ref uri 'userinfo)           @result{} "foo:bar"
(uri-ref uri 'host)               @result{} "example.com"
(uri-ref uri 'port)               @result{} 8080
(uri-ref uri 'path)               @result{} "/search"
(uri-ref uri 'query)              @result{} "q=word"
(uri-ref uri 'fragment)           @result{} "results"
(uri-ref uri 'scheme+authority)   @result{} "http://foo:bar@@example.com:8080/"
(uri-ref uri 'host+port)          @result{} "example.com:8080"
(uri-ref uri 'userinfo+host+port) @result{} "foo:bar@@example.com:8080"
(uri-ref uri 'path+query)         @result{} "/search?q=word"
(uri-ref uri 'path+query+fragment)@result{} "/search?q=word#results"
@end example

You can extract multiple parts at once by specifying a list of parts.
A list of parts is returned.

@example
(uri-ref uri '(host+port path+query))
  @result{} ("example.com:8080" "/search?q=word")
@end example
@end defun


@defun uri-parse uri
@defunx uri-scheme&specific uri
@defunx uri-decompose-hierarchical specific
@defunx uri-decompose-authority authority
@c MOD rfc.uri
@c EN
General parser of URI.  These functions does not decode
URI encoding, since the parts to be decoded differ among
the uri schemes.   After parsing uri, use @code{uri-decode} below
to decode them.
@c JP
URIの一般的なパーザです。これらの関数はURIエンコーディングを
デコードしません。URIスキームによってどの部分をデコードすべきかが
異なるからです。パージングを行った後に、後述の@code{uri-decode}等を
使ってデコードを行ってください。
@c COMMON

@c EN
@code{uri-parse} is the most handy procedure.  It breaks the uri
into the following parts and returns them as multiple values.
If the uri doesn't have the corresponding
parts, @code{#f} are returned for the parts.

@itemize @bullet
@item
URI scheme as a string
(e.g. @code{"mailto"} in @code{"mailto:foo@@example.com"}).
@item
User-info in the authority part (e.g. @code{"anonymous"}
in @code{ftp://anonymous@@ftp.example.com/pub/foo}).
@item
Hostname in the authority part (e.g. @code{"ftp.example.com"}
in @code{ftp://anonymous@@ftp.example.com/pub/foo}).
@item
Port number in the authority part, as an integer (e.g. @code{8080}
in @code{http://www.example.com:8080/}).
@item
Path part (e.g. @code{"/index.html"} in
@code{http://www.example.com/index.html}).
@item
Query part (e.g. @code{"key=xyz&lang=en"} in
@code{http://www.example.com/search?key=xyz&lang=en}).
@item
Fragment part (e.g. @code{"section4"} in
@code{http://www.example.com/document.html#section4}).
@end itemize
@c JP
@code{uri-parse}は最も手軽な手続きで、uriを以下に示す部分に
分割し、多値で返します。
もし該当する部分がuriに無かった場合は、その部分には@code{#f}が返ります。
@itemize @bullet
@item
URIスキームを文字列で。
(例： @code{"mailto:foo@@example.com"}の@code{"mailto"})。
@item
authorityパートのuser-infoを文字列で。
(例： @code{ftp://anonymous@@ftp.example.com/pub/foo}の@code{"anonymous"})。
@item
authorityパートのhostnameを文字列で。
(例： @code{ftp://anonymous@@ftp.example.com/pub/foo}の
@code{"ftp.example.com"})。
@item
authorityパートのport番号を整数で。
(例： @code{http://www.example.com:8080/}の@code{8080})。
@item
pathパート。
(例： @code{http://www.example.com/index.html}の@code{"/index.html"})。
@item
queryパート。
(例： @code{http://www.example.com/search?key=xyz&lang=en}の
@code{"key=xyz&lang=en"})。
@item
fragmentパート。
(例： @code{http://www.example.com/document.html#section4}の
@code{"section4"})。
@end itemize
@c COMMON

@c EN
The following procedures are finer grained and break up
uris with different stages.
@c JP
以下の手続きはより詳細に、段階をふんでuriを分割してゆくものです。
@c COMMON

@c EN
@code{uri-scheme&specific} takes a URI @var{uri}, and
returns two values, its scheme part and its scheme-specific part.
If @var{uri} doesn't have a scheme part, @code{#f} is returned for it.
@c JP
@code{uri-scheme&specific} は URI @var{uri} を引数に取り、
スキーム部分と、そのスキーム特有の部分を表す2つの値を返します。
@var{uri} がスキーム部分を持たない場合、@code{#f} を返します。
@c COMMON
@example
(uri-scheme&specific "mailto:sclaus@@north.pole")
  @result{} "mailto" @r{and} "sclaus@@north.pole"
(uri-scheme&specific "/icons/new.gif")
  @result{} #f @r{and} "/icons/new.gif"
@end example

@c EN
If the URI scheme uses hierarchical notation, i.e.
``@code{//@var{authority}/@var{path}?@var{query}#@var{fragment}}'',
you can pass
the scheme-specific part to @code{uri-decompose-hierarchical}
and it returns four values, @var{authority}, @var{path}, @var{query}
and @var{fragment}.
@c JP
URI が階層的な記法を用いている場合、すなわち、
``@code{//@var{authority}/@var{path}?@var{query}#@var{fragment}}''
のような場合、スキーム特有の部分を @code{uri-decompose-hierarchical}
に渡すと、@var{authority}、@var{path}、@var{query}、@var{fragment}
の4つの値が返ります。
@c COMMON
@example
(uri-decompose-hierarchical "//www.foo.com/about/company.html")
  @result{} "www.foo.com"@r{,} "/about/company.html"@r{,} #f @r{and} #f
(uri-decompose-hierarchical "//zzz.org/search?key=%3fhelp")
  @result{} "zzz.org"@r{,} "/search"@r{,} "key=%3fhelp" @r{and} #f
(uri-decompose-hierarchical "//jjj.jp/index.html#whatsnew")
  @result{} "jjj.jp"@r{,} "/index.html"@r{,} #f @r{and} "whatsnew"
(uri-decompose-hierarchical "my@@address")
  @result{} #f@r{,} #f@r{,} #f @r{and} #f
@end example

@c EN
Furthermore, you can parse @var{authority} part of the
hierarchical URI by @code{uri-decompose-authority}.
It returns @var{userinfo}, @var{host} and @var{port}.
@c JP
さらに、階層的 URI の @var{authority} の部分を
@code{uri-decompose-authority} に渡すと、@var{userinfo}、
@var{host}、@var{port} が返ります。
@c COMMON
@example
(uri-decompose-authority "yyy.jp:8080")
  @result{} #f@r{,} "yyy.jp" @r{and} "8080"
(uri-decompose-authority "[::1]:8080")  ;@r{(IPv6 host address)}
  @result{} #f@r{,} "::1" @r{and} "8080"
(uri-decompose-authority "mylogin@@yyy.jp")
  @result{} "mylogin"@r{,} "yyy.jp" @r{and} #f
@end example
@end defun


@defun uri-decompose-data uri
@c MOD rfc.uri
@c EN
Parse a Data URI string @var{uri}.  You can either pass the entire
uri including @code{data:} scheme part, or just the specific part.
If the passed uri is invalid as a data uri, an error is signalled.

Returns two values: parsed content type and the decoded data.
The data is a string if the content type is @code{text/*}, and
a u8vector otherwise.

The content-type is parsed by @code{mime-parse-content-type}
(@pxref{MIME message handling}).  The result format is a list as follows:
@c JP
Data URI文字列@var{uri}をパーズします。@code{data:}スキームは有っても無くても
構いません。渡されたuriがdata uriとして無効な文字列であればエラーが投げられます。

二つの値、パーズされたContent-Typeおよびデコードされたデータを返します。
Content-Typeが@code{text/*}であればデコードされたデータは文字列で、
そうでなければu8vectorで返されます。

Content-Typeは@code{mime-parse-content-type}でパーズされます
(@ref{MIME message handling}参照)。結果のデータ形式は次のようなリストです。
@c COMMON

@example
@code{(@i{type} @i{subtype} (@i{attribute} . @i{value}) @dots{})}.
@end example

@c EN
Here are a couple of examples:
@c JP
いくつか例を示します。
@c COMMON

@example
(uri-decompose-data
 "data:text/plain;charset=utf-8;base64,KGhlbGxvIHdvcmxkKQ==")
  @result{} ("text" "plain" ("charset" . "utf-8")) @r{and} "(hello world)"

(uri-decompose-data
 "data:application/octet-stream;base64,AAECAw==")
  @result{} ("application" "octet-stream") @r{and} #u8(0 1 2 3)
@end example

@end defun


@c EN
@subheading Constructing URI
@c JP
@subheading URIの構築
@c COMMON

@defun uri-compose :key scheme userinfo host port authority path path* query fragment specific
@c MOD rfc.uri
@c EN
Compose a URI from given components.
There can be various combinations of components to create a valid
URI---the following diagram shows the possible 'paths' of
combinations:
@c JP
与えられたコンポーネントから URI を構成します。
妥当な URI を作成するためのコンポーネントの組み合わせはたくさんあります。
以下のダイアグラムは、考え得る組み合わせの方法を示しています。
@c COMMON

@example
        /-----------------specific-------------------\
        |                                            |
 scheme-+------authority-----+-+-------path*---------+-
        |                    | |                     |
        \-userinfo-host-port-/ \-path-query-fragment-/
@end example

@c EN
If @code{#f} is given to a keyword argument, it is
equivalent to the absence of that keyword argument.
It is particularly useful to pass the results of
parsed uri.

If a component contains a character that is not appropriate
for that component, it must be properly escaped before
being passed to @code{url-compose}.

Some examples:
@c JP
キーワード引数に @code{#f} が与えられた場合、それはキーワード引数が
指定されないことと等価です。これは URI をパーズした結果を渡す場合に
特に有用です。

コンポーネントに適切でない文字が含まれている場合は、
@code{url-compose} に渡す前に正しくエスケープされなければなりません。

いくつかの例を示します。
@c COMMON
@example
(uri-compose :scheme "http" :host "foo.com" :port 80
             :path "/index.html" :fragment "top")
  @result{} "http://foo.com:80/index.html#top"

(uri-compose :scheme "http" :host "foo.net"
             :path* "/cgi-bin/query.cgi?keyword=foo")
  @result{} "http://foo.net/cgi-bin/query.cgi?keyword=foo"

(uri-compose :scheme "mailto" :specific "a@@foo.org")
  @result{} "mailto:a@@foo.org"

(receive (authority path query fragment)
   (uri-decompose-hierarchical "//foo.jp/index.html#whatsnew")
 (uri-compose :authority authority :path path
              :query query :fragment fragment))
  @result{} "//foo.jp/index.html#whatsnew"
@end example
@end defun


@defun uri-merge base-uri relative-uri relative-uri2 @dots{}
@c MOD rfc.uri
@c EN
Arguments are strings representing
full or part of URIs.  This procedure resolves @var{relative-uri}
in relative to @var{base-uri}, as defined in RFC3986 Section 5.2.
``Relative Resolution''.

If more @var{relative-uri2}s are given, first @var{relative-uri}
is merged to @var{base-uri}, then the next argument is merged
to the resulting uri, and so on.
@c JP
引数は、完全な、あるいは部分的なURIを表す文字列です。
この手続きは、RFC3986 Section 5.2. ``Relative Resolution'' に
示されるアルゴリズムに従い、@var{relative-uri}を@var{base-uri}からの相対
として解決します。

@var{relative-uri2} @dots{} が与えられた場合は、まず@var{relative-uri}
が@var{base-uri}を基準に解決され、その結果を新たな基準として次の
@var{relative-uri2}を解決し、以下同様に続けます。
@c COMMON

@example
(uri-merge "http://example.com/foo/index.html" "a/b/c")
 @result{} "http://example.com/foo/a/b/c"

(uri-merge "http://example.com/foo/search?q=abc" "../about#me")
 @result{} "http://example.com/about#me"

(uri-merge "http://example.com/foo" "http://example.net/bar")
 @result{} "http://example.net/bar"

(uri-merge "http://example.com/foo/" "q" "?xyz")
 @result{} "http://example.com/foo/q?xyz"
@end example
@end defun

@defun uri-compose-data data :key content-type encoding
@c MOD rfc.uri
@c EN
Creates a Data URI of the given @var{data}, with specified content-type
and transfer encoding.  Returns a string.

The @var{data} argument must be a string or a u8vector.

The @var{content-type} argument can be @code{#f} (default),
a string that represents a content type (e.g. @code{"text/plain;charset=utf-8"}),
or a list form of parsed content type
(e.g. @code{("application" "octet-stream")}.  If it is @code{#f},
@code{text/plain} with the gauche's native character encoding is
used when @var{data} is a complete string, and @code{application/octet-stream}
is used otherwise.

The @var{encoding} argument can be either @code{#f} (default),
or a symbol @code{uri} or @code{base64}.  This is for transfer encoding,
not character encoding.  If it is @code{#f}, URI encoding is used
for text data and base64 encoding is used for binary data.
@c JP
与えられた@var{data}からData URIを構築して文字列で返します。

@var{data}引数は文字列かu8vectorでなければなりません。

@var{content-type}キーワード引数は、@code{#f} (デフォルト)、
content typeを表現する文字列 (例: @code{"text/plain;charset=utf-8"})、
もしくはパーズされたcontent type (例: @code{("application" "octet-stream")})です。
@code{#f}である場合は、@var{data}が完全な文字列であれば
@code{text/plain}にGaucheのネイティブ文字エンコーディングに基づく@code{charset}を
つけたもの、@var{data}がそれ以外であれば@code{application/octet-stream}が
使われます。

@var{encoding}キーワード引数は@code{#f} (デフォルト)、
もしくはシンボル@code{uri}または@code{base64}です。これは文字エンコーディングではなく
トランスファーエンコーディングであることに注意。
@code{#f}の場合は、テキストデータなら@code{uri}が、バイナリデータなら@code{base64}が
使われます。
@c COMMON

@example
(uri-compose-data "(hello world)")
 @result{} "data:text/plain;charset=utf-8,%28hello%20world%29"

(uri-compose-data "(hello world)" :encoding 'base64)
 @result{} "data:text/plain;charset=utf-8;base64,KGhlbGxvIHdvcmxkKQ=="

(uri-compose-data '#u8(0 1 2 3))
 @result{} "data:application/octet-stream;base64,AAECAw=="
@end example
@end defun


@c EN
@subheading URI Encoding and decoding
@c JP
@subheading URIのエンコードとデコード
@c COMMON

@defun uri-decode :key :cgi-decode
@defunx uri-decode-string string :key :cgi-decode :encoding
@c MOD rfc.uri
@c EN
Decodes ``URI encoding'', i.e. @code{%}-escapes.
@code{uri-decode} takes input from the current input port,
and writes decoded result to the current output port.
@code{uri-decode-string} takes input from @var{string} and
returns decoded string.

If @var{cgi-decode} is true, also replaces @code{+} to a space character.

To @code{uri-decode-string} you can provide the external character
encoding by the @var{encoding} keyword argument.  When it is given,
the decoded octet sequence is assumed to be in the specified encoding
and converted to the Gauche's internal character encoding.
@c JP
URI エンコーディング、すなわち、@code{%}でエスケープされた URI 文字列を
デコードします。@code{uri-decode} は現在の入力ポートから入力を受け取り、
デコードした結果を現在の出力ポートに書き出します。
@code{uri-decode-string} は @var{string} を入力とし、デコードした
文字列を返します。

@var{cgi-decode} が真の場合は、@code{+} がスペース文字に置換されます。

@code{uri-decode-string}には、外部の文字エンコーディングを指定する
@var{encoding}キーワード引数を与えることができます。この引数が与えれた
場合、デコードされたオクテットの列を指定された文字エンコーディングであると
してGaucheの内部文字エンコーディングへと変換したものが返されます。
@c COMMON
@end defun

@defun uri-encode :key :noescape
@defunx uri-encode-string string :key :noescape :encoding
@c MOD rfc.uri
@c EN
Encodes unsafe characters by @code{%}-escape.  @code{uri-encode}
takes input from the current input port and writes the result to
the current output port.  @code{uri-encode-string} takes input
from @var{string} and returns the encoded string.

By default, characters that are not specified ``unreserved'' in
RFC3986 are escaped.  You can pass different character
set to @var{noescape} argument to keep from being encoded.
For example, the older RFC2396 has several more ``unreserved''
characters, and passing @code{*rfc2396-unreserved-char-set*} (see below)
prevents those characters from being escaped.

The multibyte characters are encoded as the octet stream of Gauche's
native multibyte representation by default.  However, you can pass
the @code{encoding} keyword argument to @code{uri-encode-string},
to convert @var{string} to the specified character encoding.
@c JP
安全でない文字を、@code{%}によるエスケープでエンコードします。
@code{uri-encode} は現在の入力ポートから入力を受け取り、
結果を現在の出力ポートに書き出します。
@code{uri-encode-string} は @var{string} を入力とし、エンコードした
文字列を返します。

デフォルトでは、RFC3986 で"非予約文字"として規定されていない文字は
エスケープされます。@var{noescape} 引数に異なる文字集合を渡すことで、
それらがエンコードされるのを抑止することができます。
例えば古いRFC2396では"非予約文字"がいくつか多かったのですが、
@code{*rfc2396-unreserved-char-set*} (下記参照) を渡すことで
それらの文字がエスケープされるのを防ぐことができます。

マルチバイト文字は、デフォルトではGauche のネイティブなマルチバイト表現の
オクテット・ストリームとしてエンコードされます。ただし
@code{uri-encode-string}には@var{encoding}キーワード引数を渡すことができて、
その場合はまず@var{string}が指定された文字エンコーディングへと変換されます。
@c COMMON
@end defun

@defvr {Constant} *rfc2396-unreserved-char-set*
@defvrx {Constant} *rfc3986-unreserved-char-set*
@c MOD rfc.uri
@c EN
These constants are bound to character sets that represents
``unreserved'' characters defined in RFC2396 and RFC3986, respectively.
(See @ref{Character sets}, and @ref{R7RS character sets}, for
operations on character sets).
@c JP
これらの定数はそれぞれ、RFC2396とRFC3986で定義されている
「非予約文字」の文字集合に束縛されています。
(文字集合の操作については、@ref{Character sets}および@ref{R7RS character sets}
を参照して下さい。)
@c COMMON
@end defvr

@c ----------------------------------------------------------------------
@node UUID, Zlib compression library, URI parsing and construction, Library modules - Utilities
@section @code{rfc.uuid} - UUID
@c NODE UUID, @code{rfc.uuid} - UUID

@deftp {Module} rfc.uuid
@mdindex rfc.uuid
This module implements UUID defined in RFC4122.

It provides generators of UUID version 1 and 4, and writer/parser
of the string represenation of UUIDs.
@end deftp

@deftp {Class} <uuid>
@c MOD rfc.uuid
Class of UUID instances.
@end deftp

@defun uuid-value uuid
@c MOD rfc.uuid
Returns the raw value of @var{uuid} as 16-element @code{u8vector}.
You shouldn't mutate the returned u8vector.
@end defun

@defun uuid-version uuid
@c MOD rfc.uuid
Returns the version number of @var{uuid}.
@end defun

@defvar uuid-comparator
@c MOD rfc.uuid
A comparator to compare and hash uuids.  @xref{Basic comparators}.
@end defvar

@defun uuid-random-source-set! random-source
@c MOD rfc.uuid
We use PRNG to generate UUIDs.  By default, we internally creates
a random source and randomize it.  You can pass in your own
random source instead (@pxref{Sources of random bits}, for the details).
@end defun

@defun uuid1 :optional node-id
@c MOD rfc.uuid
Generates a uuid with version 1 algorithm (timestamp and node id based).
The optional @var{node-id} argument must be 48bit exact integer
specifing the node ID (IEEE802 MAC address of the machine).
If it is omitted, we generate a process-global
random node ID (with the multicast bit set to 1, so that it won't
conflict with existing MAC address).
@end defun

@defun uuid4
@c MOD rfc.uuid
Generates a uuid with version 4 algorithm (random numbers).
@end defun

@defun nil-uuid
@c MOD rfc.uuid
Returns a nil-UUID (all bits zero).
@end defun

@defun parse-uuid string
@c MOD rfc.uuid
Takes a string representation of UUID, parses it and returns
an uuid instance.  If the string isn't a valid UUID representation,
an error is thrown.

Other than @code{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} format,
it recognizes the one with @code{urn:uuid:} prefix,
the one enclosed by curly braces, and the one without hyphens.
@end defun

@defun write-uuid uuid :optional port
@c MOD rfc.uuid
Writes out a string representation of @var{uuid},
in @code{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} format, to the given
port.  If the port is omitted, current output port is used.
@end defun

@defun uuid->string uuid
@c MOD rfc.uuid
Returns a string representation of @var{uuid},
in @code{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} format.
@end defun

@c ----------------------------------------------------------------------
@node Zlib compression library, SLIB, UUID, Library modules - Utilities
@section @code{rfc.zlib} - zlib compression library
@c NODE zlib圧縮ライブラリ, @code{rfc.zlib} - zlib圧縮ライブラリ

@deftp {Module} rfc.zlib
@mdindex rfc.zlib
@c EN
This module provides bindings to zlib compression library.
Most features of zlib can be used through this module.

Zlib supports reading and writing of
Zlib compressed data format (RFC1950),
DEFLATE compressed data format (RFC1951),
and GZIP file format (RFC1052).  It also provides
procedures to calculate CRC32 and Adler32 checksums.

Compression and decompression are done through specialized ports.
There are number of parameters to fine-tune compression; refer
to zlib documentation for the details.
@c JP
このモジュールは、Zlib圧縮ライブラリに対するバインディングを提供します。
Zlibのほとんどの機能がこのモジュールを通して利用可能です。

Zlibは、ZLIB圧縮データフォーマット(RFC1950)、DEFLATE圧縮データフォー
マット(RFC1951)、GZIPファイルフォーマット(RFC1952)の読み書きをサポー
トするライブラリです。また、CRC32とAdler32チェックサムの計算のための
関数も提供します。

圧縮・展開機能はポートを通して提供されます。圧縮をチューンするパラ
メータの詳細については、Zlibのドキュメントも合わせて参照してください。
@c COMMON
@end deftp

@subheading Condition types

@c EN
The following condition types are defined to represent errors
during processing by zlib.
@c JP
Zlib処理中のエラーを示すために、以下のコンディションタイプが定義されています。
@c COMMON

@deftp {Condition Type} <zlib-error>
@c MOD rfc.zlib
@c EN
Subclass of @code{<error>} and superclass of the following
condition types.  This class is an abstract class to catch any of the
zlib-specific errors.  Zlib-specific errors raised by
procedures in @code{rfc.zlib} are always an instance (or a compound
condition including) one of the following specific classes.
@c JP
@code{<error>}のサブクラスで、以下のコンディションタイプのスーパークラスです。
このクラスはzlib特有のエラーをまとめて捕捉するための抽象クラスとして設けられています。
@code{rfc.zlib}が投げるZlib固有のエラーは常に以下の特定のクラスのインスタンス、
もしくはそのインスタンスを含む複合コンディションです。
@c COMMON
@end deftp

@deftp {Condition Type} <zlib-need-dict-error>
@deftpx {Condition Type} <zlib-stream-error>
@deftpx {Condition Type} <zlib-data-error>
@deftpx {Condition Type} <zlib-memory-error>
@deftpx {Condition Type} <zlib-version-error>
@c MOD rfc.zlib
@c EN
Subclasses of @code{<zlib-error>}.  Those condition type correspond
to zlib's
@code{Z_NEED_DICT_ERROR},
@code{Z_STREAM_ERROR},
@code{Z_DATA_ERROR},
@code{Z_MEMORY_ERROR}, and
@code{Z_VERSION_ERROR} errors.
@c JP
@code{<zlib-error>}のサブクラスです。それぞれ、Zlibの
@code{Z_NEED_DICT_ERROR}、
@code{Z_STREAM_ERROR}、
@code{Z_DATA_ERROR}、
@code{Z_MEMORY_ERROR}、
@code{Z_VERSION_ERROR}
に対応します。
@c COMMON

@c EN
When an error occurs during reading data, a compound
condition of a subclass of @code{<zlib-error>} and
@code{<io-read-error>} is raised.
When an error occurs without I/O, a simple condition
of a subclass of @code{<zlib-error>} is raised.
Errors unrelated to zlib, such as invalid argument error,
would be a simple @code{<error>} condition.
@c JP
データの読み出し時にエラーが発生した場合、
@code{<zlib-error>}のサブクラスと
@code{<io-read-error>}の合成コンディションが投げられます。入力が伴わ
ない場合、例えば圧縮ストリームの初期化エラーのときには、合成され
ていない@code{<zlib-error>}のサブクラスが投げられます。ただの引数の型の
エラーのように、Zlibの関数が呼び出されない場合は、ただの@code{<error>}が
投げられるかもしれません。
@c COMMON
@end deftp

@subheading Compression/decompression ports

@deftp {Class} <deflating-port>
@deftpx {Class} <inflating-port>
@clindex deflating-port
@clindex inflating-port
@c MOD rfc.zlib
@c EN
Compression and decompression functions are provided
via ports.  A @emph{deflating port} is an output port
that compresses the output data.  An @emph{inflating port}
is an input that reads compressed data and decompress it.

When an inflating port encounters a corrupted compressed
data, a compound condition of @code{<io-read-error>}
and @code{<zlib-data-error>} is raised during read operation.
@c JP
圧縮と展開の機能はポートを通じて提供されます。
@emph{deflating port}は出力されたデータを圧縮する出力ポートです。
@emph{inflating port}は圧縮されたデータソースからデータを展開しつつ
読み込む入力ポートです。

inflating portが読み出す圧縮データが壊れていた場合、読み出し時に
@code{<io-read-error>}と@code{<zlib-data-error>}の
合成コンディションが投げられます。
@c COMMON
@end deftp


@defun open-deflating-port drain :key compression-level buffer-size window-bits memory-level strategy dictionary owner?
@c MOD rfc.zlib
@c EN
Creates and returns an instance of @code{<deflating-port>},
an output port that compresses the output data and sends
the compressed data to another output port @var{drain}.
This combines the functionality of zlib's @code{deflateInit2()}
and @code{deflateSetDictionary()}.
@c JP
新たな@code{<deflating-port>}のインスタンス、
すなわち書き込まれたデータを圧縮し出力ポート@var{drain}に書き出す出力ポートを作成して、
そのポートを返します。Zlibの関数@code{deflateInit2()}と
@code{deflateSetDictionary()}とを合わせた手続きです。
@c COMMON

@c EN
You can specify an exact integer between 1 and 9 (inclusive) to
@var{compression-level}.  Larger integer means larger compression ratio.
When omitted, a default compression level is used, which is usually 6.
@c JP
@var{compression-level}には1から9の整数を指定することができ、
大きい数が高い圧縮率を意味します。引数が省略された場合は、
デフォルトの圧縮レベルと見なされます。これは通常6です。
@c COMMON

@c EN
The following constants are defined to specify @var{compression-level}
conveniently:
@c JP
@var{compression-level}をわかりやすく指定するために以下の定数が定義されています。
@c COMMON

@defvr {Constant} Z_NO_COMPRESSION
@defvrx {Constant} Z_BEST_SPEED
@defvrx {Constant} Z_BEST_COMPRESSION
@defvrx {Constant} Z_DEFAULT_COMPRESSION
@c MOD rfc.zlib
@end defvr

@c EN
The @var{buffer-size} argument specifies the buffer size of the port in bytes.
The default is 4096.
@c JP
@var{buffer-size}は、ポートのバッファサイズを指定します。デフォルトは4096バイトです。
@c COMMON

@c EN
The @var{window-bits} argument specifies the size of the window in
exact integer.   Typically the value should be
between 8 and 15, inclusive, and it specifies the base two logarithm
of the window size used in compression.
Larger number yields better compression ratio, but more memory usage.
The default value is 15.
@c JP
@var{window-bits}はウィンドウサイズを指定します。
通常この値は8から15までの整数で、圧縮に使われるウィンドウサイズの
2を底とするlogをとった値です。
大きい数であるだけ圧縮率が高くなりますが、
そのぶんメモリの使用量が増加します。デフォルトは15です。
@c COMMON

@c EN
There are a couple of special modes specifiable by @var{window-bits}.
When an integer between -8 and -15 is given to
@var{window-bits}, the port produces a raw deflated data,
that lacks zlib header and trailer.  In this case, Adler32 checksum isn't
calculated.  The actual window size is determined by the absolute value of
@var{window-bits}.
@c JP
@var{window-bits}よって、2つばかり特別なモードを指定することができます。
@var{window-bits}に-8から-15の整数を指定された場合は、
ZLIBヘッダとトレイラのない生のdeflateデータを作成します。
この場合Adler32チェックサムも計算されません。
実際のウィンドウサイズは@var{window-bits}の絶対値によって計算されます。
@c COMMON

@c EN
When @var{window-bits} is between 24 and 31, the port uses GZIP encoding;
that is, instead of zlib wrapper,
the compressed data is enveloped by simple gzip header and trailer.
The gzip header added by this case doesn't have filenames, comments,
header CRC and other data, and have zero modified time, and 255 (unknown)
in the OS field.  The @code{zstream-adler32} procedure will return
CRC32 checksum instead of Adler32.
The actual window size is determined by @var{window-bits}-16.
@c JP
@var{window-bits}が24から31の間である場合、
ポートはgzipエンコーディングを使うようになります。すなわち、
zlibラッパの代わりに、シンプルなgzipヘッダとトレイラが圧縮データの前後に書き出されます。
gzipヘッダはファイル名やその他のデータ、コメントを持たず、変更時刻は0、
ヘッダCRCはなし、OS名は不明を意味する255になります。gzipストリームが書き出
されるときは、@code{zstream-adler32}で取得できるチェックサムはAdler32
ではなくCRC32になります。
実際のウィンドウサイズは @var{window-bits}-16 で決定されます。
@c COMMON

@c EN
The @var{memory-level} argument specifies how much memory
should be allocated to keep the internal state during compression.
1 means smallest memory, which causes slow and less compression.
9 means fastest and best compression with largest amount of memory.
The default value is 8.
@c JP
@var{memory-level}は、圧縮の内部状態のためにどれだけのメモリを割り当て
るかを指定するパラメータです。1ではメモリの使用量は最小ですが、遅
くなり圧縮率が低下します。9では高速な処理のためにメモリが最も多く
使われます。デフォルトは8です。
@c COMMON

@c EN
To fine tune compression algorithm, you can use the @var{strategy}
argument.  The following constants are defined as the valid
value as @var{strategy}:
@c JP
@var{strategy}で圧縮アルゴリズムをチューンできます。
以下の定数が@var{strategy}に有効な値として定義されています。
@c COMMON

@defvr {Constant} Z_DEFAULT_STRATEGY
@c MOD rfc.zlib
@c EN
The default strategy, suitable for most ordinary data.
@c JP
通常のデータに適する、デフォルトのアルゴリズムを使います。
@c COMMON
@end defvr

@defvr {Constant} Z_FILTERED
@c MOD rfc.zlib
@c EN
Suitable for data generated by filters.
Filtered data consists mostly of small values with a
random distribution, and this makes the compression algorithm
to use more huffman encoding and less string match.
@c JP
フィルタにより生成されたデータに適したアルゴリズムを使います。
このようなデータは小さな値とランダムな分散を持つことが多いため、
このアルゴリズムではハフマンエンコーディングをより優先し、
文字列一致の使用をやや抑えます。
@c COMMON
@end defvr

@defvr {Constant} Z_HUFFMAN_ONLY
@c MOD rfc.zlib
@c EN
Force huffman encoding only (no string match).
@c JP
ハフマンエンコーディングのみを使います (文字列一致を使いません)。
@c COMMON
@end defvr

@defvr {Constant} Z_RLE
@c MOD rfc.zlib
@c EN
Limit match distance to 1 (that is, to force run-length encoding).
It is as fast as @code{Z_HUFFMAN_ONLY} and gives better compression
for png image data.
@c JP
マッチ距離を1に制限します (ランレングスエンコーディングを強制することになります)。
@code{Z_HUFFMAN_ONLY}と同じくらい高速で、かつpngイメージデータに対して
良い圧縮率が得られます。
@c COMMON
@end defvr

@defvr {Constant} Z_FIXED
@c MOD rfc.zlib
@c EN
Prohibits dynamic huffman encoding.  It allows a simple decoder
for special applications.
@c JP
動的ハフマンエンコーディングを禁止します。特殊なアプリケーションで、
単純なデコーダを使いたい場合に便利です。
@c COMMON
@end defvr

@c EN
The choice of @var{strategy} only affects compression ratio and
speed.  Any choice produces correct and decompressable data.
@c JP
@var{strategy}の選択は圧縮率と速度にのみ影響を与えます。
どの値を選んでも圧縮されたデータは正しく展開できます。
@c COMMON

@c EN
You can give an initial dictionary to the @var{dictionary}
argument to be used in compression.
The compressor and decompressor must use exactly the same dictionary.
See the zlib documentation for the details.
@c JP
@var{dictionary}には圧縮に使う辞書を文字列で与えます。辞書を与える場合、
圧縮と展開で全く同じものを使う必要があります。
辞書の詳細についてはzlibのドキュメントを参照してください。
@c COMMON

@c EN
By default, a deflating port leaves @var{drain} open
after all conversion is done, i.e. the deflating port itself is
closed.  If you don't want to bother closing @var{drain},
give a true value to the @var{owner?} argument; then @var{drain}
is closed after the deflating port is closed and all data
is written out.
@c JP
デフォルトでは、deflating portはそれ自身がクローズされても
@var{drain}をクローズしません。@var{drain}の後始末を気にしたくない
場合は@var{owner?}引数に真の値を与えてください。
その場合、deflating portがクローズされすべてのデータが書き出されたのちに
@var{drain}は自動的にクローズされます。
@c COMMON

@c EN
Note: You @emph{must} close a deflating port explicitly,
or the compressed data can be chopped prematurely.
When you leave a deflating port open to be GCed, the
finalizer will close it; however, the order in which
finalizers are called is undeterministic, and it is
possible that the @var{drain} port is closed before
the deflating port is closed.  In such cases,
the deflating port's attempt to flush the buffered data
and trailer will fail.
@c JP
注意: deflating portは必ず明示的にクローズしてください。
そうしなければ圧縮データの終わりの部分(バッファされているデータおよびトレイラ)が
@var{drain}に書き出されないかもしれません。
ポートを明示的にクローズせずにガベージ・コレクタに任せた場合、
出力ポートのクローズ手続きはファイナラザから呼び出されることになります。
複数のごみに対してファイナライザの呼ばれる順番は不定なので、
deflating portより先に@var{drain}のファイナライザが呼ばれて
そのポートがクローズされてしまうことがあります。
こうなると、圧縮データの終わりの部分の出力がエラーになってしまいます。
@c COMMON
@end defun

@defun open-inflating-port source :key buffer-size window-bits dictionary owner?
@c MOD rfc.zlib
@c EN
Takes an input port @var{source} from which a compressed data
can be read, and creates and returns a new instance of
@code{<inflating-port>}, that is, a port that allows
decompressed data from it.
This procedure covers zlib's functionality of
@code{inflateInit2()} and @code{inflateSetDictionary()}.
@c JP
圧縮データを読み出せる入力ポート@var{source}を取り、
新たな@code{<inflating-port>}のインスタンス、すなわち
展開されたデータを読み出すことのできる入力ポートを作成し、そのポートを返します。
これはZlibの関数@code{inflateInit2()}、@code{inflateSetDictionary()}
を合わせた手続きです。
@c COMMON

@c EN
The meaning of @var{buffer-size} and @var{owner} are
the same as @code{open-deflating-port}.
@c JP
@var{buffer-size}、@var{owner?}の意味は
@code{open-deflating-port}と同じです。
@c COMMON

@c EN
The meaning of @var{window-bits} is almost the same,
except that if a value increased by 32 is given, the inflating port
automatically detects whether the source stream is
zlib or gzip by its header.
@c JP
@var{window-bits}の意味もほぼ同じですが、
32が足された値が与えられた場合にはZLIBとGZIPのヘッダ自動判定が有効になります。
@c COMMON

@c EN
If the input data is compressed with specified dictionary,
the same dictionary must be given to the @var{dictionary} argument.
Otherwise, a compound condition of
@code{<io-read-error>} and @code{<zlib-need-dict-error>} will be raised.
@c JP
@var{dictionary}は圧縮時の辞書と同じものを指定しなければなりません。
辞書を使って圧縮されたデータを展開する際に、@var{dictionary}引数
を指定しなかったり、異なる辞書を与えた場合は
@code{<io-read-error>}と@code{<zlib-need-dict-error>}の
合成コンディションが投げられます。
@c COMMON
@end defun

@subheading Operations on inflating/deflating ports

@defun zstream-total-in xflating-port
@defunx zstream-total-out xflating-port
@defunx zstream-adler32 xflating-port
@defunx zstream-data-type xflating-port
@c MOD rfc.zlib
@c EN
The @var{xflating-port} argument must be either
inflating and deflating port, or an error is raised.

Returns the value of @code{total_in}, @code{total_out},
@var{adler32}, and @code{data_type} fields of the @code{z_stream}
structure associated to the given inflating or deflating port,
respectively.
@c JP
@var{xflating-port}はinflating portかdeflating portでなければ
なりません。さもなくばエラーが通知されます。

@code{z_stream}構造体の@code{total_in}、@code{total_out}、
@code{adlre32}および@code{data_type}フィールドの値を返します。
@c COMMON

@c EN
The value of @code{data_type} can be one of the following
constants:
@c JP
@code{data_type}フィールドの値は以下の定数のうちのいずれかです。
@c COMMON

@defvr {Constant} Z_BINARY
@defvrx {Constant} Z_TEXT
@defvrx {Constant} Z_ASCII
@defvrx {Constant} Z_UNKNOWN
@c MOD rfc.zlib
@end defvr

@end defun

@defun zstream-params-set! deflating-port :key compression-level strategy
@c MOD rfc.zlib
@c EN
Changes compression level and/or strategy during compressing.
@c JP
圧縮率とストラテジを動的に変更するための手続きです。
@c COMMON
@end defun

@defun zstream-dictionary-adler32 deflating-port
@c MOD rfc.zlib
@c EN
When a dictionary is given to @code{open-deflating-port}, the
dictionary's adler32 checksum is calculated.  This
procedure returns the checksum.  If no dictionary has been given,
this procedure returns @code{#f}.
@c JP
deflating portの作成時に辞書を指定すると、辞書のAdler32チェックサム
が計算されます。この手続きはそのチェックサムを返します。
@code{open-deflating-port}に辞書を与えなかったなら、@code{#f}が返ります。
@c COMMON
@end defun

@defun deflating-port-full-flush deflating-port
@c MOD rfc.zlib
@c EN
Flush the data buffered in the @var{deflating-port}, and
resets compression state.  The decompression routine can
skip the data to the full-flush point by @code{inflate-sync}.
@c JP
ポートのデータをフルフラッシュし、圧縮状態をリセットします。
展開ルーチンは@code{inflate-sync}手続きを使って
入力をこの地点までスキップすることができます。
@c COMMON
@end defun

@defun inflate-sync inflating-port
@c MOD rfc.zlib
@c EN
Skip the (possibly corrupted) compressed data up to the
next full-flush point marked by @code{deflating-port-full-flush}.
You may want to use this procedure when you get
@code{<zlib-data-error>}.  Returns the number of bytes
skipped when the next full-flush point is found, or
@code{#f} when the input reaches EOF before finding the next point.
@c JP
圧縮データを、@code{deflating-port-full-flush}によって
フルフラッシュしたポイントまで読み飛ばします。
@code{<zlib-data-error>}が投げられたときに使用するとよいでしょう。
フルフラッシュポイントに達したときは読み飛ばしたバイトの数を、EOFまで達
したときは@code{#f}を返します。
@c COMMON
@end defun

@subheading Miscellaneous API

@defun zlib-version
@c MOD rfc.zlib
@c EN
Returns Zlib's version in string.
@c JP
Zlibのバージョンを文字列で返します。
@c COMMON
@end defun

@defun deflate-string string options @dots{}
@c MOD rfc.zlib
@c EN
Compresses the given string and returns zlib-compressed data
in a string.  All optional arguments are passed to
@code{open-deflating-port} as they are.
@c JP
与えられた文字列を圧縮し、zlib圧縮されたデータを文字列で返します。
すべてのオプション引数はそのまま@code{open-deflating-port}に渡されます。
@c COMMON
@end defun

@defun inflate-string string options @dots{}
@c MOD rfc.zlib
@c EN
Takes zlib-compressed data in string, and returns decompressed data
in a string.  All optional arguments are passed to
@code{open-inflating-port} as they are.
@c JP
Zlib圧縮されたデータを文字列で受け取り、展開されたデータを文字列で
返します。
すべてのオプション引数はそのまま@code{open-deflating-port}に渡されます。
@c COMMON
@end defun

@defun gzip-encode-string string options @dots{}
@defunx gzip-decode-string string options @dots{}
@c MOD rfc.zlib
@c EN
Like @code{deflate-string} and @code{inflate-string}, but
uses the gzip format instead.  It is same as giving
more than 15 to the @var{window-bits} argument of @code{deflate-string}
and @code{inflate-string}.
@c JP
@code{deflate-string}および@code{inflate-string}と似ていますが、
GZIPフォーマットを使います。これは
@code{deflate-string}および@code{inflate-string}の
@var{window-bits}に15以上の値指定するのと同じです。
@c COMMON
@end defun

@defun crc32 string :optional checksum
@c MOD rfc.zlib
@c EN
Returns CRC32 checksum of @var{string}.  If optional @var{checksum}
is given, the returned checksum is an update of @var{checksum} by
@var{string}.
@c JP
文字列@var{string}のCRC32チェックサムを計算して返します。@var{checksum}
引数が与えられた場合は、それを@var{string}によるチェックサムで更新した
値が返されます。
@c COMMON
@end defun

@defun adler32 string :optional checksum
@c MOD rfc.zlib
@c EN
Returns Adler32 checksum of @var{string}.  If optional @var{checksum}
is given, the returned checksum is an update of @var{checksum} by
@var{string}.

Calculating Adler32 is faster than CRC32, but it is known to produce
uneven distribution of hash values for small input.
See RFC3309 for the detailed description.  If it matters,
use CRC32 instead.
@c JP
文字列@var{string}のAdler32チェックサムを計算して返します。@var{checksum}
引数が与えられた場合は、それを@var{string}によるチェックサムで更新した
値が返されます。

Adler32はCRC32と比較して高速に計算することが可能なアルゴリズムです
が、小さなデータのチェックサムの信頼性にいくらか問題があることがわ
かっています。詳しくはRFC3309を見てください。これが問題になる場合
はCRC32を使用してください。
@c COMMON
@end defun






@c ----------------------------------------------------------------------
@node SLIB, Functional XML parser, Zlib compression library, Library modules - Utilities
@section @code{slib} - SLIB interface
@c NODE SLIBインタフェース, @code{slib} - SLIBインタフェース

@deftp {Module} slib
@mdindex slib
@c EN
This module is the interface to the Aubrey Jaffer's SLIB.
To use SLIB, say @code{(use slib)}.   SLIB itself is not included
in Gauche distribution.   If you don't have it on your system,
get it from @uref{http://www-swiss.ai.mit.edu/~jaffer/SLIB.html}.
@c JP
このモジュールはAubrey Jaffer氏のSLIBへのインタフェースです。
SLIBがインストールされている場合、@code{(use slib)} とすれば
SLIBの機能が使えるようになります。
SLIBそのものはGaucheのディストリビューションには含まれていません。
あなたのシステムにまだインストールされていない場合は
@uref{http://www-swiss.ai.mit.edu/~jaffer/SLIB.html}から入手することができます。
@c COMMON

@c EN
By default, the SLIB installation is searched from the directory
specified at the Gauche configuration.  If SLIB isn't there, an error
is signaled.  In that case, you can set the environment
variable @code{SCHEME_LIBRARY_PATH} to point to the SLIB installation path.
@c JP
デフォルトでは、インストールされたSLIBはGaucheのconfiguration時に指定された
場所から探されます。SLIBがそこになければ、エラーが報告されます。
その場合、環境変数@code{SCHEME_LIBRARY_PATH}でSLIBがインストールされた
パスを指定してください。
@c COMMON

@c EN
This module redefines @code{require}, shadowing the Gauche's original
@code{require}.  If it gets a symbol as an argument, it works as
SLIB's @code{require}, while if it gets a string, it works as
Gauche's @code{require}.   The same applies to @code{provide} and
@code{provided?}.
@c JP
このモジュールは@code{require}を再定義し、Gaucheオリジナルの@code{require}を
シャドウします。@code{require}にシンボルが渡された場合はSLIBの@code{require}
のように動作します。@code{require}に文字列が渡された場合はGaucheの@code{require}
のように動作します。@code{provide}と@code{provided?}についても同様です。
@c COMMON

@c EN
All SLIB symbol bindings, loaded by @code{require}, stay in the
module @code{slib}.
@c JP
@code{require}でロードされる、SLIBで導入されるすべての定義は、
@code{slib}モジュール内で行われます。
@c COMMON
@end deftp

@example
(use slib)         ; @r{load and set up slib}
(require 'getopt)  ; @r{load SLIB's getopt module}
(require "foo")    ; @r{load Gauche's foo module}
@end example

@c ----------------------------------------------------------------------
@node Functional XML parser, SXML query language, SLIB, Library modules - Utilities
@section @code{sxml.ssax} - Functional XML parser
@c NODE 関数的なXMLパーザ, @code{sxml.ssax} - 関数的なXMLパーザ

@deftp {Module} sxml.ssax
@mdindex sxml.ssax
@c EN
@code{sxml.*} modules are the adaptation of
Oleg Kiselyov's SXML framework (@uref{http://okmij.org/ftp/Scheme/xml.html}),
which is based on S-expression representation of XML structure.
@c JP
@code{sxml.*}モジュールは、XML構造のS式表現に基づく
Oleg KiselyovのSXMLフレームワーク(@uref{http://okmij.org/ftp/Scheme/xml.html})の適合です。
@c COMMON

@c EN
SSAX is a parser part of SXML framework.
This is a quote from SSAX webpage:
@c JP
SSAXは、SXMLフレームワークのパーザ部分です。以下は、
SSAXのウェブページからの引用です。
@c COMMON

@quotation
@c EN
A SSAX functional XML parsing framework consists of a DOM/SXML parser,
a SAX parser, and a supporting library of lexing and parsing procedures.
The procedures in the package can be used separately to tokenize or parse
various pieces of XML documents.
The framework supports XML Namespaces, character, internal
and external parsed entities, attribute value normalization,
processing instructions and CDATA sections. The package includes
a semi-validating SXML parser : a DOM-mode parser that is an
instantiation of a SAX parser (called SSAX).
@c JP
SSAXは関数的なXMLパージングフレームワークで、DOM/SXMLパーザ、SAXパーザ、
字句解析・構文解析手続きのサポートライブラリから構成されます。
パッケージ内の手続きは、XML文書の様々な部分をトークナイズ、あるいは
パーズするために独立して使うことができます。
このフレームワークは、XML名前空間、文字、内部および外部解析済み実体、
属性値の正規化、処理命令とCDATAセクションをサポートしています。
パッケージは、ある程度の妥当性検査を行うSXMLパーザ: SAXパーザの
インスタンスであるDOMモードのパーザ(SSAXと呼ばれます)を含んでいます。
@c COMMON
@end quotation

@c EN
The current version is based on the SSAX CVS version newer than
the last 'official' release of SXML toolset (4.9), and
SXML-gauche-0.9 package which was based on SXML-4.9.
There is an important change from that release.
Now the API uses lowercase letter suffix @code{ssax:}
instead of uppercase @code{SSAX:}---the difference matters since
Gauche is case sensitive by default.
Alias names are defined for backward compatibility,
but the use of uppercase suffixed names are deprecated.
@c JP
現在のバージョンは、SXMLツールセットの最新の'公式な'リリース(4.9)よりも
新しい、SSAXのCVSバージョンをベースにしており、パッケージSXML-gauche-0.9は、
SXML-4.9をベースにしています。
SXMLのリリース4.9以降では、重要な変更があります。
現在のAPIでは、大文字の接頭辞@code{SSAX:}の代わりに小文字の@code{ssax:}を
使います。Gaucheはデフォルトで文字の大小を区別するために、この違いは
問題となります。
後方互換性のためにエイリアスされた名前が定義されていますが、
大文字の接頭辞付きの名前の使用は推奨されません。
@c COMMON
@end deftp

@c EN
I derived the content of this part of the manual from SSAX
source code, just by converting its comments into texinfo format.
The original text is by Oleg Kiselyov.  Shiro Kawai
should be responsible for any typographical error or formatting error
introduced by conversion.
@c JP
マニュアルのこのパートの内容はSSAXのソースコードから抽出されたもので、
単にそのコメントをTexinfoのフォーマットに変換しただけです。
オリジナルのテキストは、Oleg Kiselyovによるものです。
変換により生じた誤字・誤植やフォーマットエラーの責任は、
Shiro Kawaiにあります。
@c COMMON

@c EN
The manual entries are ordered in "bottom-up" way, beginning from
the lower-level constructs towards the high-level utilities.
If you just want to parse XML document and obtain SXML,
check out @code{ssax:xml->sxml} in @ref{SSAX Highest-level parsers - XML to SXML}.
@c JP
このマニュアルのエントリは、低レベルの構造から高レベルのユーティリティへと
``ボトムアップ''の方法で並べられています。
もし、あなたが単にXMLドキュメントをパーズしたりSXMLを得たいだけならば、
@ref{SSAX Highest-level parsers - XML to SXML}の@code{ssax:xml->sxml}を
チェックして下さい。
@c COMMON

@c ----------------------------------------------------------------------
@menu
* SSAX data types::
* SSAX low-level parsing code::
* SSAX higher-level parsers and scanners::
* SSAX Highest-level parsers - XML to SXML::
@end menu

@node SSAX data types, SSAX low-level parsing code, Functional XML parser, Functional XML parser
@subsection SSAX data types
@c NODE SSAXデータタイプ

@table @emph
@item TAG-KIND
@c EN
a symbol '@code{START}, '@code{END}, '@code{PI}, '@code{DECL}, '@code{COMMENT}, '@code{CDSECT}
or '@code{ENTITY-REF} that identifies a markup token.
@c JP
シンボル'@code{START}、'@code{END}、'@code{PI}、'@code{DECL}、'@code{COMMENT}、
'@code{CDSECT}は、マークアップトークンを識別するものです。
@c COMMON
@item UNRES-NAME
@c EN
a name (called @code{GI} in the XML Recommendation) as given in an xml
document for a markup token: start-tag, @code{PI} target, attribute name.
If a @code{GI} is an @code{NCName}, @var{UNRES-NAME} is this @code{NCName} converted into
a Scheme symbol. If a @code{GI} is a @code{QName}, @var{UNRES-NAME} is a pair of
symbols: (@var{PREFIX} . @var{LOCALPART})
@c JP
XML文書で、マークアップトークン: 開始タグ、@code{PI}ターゲット、属性名に
与えられる名前(XML勧告では@code{GI}と呼ばれます)です。
@code{GI}が@code{NCName}である場合、@var{UNRES-NAME}はこの@code{NCName}が
Schemeのシンボルに変換されたものになります。
@code{GI}が@code{QName}ならば、@var{UNRES-NAME}は、シンボルのペア、
(@var{PREFIX} . @var{LOCALPART})となります。
@c COMMON
@item RES-NAME
@c EN
An expanded name, a resolved version of an @var{UNRES-NAME}.
For an element or an attribute name with a non-empty namespace URI,
@var{RES-NAME} is a pair of symbols, (@var{URI-SYMB} . @var{LOCALPART}).
Otherwise, it's a single symbol.
@c JP
展開された名前、つまり@var{UNRES-NAME}の解決されたバージョンです。
名前空間URIが空でない場合の要素や属性名では、@var{RES-NAME}はシンボルのペア、
(@var{URI-SYMB} . @var{LOCALPART})です。そうでない場合は、1つのシンボルです。
@c COMMON
@item ELEM-CONTENT-MODEL
@c EN
A symbol:
@c JP
以下のシンボルのうちの1つです。
@c COMMON
@c EN
@multitable @columnfractions .3 .7
@item @code{ANY}
@tab anything goes, expect an END tag.
@item @code{EMPTY-TAG}
@tab no content, and no END-tag is coming.
@item @code{EMPTY}
@tab no content, expect the END-tag as the next token.
@item @code{PCDATA}
@tab expect character data only, and no children elements.
@item @code{MIXED}
@tab
@item @code{ELEM-CONTENT}
@tab
@end multitable
@c JP
@multitable @columnfractions .3 .7
@item @code{ANY}
@tab 何でもよく、ENDタグがあるもの。
@item @code{EMPTY-TAG}
@tab 内容がなく、ENDタグのないもの。
@item @code{EMPTY}
@tab 内容がなく、次のトークンがENDタグであるもの。
@item @code{PCDATA}
@tab 文字データのみで、子要素がないもの。
@item @code{MIXED}
@tab
@item @code{ELEM-CONTENT}
@tab
@end multitable
@c COMMON
@item URI-SYMB
@c EN
A symbol representing a namespace URI -- or other symbol chosen
by the user to represent URI. In the former case,
@var{URI-SYMB} is created by @code{%}-quoting of bad URI characters and
converting the resulting string into a symbol.
@c JP
名前空間を表すシンボル、あるいはURIを表すためにユーザが選んだ他のシンボルです。
前者の場合、@var{URI-SYMB}は不正なURI文字が@code{%}でクォートされた
文字列をシンボルに変換したものです。
@c COMMON
@item NAMESPACES
@c EN
A list representing namespaces in effect. An element of the list
has one of the following forms:
@c JP
効力を持つ名前空間を表すリストです。リストの要素は、以下のフォームのうちの1つです。
@c COMMON

@c EN
@table @code
@item (@var{prefix} @var{uri-symb} . @var{uri-symb})
or,
@item (@var{prefix} @var{user-prefix} . @var{uri-symb})
@var{user-prefix} is a symbol chosen by the user
to represent the URI.
@item (#f @var{user-prefix} . @var{uri-symb})
Specification of the user-chosen prefix and a @var{uri-symbol}.
@item (*DEFAULT* @var{user-prefix} . @var{uri-symb})
Declaration of the default namespace
@item (*DEFAULT* #f . #f)
Un-declaration of the default namespace. This notation
represents overriding of the previous declaration
@end table
@c JP
@table @code
@item (@var{prefix} @var{uri-symb} . @var{uri-symb})
あるいは、
@item (@var{prefix} @var{user-prefix} . @var{uri-symb})
@var{user-prefix}は、そのURIを表現するためにユーザにより選ばれたシンボル。
@item (#f @var{user-prefix} . @var{uri-symb})
ユーザが選んだプリフィックスと@var{uri-symbol}の指定。
@item (*DEFAULT* @var{user-prefix} . @var{uri-symb})
デフォルト名前空間の宣言。
@item (*DEFAULT* #f . #f)
デフォルト名前空間を宣言しない。この記法は、それ以前の宣言を上書き
することを表す。
@end table
@c COMMON

@c EN
A @var{NAMESPACES} list may contain several elements for the same @var{PREFIX}.
The one closest to the beginning of the list takes effect.
@c JP
@var{NAMESPACES}のリストは、同じ@var{PREFIX}についていくつかの要素を含むかも
しれません。リストの先頭に近いものが効力を持ちます。
@c COMMON

@item ATTLIST
@c EN
An ordered collection of (@var{NAME} . @var{VALUE}) pairs, where @var{NAME} is
a @var{RES-NAME} or an @var{UNRES-NAME}. The collection is an ADT.
@c JP
ペア(@var{NAME} . @var{VALUE})の順序付きのコレクションで、@var{NAME}は
@var{RES-NAME}か@var{UNRES-NAME}です。このコレクションはADTです。
@c COMMON
@item STR-HANDLER
@c EN
A procedure of three arguments:
@code{(@var{string1} @var{string2} @var{seed})}
returning a new @var{seed}.
The procedure is supposed to handle a chunk of character data
@var{string1} followed by a chunk of character data @var{string2}.
@var{string2} is a short string, often "\n" and even ""
@c JP
3引数の手続き @code{(@var{string1} @var{string2} @var{seed})}で、
新しい@var{seed}を返します。
この手続きは、文字データ@var{string2}が後に続く、文字データ@var{string1}を
扱うものです。@var{string2}は、``\n''や``''のような短い文字列です。
@c COMMON
@item ENTITIES
@c EN
An assoc list of pairs:
@example
  (@var{named-entity-name} . @var{named-entity-body})
@end example
where @var{named-entity-name} is a symbol under which the entity was
declared, @var{named-entity-body} is either a string, or
(for an external entity) a thunk that will return an
input port (from which the entity can be read).
@var{named-entity-body} may also be @code{#f}. This is an indication that a
@var{named-entity-name} is currently being expanded. A reference to
this @var{named-entity-name} will be an error: violation of the
WFC nonrecursion.
@c JP
ペア (@var{named-entity-name} . @var{named-entity-body})の連想リストで、
@var{named-entity-name}はその実体が宣言されたシンボル、
@var{named-entity-body}は文字列か、(外部実体の場合は)
(そこから実体が読み込める)入力ポートを返す手続きです。
@var{named-entity-body}はまた、@code{#f}かも知れません。
これは、@var{named-entity-name}がその時点で展開されていることを
示します。
この@var{named-entity-name}への参照は、WFC非再帰違反としてエラーに
なります。
@c COMMON
@item XML-TOKEN
@c EN
A record with two slots, @var{kind} and @var{token}.
This record represents a markup, which is, according to the XML
Recommendation, "takes the form of start-tags, end-tags, empty-element tags,
entity references, character references, comments, CDATA section delimiters,
document type declarations, and processing instructions."
@c JP
@var{kind}と@var{token}という2つのスロットを持つレコードです。
このレコードは、XML勧告によれば、「開始タグ、終了タグ、空要素タグ、
実体参照、文字参照、コメント、CDATAセクションの区切り、
文書型宣言、処理命令の形を取る」マークアップを表します。
@c COMMON
@table @var
@item kind
@c EN
a @var{TAG-KIND}
@c JP
@var{TAG-KIND}。
@c COMMON
@item head
@c EN
an @var{UNRES-NAME}. For xml-tokens of kinds '@code{COMMENT} and
'@code{CDSECT}, the head is @code{#f}
@c JP
@var{UNRES-NAME}。'@code{COMMENT}と'@code{CDSECT}というkindのXMLトークンでは、
そのheadは@code{#f}になります。
@c COMMON
@end table

@c EN
For example,
@c JP
例を示します。
@c COMMON
@example
<P>  => kind='START, head='P
</P> => kind='END, head='P
<BR/> => kind='EMPTY-EL, head='BR
<!DOCTYPE OMF ...> => kind='DECL, head='DOCTYPE
<?xml version="1.0"?> => kind='PI, head='xml
&my-ent; => kind = 'ENTITY-REF, head='my-ent
@end example
@c EN
Character references are not represented by xml-tokens as these references
are transparently resolved into the corresponding characters.
@c JP
文字参照は、対応する文字へと透過的に解決されるので、XMLトークンとしては
表現されません。
@c COMMON
@item XML-DECL
@c EN
A record with three slots, @var{elems}, @var{entities}, and @var{notations}.

The record represents a datatype of an XML document: the list of
declared elements and their attributes, declared notations, list of
replacement strings or loading procedures for parsed general
entities, etc. Normally an xml-decl record is created from a DTD or
an XML Schema, although it can be created and filled in in many other
ways (e.g., loaded from a file).
@c JP
@var{elems}、@var{entities}、@var{notations}という3つのスロットを持つレコードです。

このレコードは、XML文書のデータタイプを表現します。それは、
宣言された要素とその属性のリスト、宣言された記法、
解析済み一般実体の置換文字列やロードされる手続きのリストなどです。
通常、xml-declレコードは、それを作るには他にたくさんの方法
(例えばファイルからロードするなど)があるにも関わらず、DTDかXML Schemaから
作られます。
@c COMMON

@c EN
@var{elems}: an (assoc) list of decl-elem or @code{#f}. The latter instructs
the parser to do no validation of elements and attributes.
@c JP
@var{elems}: decl-elemか@code{#f}の(連想)リスト。後者は、パーザに、
要素と属性の妥当性検査を行わないように指示します。
@c COMMON

@c EN
@var{decl-elem}: declaration of one element:
@code{(@var{elem-name} @var{elem-content} @var{decl-attrs})};
@var{elem-name} is an @var{UNRES-NAME} for the element.
@var{elem-content} is an @var{ELEM-CONTENT-MODEL}.
@var{decl-attrs} is an @var{ATTLIST},
of @code{(@var{attr-name} . @var{value})} associations.
This element can declare a user procedure to handle parsing of an
element (e.g., to do a custom validation, or to build a hash of
IDs as they're encountered).
@c JP
@var{decl-elem}: 1つの要素の宣言:
@code{(@var{elem-name} @var{elem-content} @var{decl-attrs})};
@var{elem-name}はその要素の@var{UNRES-NAME}。
@var{elem-content}は@var{ELEM-CONTENT-MODEL}。
@var{decl-attrs}は@var{ATTLIST}か、@code{(@var{attr-name} . @var{value})}の
連想リスト。
この要素は、要素のパージングを扱うユーザ手続きを宣言できます。
(例えば、カスタムな妥当性検査を行ったり、タグに出会うたびに
IDのハッシュを構築するなど。)
@c COMMON

@c EN
@var{decl-attr}: an element of an @var{ATTLIST}, declaration of one attribute
@code{(@var{attr-name} @var{content-type} @var{use-type} @var{default-value})}:
@var{attr-name} is an @var{UNRES-NAME} for the declared attribute;
@var{content-type} is a symbol: @code{CDATA}, @var{NMTOKEN}, @var{NMTOKENS}, ...;
or a list of strings for the enumerated type.
@var{use-type} is a symbol: @code{REQUIRED}, @code{IMPLIED}, @code{FIXED}
default-value is a string for the default value, or @code{#f} if not given.
@c JP
@var{decl-attr}: @var{ATTLIST}の要素で、1つの属性
@code{(@var{attr-name} @var{content-type} @var{use-type} @var{default-value})}
の宣言:
@var{attr-name}はその宣言された属性の@var{UNRES-NAME}、
@var{content-type}はシンボル@code{CDATA}、@var{NMTOKEN}、@var{NMTOKENS}、
あるいは列挙されたタイプの文字列のリスト。
@var{use-type}はシンボル@code{REQUIRED}、@code{IMPLIED}、@code{FIXED}。
default-valueは、デフォルト値としての文字列か、与えられなければ@code{#f}。
@c COMMON
@end table

@defun make-empty-attlist
@defunx attlist-add attlist name-value
@defunx attlist-null?
@defunx attlist-remove-top attlist
@defunx attlist->alist attlist
@defunx attlist-fold
@c MOD sxml.ssax
@c EN
Utility procedures to deal with attribute list, which
keeps name-value association.
@c JP
名前-値の属性リストを扱うユーティリティ手続きです。
@c COMMON
@end defun

@defun make-xml-token kind head
@defunx xml-token? token
@c MOD sxml.ssax
@c EN
A constructor and a predicate for a @var{XML-TOKEN} record.
@c JP
@var{XML-TOKEN}レコードのコンストラクタと述語です。
@c COMMON
@end defun

@defmac xml-token-kind token
@defmacx xml-token-head token
@c MOD sxml.ssax
@c EN
Accessor macros of a @var{XML-TOKEN} record.
@c JP
@var{XML-TOKEN}レコードのアクセッサマクロです。
@c COMMON
@end defmac

@c ----------------------------------------------------------------------
@node SSAX low-level parsing code, SSAX higher-level parsers and scanners, SSAX data types, Functional XML parser
@subsection SSAX low-level parsing code
@c NODE SSAXの低レベルパージングコード

@c EN
They deal with primitive lexical units (Names, whitespaces, tags)
and with pieces of more generic productions. Most of these parsers
must be called in appropriate context. For example, @code{ssax:complete-start-tag}
must be called only when the start-tag has been detected and its @code{GI}
has been read.
@c JP
これらは、プリミティブな字句解析ユニット(名前、空白、タグ)や、
より一般的な断片を扱います。
これらのパーザのほとんどは、適切なコンテキストで呼ばれなければなりません。
例えば、@code{ssax:complete-start-tag}は、開始タグが検知されその@code{GI}が
読み込まれたときにのみ呼ばれなければなりません。
@c COMMON

@defun ssax:skip-S port
@c MOD sxml.ssax
@c EN
Skip the S (whitespace) production as defined by
@c JP
次のように定義されるS(空白)をスキップします。
@c COMMON
@example
 [3] S ::= (#x20 | #x9 | #xD | #xA)
@end example
@c EN
The procedure returns the first not-whitespace character it
encounters while scanning the @var{port}. This character is left
on the input stream.
@c JP
この手続きは、@var{port}のスキャン中に遭遇した最初の空白ではない文字を
返します。この文字は、入力ストリームに残されます。
@c COMMON
@end defun

@defun ssax:ncname-starting-char? a-char
@c MOD sxml.ssax
@c EN
Check to see if a-char may start a @code{NCName}.
@c JP
@code{NCName}がa-charで始まるかどうかを検査します。
@c COMMON
@end defun

@defun ssax:read-NCName port
@c MOD sxml.ssax
@c EN
Read a @code{NCName} starting from the current position in the @var{port} and
return it as a symbol.
@c JP
@var{port}で現在の位置から始まる@code{NCName}を読み込み、それをシンボルとして
返します。
@c COMMON
@end defun

@defun ssax:read-QName port
@c MOD sxml.ssax
@c EN
Read a (namespace-) Qualified Name, @code{QName}, from the current
position in the @var{port}.

From REC-xml-names:
@c JP
(名前空間)完全修飾名、@code{QName}を@var{port}の現在の位置から読み込みます。

REC-xml-namesは、
@c COMMON
@example
 [6] QName ::= (Prefix ':')? LocalPart
 [7] Prefix ::= NCName
 [8] LocalPart ::= NCName
@end example

@c EN
Return: an @var{UNRES-NAME}.
@c JP
戻り値は、@var{UNRES-NAME}です。
@c COMMON
@end defun

@defvar ssax:Prefix-XML
@c MOD sxml.ssax
@c EN
The prefix of the pre-defined XML namespace, i.e. '@code{xml}.
@c JP
定義済みのXML名前空間の接頭辞、つまり、'@code{xml}です。
@c COMMON
@end defvar

@defun ssax:read-markup-token port
@c MOD sxml.ssax
@c EN
This procedure starts parsing of a markup token. The current position
in the stream must be @code{#\<}. This procedure scans enough of the input stream
to figure out what kind of a markup token it is seeing. The procedure returns
an xml-token structure describing the token. Note, generally reading
of the current markup is not finished! In particular, no attributes of
the start-tag token are scanned.

Here's a detailed break out of the return values and the position in the @var{port}
when that particular value is returned:
@c JP
この手続きは、マークアップトークンのパージングを開始します。
ストリームの現在の位置は、@code{#\<}でなければなりません。
この手続きは、見ているマークアップトークンがどの種類のものか見当を
つけるに十分な程度、入力ストリームをスキャンします。
この手続きは、そのトークンを表現するxml-token構造を返します。
通常、その時点のマークアップの読み込みは完了していないことに注意して下さい。
特に、開始タグトークンの属性はスキャンされていません。

特定の値が返されたときの戻り値と@var{port}での位置を詳細に説明します。
@c COMMON
@table @code
@item PI-token
@c EN
only @code{PI}-target is read.
To finish the Processing Instruction and disregard it,
call @code{ssax:skip-pi}. @code{ssax:read-attributes} may be useful
as well (for @code{PI}s whose content is attribute-value
pairs)
@c JP
@code{PI}ターゲットのみが読み込まれました。
処理命令の読み込みを完了してそれを無視するためには、@code{ssax:skip-pi}を呼びます。
(@code{PI}の内容が、属性-値のペアの場合は、)@code{ssax:read-attributes}も
便利です。
@c COMMON
@item END-token
@c EN
The end tag is read completely; the current position
is right after the terminating @code{#\>} character.
@c JP
終了タグが完全に読み込まれました。
現在の位置は、終了の@code{#\>}文字の直後です。
@c COMMON
@item COMMENT
@c EN
is read and skipped completely. The current position
is right after "@code{-->}" that terminates the comment.
@c JP
コメントが完全に読み込まれスキップされました。
現在の位置は、コメントが終了する``@code{-->}''の直後です。
@c COMMON
@item CDSECT
@c EN
The current position is right after "@code{<!CDATA[}".
Use @code{ssax:read-cdata-body} to read the rest.
@c JP
現在の位置は、"@code{<!CDATA[}"の直後です。
残りを読むためには、@code{ssax:read-cdata-body}を使います。
@c COMMON
@item DECL
@c EN
We have read the keyword (the one that follows "@code{<!}")
identifying this declaration markup. The current
position is after the keyword (usually a
whitespace character)
@c JP
この宣言マークアップを識別するキーワード(``@code{<!}''に続くもの)を
読み込んだところです。現在の位置は、(通常は空白文字である)
そのキーワードの直後です。
@c COMMON
@item START-token
@c EN
We have read the keyword (@code{GI}) of this start tag.
No attributes are scanned yet. We don't know if this
tag has an empty content either.
Use @code{ssax:complete-start-tag} to finish parsing of
the token.
@c JP
この開始タグのキーワード(@code{GI})を読み込んだところです。
属性はまだスキャンされていません。
また、このタグが空の要素を持つかどうかも分かりません。
このトークンのパージングを終了するためには、
@code{ssax:complete-start-tag}を使います。
@c COMMON
@end table
@end defun

@defun ssax:skip-pi port
@c MOD sxml.ssax
@c EN
The current position is inside a @code{PI}. Skip till the rest of the @code{PI}.
@c JP
現在の位置は、@code{PI}の内側です。
@code{PI}の残りをスキップします。
@c COMMON
@end defun

@defun ssax:read-pi-body-as-string port
@c MOD sxml.ssax
@c EN
The current position is right after reading the @code{PITarget}. We read the
body of @code{PI} and return it as a string. The port will point to the
character right after '@code{?>}' combination that terminates @code{PI}.
@c JP
現在の位置は、@code{PITarget}を読み込んだ直後です。
@code{PI}のボディを読み込んで、それを文字列として返します。
ポートでは、@code{PI}を終了する'@code{?>}'の直後の文字を指します。
@c COMMON
@example
 [16] PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
@end example
@end defun

@defun ssax:skip-internal-dtd port
@c MOD sxml.ssax
@c EN
The current pos in the port is inside an internal DTD subset
(e.g., after reading @code{#\[ }that begins an internal DTD subset)
Skip until the "@code{]>}" combination that terminates this DTD
@c JP
ポートでの現在の位置は、内部DTDサブセットの内側です
(例えば、内部DTDサブセットの始まりである@code{#\[ }を読み込んだところ)。
このDTDを終了する、組み合わせとなる``@code{]>}''までをスキップします。
@c COMMON
@end defun

@defun ssax:read-cdata-body port str-handler seed
@c MOD sxml.ssax
@c EN
This procedure must be called after we have read a string "@code{<![CDATA[}"
that begins a @code{CDATA} section. The current position must be the first
position of the @code{CDATA} body. This function reads @emph{lines} of the @code{CDATA}
body and passes them to a @var{STR-HANDLER}, a character data consumer.
@c JP
この手続きは、@code{CDATA}セクションを開始する文字列、"@code{<![CDATA[}"を
読み込んだ後に呼ばれなければなりません。
現在の位置は、@code{CDATA}のボディの最初の位置です。
この手続きは、@code{CDATA}のボディの@emph{データ}を読み込み、それらを
@var{STR-HANDLER}(文字データのコンシューマ)へ渡します。
@c COMMON

@c EN
The str-handler is a @var{STR-HANDLER}, a procedure @code{string1} @var{string2} @var{seed}.
The first @var{string1} argument to @var{STR-HANDLER} never contains a newline.
The second @var{string2} argument often will. On the first invocation of
the @var{STR-HANDLER}, the seed is the one passed to @code{ssax:read-cdata-body}
as the third argument. The result of this first invocation will be
passed as the seed argument to the second invocation of the line
consumer, and so on. The result of the last invocation of the
@var{STR-HANDLER} is returned by the @code{ssax:read-cdata-body}.  Note a
similarity to the fundamental '@code{fold}' iterator.
@c JP
str-handlerは、@code{string1} @var{string2} @var{seed}を取る手続き
@var{STR-HANDLER}です。
@var{STR-HANDLER}の最初の引数@var{string1}は、改行を含みません。
2番目の引数@var{string2}は、改行を含むことがよくあります。
@var{STR-HANDLER}の最初の呼び出しでは、seedは@code{ssax:read-cdata-body}の
第3引数として渡されるものです。
この最初の呼び出しの結果は、文字データのコンシューマの引数seedとして渡され、
以降同じように続きます。
@var{STR-HANDLER}の最後の呼び出しの結果は、@code{ssax:read-cdata-body}
から返されるものです。
基本的な'@code{fold}'イテレータに似ています。
@c COMMON

@c EN
Within a @code{CDATA} section all characters are taken at their face value,
with only three exceptions:
@c JP
@code{CDATA}セクションでは、以下の3つだけの例外を除いて、全ての文字は
その表面上の値を持ちます。
@c COMMON
@itemize @bullet
@item
@c EN
@code{CR}, @code{LF}, and @code{CRLF} are treated as line delimiters, and passed
as a single @code{#\newline} to the @var{STR-HANDLER}.
@c JP
@code{CR}、@code{LF}、@code{CRLF}は行区切りとして扱われ、@var{STR-HANDLER}へは
1つの@code{#\newline}として渡されます。
@c COMMON
@item
@c EN
"@code{]]>}" combination is the end of the @code{CDATA} section.
@c JP
組み合わせとなる``@code{]]>}''は、@code{CDATA}セクションの終わりであると
されます。
@c COMMON
@item
@c EN
@code{&gt;} is treated as an embedded @code{#\>} character.
Note, @code{&lt;} and @code{&amp;} are not specially recognized (and are not expanded)!
@c JP
@code{&gt;}は、@code{#\>}文字の埋め込みとして扱われます。
@code{&lt;}と@code{&amp;}は特別なものとして認識されない(よって展開されない)ことに
注意が必要です!
@c COMMON
@end itemize
@end defun

@defun ssax:read-char-ref port
@c MOD sxml.ssax
@example
 [66]  CharRef ::=  '&#' [0-9]+ ';'
                  | '&#x' [0-9a-fA-F]+ ';'
@end example
@c EN
This procedure must be called after we we have read "@code{&#}"
that introduces a char reference.
The procedure reads this reference and returns the corresponding char.
The current position in @var{port} will be after "@code{;}" that terminates
the char reference.
Faults detected: @code{WFC: XML-Spec.html#wf-Legalchar}.
@c JP
この手続きは、文字参照を表す``@code{&#}''を読み込んだ後に呼ばれなければ
なりません。
この手続きは、この参照を読み込んで対応する文字を返します。
@var{port}での現在の位置は、文字参照の終わりとなる``@code{;}''の後と
なります。
@code{WFC: XML-Spec.html#wf-Legalchar}も参照のこと。
@c COMMON

@c EN
According to Section "4.1 Character and Entity References"
of the XML Recommendation:
@c JP
XML勧告のセクション``4.1 文字と実体参照''によると、
@c COMMON
@quotation
@c EN
"[Definition: A character reference refers to a specific character
 in the ISO/IEC 10646 character set, for example one not directly
 accessible from available input devices.]"
@c JP
``[定義: 文字参照は、ISO/IEC 10646文字集合にある特定の文字を参照する。
例えば、利用できる入力デバイスからは直接アクセスできないものなど。]''
@c COMMON
@end quotation
@c EN
Therefore, we use a @code{ucscode->char} function to convert a character
code into the character -- @emph{regardless} of the current character
encoding of the input stream.
@c JP
したがって、入力ストリームの現在の文字エンコーディングに@emph{関係なく}、
文字コードを文字に変換するために関数@code{ucscode->char}を使います。
@c COMMON
@end defun

@defun ssax:handle-parsed-entity port name entities content-handler str-handler seed
@c MOD sxml.ssax
@c EN
Expand and handle a parsed-entity reference
@c JP
解析済み実体参照を展開し処理します。
@c COMMON
@itemize @bullet
@item
@c EN
@var{port} - a PORT
@c JP
@var{port} - ポート
@c COMMON
@item
@c EN
@var{name} - the name of the parsed entity to expand, a symbol.
@c JP
@var{name} - 展開する解析済み実体の名前。シンボル。
@c COMMON
@item
@c EN
@var{entities} - see @var{ENTITIES}
@c JP
@var{entities} - @var{ENTITIES}を参照。
@c COMMON
@item
@c EN
@var{content-handler} - procedure @var{port} @var{entities} @var{seed}
that is supposed to return a @var{seed}.
@c JP
@var{content-handler} - @var{port} @var{entities} @var{seed}を取る手続きで、
@var{seed}を返す。
@c COMMON
@item
@c EN
@var{str-handler} - a @var{STR-HANDLER}. It is called if the entity in question
turns out to be a pre-declared entity
@c JP
@var{str-handler} - @var{STR-HANDLER}。対象となる実体が宣言済み実体となった
場合に呼ばれる。
@c COMMON
@end itemize
@c EN
The result is the one returned by @var{content-handler} or @var{str-handler}.
@c JP
戻り値は、@var{content-handler}か@var{str-handler}から返された値です。
@c COMMON

@c EN
Faults detected:
@c JP
こちらも参照のこと。
@c COMMON
@example
  WFC: XML-Spec.html#wf-entdeclared
  WFC: XML-Spec.html#norecursion
@end example
@end defun

@defun ssax:read-attributes port entities
@c MOD sxml.ssax
@c EN
This procedure reads and parses a production @code{Attribute*}
@c JP
この手続きは、@code{Attribute*}を読み込みパーズします。
@c COMMON
@example
 [41] Attribute ::= Name Eq AttValue
 [10] AttValue ::=  '"' ([^<&"] | Reference)* '"'
                 | "'" ([^<&'] | Reference)* "'"
 [25] Eq ::= S? '=' S?
@end example
@c EN
The procedure returns an @var{ATTLIST}, of @var{Name} (as @var{UNRES-NAME}),
@var{Value} (as string) pairs.
The current character on the @var{port} is a non-whitespace character
that is not an ncname-starting character.
@c JP
この手続きは、@var{Name}(@var{UNRES-NAME})と@var{Value}(文字列)のペアである
@var{ATTLIST}を返します。
@var{port}での現在の文字は、NCNameの開始文字ではなく、空白ではない文字です。
@c COMMON

@c EN
Note the following rules to keep in mind when reading an 'AttValue'
"Before the value of an attribute is passed to the application
or checked for validity, the XML processor must normalize it as follows:
@c JP
'AttValue'を読み込むときには、以下のルールに留意して下さい。
``属性の値がアプリケーションに渡されるか妥当性が検査される前に、
XMLプロセッサはそれを以下のように正規化しなければならない:
@c COMMON
@itemize @bullet
@item
@c EN
a character reference is processed by appending the referenced
character to the attribute value
@c JP
文字参照は、属性値に参照された文字を追加することで処理される。
@c COMMON
@item
@c EN
an entity reference is processed by recursively processing the
replacement text of the entity [see @var{ENTITIES}]
[named entities amp lt gt quot apos are assumed pre-declared]
@c JP
実体参照は、その実体のテキストの置換を再帰的に行うことにより
処理される。[@var{ENTITIES}参照] [名前付きのエンティティ、amp lt gt
quot aposは定義済みと想定される]
@c COMMON
@item
@c EN
a whitespace character (@code{#x20}, @code{#xD}, @code{#xA}, @code{#x9}) is processed by appending @code{#x20}
to the normalized value, except that only a single @code{#x20} is appended for a
"@code{#xD#xA}" sequence that is part of an external parsed entity or the
literal entity value of an internal parsed entity
@c JP
空白文字(@code{#x20}、@code{#xD}、@code{#xA}、@code{#x9})は、
外部解析済み実体か内部解析済み実体のリテラルの実体の値の一部である
``@code{#xD#xA}''のシーケンスにただ1つの@code{#x20}が追加されることを
除いて、正規化された値に@code{#x20}を追加することで処理される。
@c COMMON
@item
@c EN
other characters are processed by appending them to the normalized value "
@c JP
他の文字は、正規化された値をそれらに追加することにより処理される''
@c COMMON
@end itemize

@c EN
Faults detected:
@c JP
こちらも参照のこと。
@c COMMON
@example
 WFC: XML-Spec.html#CleanAttrVals
 WFC: XML-Spec.html#uniqattspec
@end example
@end defun

@defun ssax:resolve-name port unres-name namespaces apply-default-ns?
@c MOD sxml.ssax
@c EN
Convert an @var{unres-name} to a @var{res-name} given the appropriate @var{namespaces}
declarations.
The last parameter @var{apply-default-ns?} determines if the default
namespace applies (for instance, it does not for attribute names)

Per @code{REC-xml-names/#nsc-NSDeclared}, "xml" prefix is considered pre-declared
and bound to the namespace name "@url{http://www.w3.org/XML/1998/namespace}".

This procedure tests for the namespace constraints:
@url{http://www.w3.org/TR/REC-xml-names/#nsc-NSDeclared}.
@c JP
与えられた適切な@var{namespaces}の宣言を用いて、@var{unres-name}を
@var{res-name}に変換する。
最後の引数@var{apply-default-ns?}は、デフォルト名前空間の適用を行うか
どうかを決めます(例えば、属性名には適用しないなど)。

@code{REC-xml-names/#nsc-NSDeclared}によれば、接頭辞``xml''は
名前空間名``@url{http://www.w3.org/XML/1998/namespace}''に定義済みで束縛されていると
されます。

この手続きは、名前空間の制約をテストします:
@url{http://www.w3.org/TR/REC-xml-names/#nsc-NSDeclared}。
@c COMMON
@end defun

@defun ssax:uri-string->symbol uri-str
@c MOD sxml.ssax
@c EN
Convert a @var{uri-str} to an appropriate symbol.
@c JP
@var{uri-str}を適切なシンボルに変換します。
@c COMMON
@end defun

@defun ssax:complete-start-tag tag port elems entities namespaces
@c MOD sxml.ssax
@c EN
This procedure is to complete parsing of a start-tag markup. The
procedure must be called after the start tag token has been
read. @var{Tag} is an @var{UNRES-NAME}.
@var{Elem
s} is an instance of @code{xml-decl::elems};
it can be @code{#f} to tell the function to do @emph{no} validation of elements
and their attributes.
@c JP
この手続きは、開始タグのマークアップのパージングを完了するためのものです。
この手続きは、開始タグトークンが読み込まれた後に呼ばれなければなりません。
@var{tag}は@var{UNRES-NAME}です。
@var{elems}は@code{xml-decl::elems}のインスタンスで、
手続きに、要素とそれらの属性の妥当性検査を@emph{行わない}ように
指示するために、@code{#f}を指定することができます。
@c COMMON

@c EN
This procedure returns several values:
@c JP
この手続きはいくつかの値を返します。
@c COMMON
@table @var
@item elem-gi
@c EN
a @var{RES-NAME}.
@c JP
@var{RES-NAME}。
@c COMMON
@item attributes
@c EN
element's attributes, an @var{ATTLIST} of @code{(@var{res-name} . @var{string})}
pairs. The list does @emph{not} include @code{xmlns} attributes.
@c JP
要素の属性。@code{(@var{res-name} . @var{string})}というペアの@var{ATTLIST}。
このリストは、@code{xmlns}属性を@emph{含みません}。
@c COMMON
@item namespaces
@c EN
the input list of namespaces amended with namespace
(re-)declarations contained within the start-tag under parsing
@var{ELEM-CONTENT-MODEL}.
@c JP
パージング中の開始タグに含まれる名前空間(再)宣言により修正された後の
名前空間の入力リスト。
@c COMMON
@end table

@c EN
On exit, the current position in @var{port} will be the first character after
@code{#\>} that terminates the start-tag markup.
@c JP
終了時の@var{port}での現在の位置は、開始タグのマークアップを終了する
@code{#\>}の後になります。
@c COMMON

@c EN
Faults detected:
@c JP
こちらも参照のこと。
@c COMMON
@example
 VC: XML-Spec.html#enum
 VC: XML-Spec.html#RequiredAttr
 VC: XML-Spec.html#FixedAttr
 VC: XML-Spec.html#ValueType
 WFC: XML-Spec.html#uniqattspec (after namespaces prefixes are resolved)
 VC: XML-Spec.html#elementvalid
 WFC: REC-xml-names/#dt-NSName
@end example

@c EN
Note, although XML Recommendation does not explicitly say it,
@var{xmlns} and @var{xmlns:} attributes don't have to be declared (although they
can be declared, to specify their default value).
@c JP
XML勧告では明示されていませんが、@var{xmlns}と@var{xmlns:}属性は、
(そのデフォルト値を指定するために宣言されることが出来ますが)
宣言される必要がないことに注意して下さい。
@c COMMON
@end defun

@defun ssax:read-external-id port
@c MOD sxml.ssax
@c EN
This procedure parses an @code{ExternalID} production.
@c JP
この手続きは、@code{ExternalID}をパーズします。
@c COMMON
@example
 [75] ExternalID ::= 'SYSTEM' S SystemLiteral
                 | 'PUBLIC' S PubidLiteral S SystemLiteral
 [11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'")
 [12] PubidLiteral ::=  '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"
 [13] PubidChar ::=  #x20 | #xD | #xA | [a-zA-Z0-9]
                | [-'()+,./:=?;!*#@@$_%]
@end example
@c EN
This procedure is supposed to be called when an @code{ExternalID} is expected;
that is, the current character must be either @code{#\S} or @code{#\P} that start
correspondingly a @code{SYSTEM} or @code{PUBLIC} token. This procedure returns the
@code{SystemLiteral} as a string. A @code{PubidLiteral} is disregarded if present.
@c JP
この手続きは、@code{ExternalID}が期待されるところで呼ばれます。
つまり、現在の文字は、それぞれ@code{SYSTEM}か@code{PUBLIC}トークンを開始する
@code{#\S}か@code{#\P}でなければなりません。
この手続きは、@code{SystemLiteral}を文字列として返します。
@code{PubidLiteral}は、存在したとしても無視されます。
@c COMMON
@end defun

@c ----------------------------------------------------------------------
@node SSAX higher-level parsers and scanners, SSAX Highest-level parsers - XML to SXML, SSAX low-level parsing code, Functional XML parser
@subsection SSAX higher-level parsers and scanners
@c NODE SSAXの高レベルのパーザとスキャナ

@c EN
They parse productions corresponding to the whole (document) entity
or its higher-level pieces (prolog, root element, etc).
@c JP
これらは、全体的な実体(ドキュメント)あるいはその高レベルな断片
(プロローグ、ルート要素など)をパーズします。
@c COMMON

@defun ssax:scan-Misc port
@c MOD sxml.ssax
@c EN
Scan the @code{Misc} production in the context:
@c JP
そのコンテキストでの@code{Misc}をスキャンします。
@c COMMON
@example
[1]  document ::=  prolog element Misc*
[22] prolog ::= XMLDecl? Misc* (doctypedec l Misc*)?
[27] Misc ::= Comment | PI |  S
@end example
@c EN
The following function should be called in the prolog or epilog contexts.
In these contexts, whitespaces are completely ignored.
The return value from @code{ssax:scan-Misc} is either a @code{PI}-token,
a @code{DECL}-token, a @code{START} token, or EOF.
Comments are ignored and not reported.
@c JP
以下の関数は、プロローグかエピローグのコンテキストで呼ばれます。
これらのコンテキストでは、空白文字は完全に無視されます。
@code{ssax:scan-Misc}からの戻り値は、@code{PI}トークンか@code{DECL}トークン、
@code{START}トークン、EOFのいずれかです。
コメントは無視され報告されません。
@c COMMON
@end defun

@defun ssax:read-char-data port expect-eof? str-handler seed
@c MOD sxml.ssax
@c EN
This procedure is to read the character content of an XML document
or an XML element.
@c JP
この手続きは、XML文書かXML要素の文字内容を読むためのものです。
@c COMMON
@example
 [43] content ::=
        (element | CharData | Reference | CDSect | PI
         | Comment)*
@end example
@c EN
To be more precise, the procedure reads @code{CharData}, expands @code{CDSect}
and character entities, and skips comments. The procedure stops
at a named reference, EOF, at the beginning of a @code{PI} or a start/end tag.
@c JP
具体的には、この手続きは@code{CharData}を読み込み、@code{CDSect}と
文字実体を展開し、コメントをスキップします。
この手続きは、名前付き参照、EOF、@code{PI}あるいは開始/終了タグの開始地点で
停止します。
@c COMMON

@table @var
@item port
@c EN
a port to read
@c JP
読み込むポート。
@c COMMON
@item expect-eof?
@c EN
a boolean indicating if EOF is normal, i.e., the character
data may be terminated by the EOF. EOF is normal
while processing a parsed entity.
@c JP
EOFがノーマルかどうか、つまり、文字データがEOFで終わるかどうかを
表す真偽値。解析済み実体を処理している間はEOFはノーマル。
@c COMMON
@item str-handler
@c EN
a @var{STR-HANDLER}.
@c JP
@var{STR-HANDLER}。
@c COMMON
@item seed
@c EN
an argument passed to the first invocation of @var{STR-HANDLER}.
@c JP
@var{STR-HANDLER}の最初の呼び出し時に渡される引数。
@c COMMON
@end table

@c EN
The procedure returns two results: @var{seed} and @var{token}.

The @var{seed} is the result of the last invocation of @var{str-handler}, or the
original seed if @var{str-handler} was never called.
@c JP
この手続きは2つの結果、@var{seed}と@var{token}を返します。

@var{seed}は@var{str-handler}の最後の呼び出しの結果、あるいは
@var{str-handler}が一度も呼ばれなかった場合はオリジナルのseedです。
@c COMMON

@c EN
@var{Token} can be either an eof-object (this can happen only if
@var{expect-eof?} was @code{#t}), or:
@c JP
@var{token}はEOFオブジェクト(これは@var{expect-eof?}が@code{#t}の場合のみ)か、
@c COMMON
@itemize @bullet
@item
@c EN
an xml-token describing a @var{START} tag or an @var{END}-tag;
For a start token, the caller has to finish reading it.
@c JP
@var{START}タグか@var{END}タグを表すxml-token。
開始トークンの場合は、呼び出し側が読み込みを完了する必要がある。
@c COMMON
@item
@c EN
an xml-token describing the beginning of a @code{PI}. It's up to an
application to read or skip through the rest of this @code{PI};
@c JP
@code{PI}の開始を表すxml-token。
この@code{PI}の残りを読み込むかスキップするかはアプリケーションに
任される。
@c COMMON
@item
@c EN
an xml-token describing a named entity reference.
@c JP
名前付き実体参照を表すxml-token。
@c COMMON
@end itemize

@c EN
@code{CDATA} sections and character references are expanded inline and
never returned. Comments are silently disregarded.

As the XML Recommendation requires, all whitespace in character data
must be preserved. However, a @code{CR} character (@code{#xD}) must be disregarded
if it appears before a @code{LF} character (@code{#xA}), or replaced by a @code{#xA} character
otherwise. See Secs. 2.10 and 2.11 of the XML Recommendation. See also
the canonical XML Recommendation.
@c JP
@code{CDATA}セクションと文字参照はインラインで展開され返されません。
コメントは無視されます。

XML勧告が要求するように、文字データ中の全ての空白文字は保存されなければなりません。
しかし、@code{CR}文字(@code{#xD})は、@code{LF}文字(@code{#A})の前に現れるか
@code{#xA}文字で置き換えられた場合は、無視されなければなりません。
XML勧告のセクション2.10と2.11を参照して下さい。
また、正規のXML勧告も参照して下さい。
@c COMMON
@end defun

@defun ssax:assert-token token kind gi error-cont
@c MOD sxml.ssax
@c EN
Make sure that @var{token} is of anticipated @var{kind} and has anticipated @var{gi}.
Note @var{gi} argument may actually be a pair of two symbols, Namespace
URI or the prefix, and of the localname.
If the assertion fails, @var{error-cont} is evaluated by passing it
three arguments: @var{token} @var{kind} @var{gi}.
The result of @var{error-cont} is returned.
@c JP
@var{token}が、予想された@var{kind}のもので、予想された@var{gi}を
持つことを確認します。@var{gi}引数は、実際には2つのシンボル、
名前空間URIかその接頭辞と、そのローカル名のペアでしょう。
アサーションが失敗したら、@var{error-cont}に3つの引数、@var{token} @var{kind} @var{gi}
を渡されて評価されます。
@var{error-cont}の結果が返されます。
@c COMMON
@end defun

@c ----------------------------------------------------------------------
@node SSAX Highest-level parsers - XML to SXML,  , SSAX higher-level parsers and scanners, Functional XML parser
@subsection SSAX Highest-level parsers - XML to SXML
@c NODE SSAXの高レベルのパーザ - XMLからSXMLへ

@c EN
These parsers are a set of syntactic forms to instantiate a SSAX parser.
A user can instantiate the parser to do the full validation, or
no validation, or any particular validation. The user specifies
which @code{PI} he wants to be notified about. The user tells what to do
with the parsed character and element data. The latter handlers
determine if the parsing follows a SAX or a DOM model.
@c JP
これらのパーザは、SSAXパーザをインスタンス化するための構文的フォームのセットです。
ユーザは、完全な妥当性検査、妥当性検査なし、特定の妥当性検査を行うために
このパーザをインスタンス化できます。
ユーザは、どの@code{PI}について通知されたいかを指定します。
ユーザは、解析済み文字と要素のデータで何をしたいかを知らせます。
後者のハンドラは、パージングがSAXやDOMモデルに従うかを決定します。
@c COMMON

@defmac ssax:make-pi-parser my-pi-handlers
@c MOD sxml.ssax
@c EN
Create a parser to parse and process one Processing Element (@code{PI}).
@c JP
1つの処理命令(@code{PI})をパーズして処理するパーザを作ります。
@c COMMON

@c EN
@var{My-pi-handlers}:
An assoc list of pairs (@var{PI-TAG} . @var{PI-HANDLER})
where @var{PI-TAG} is an @var{NCName} symbol, the @code{PI} target, and
@var{PI-HANDLER} is a procedure @var{port} @var{pi-tag} @var{seed}
where @var{port} points to the first symbol after the @code{PI} target.
The handler should read the rest of the @code{PI} up to and including
the combination '@code{?>}' that terminates the @code{PI}. The handler should
return a new seed.
One of the @var{PI-TAG}s may be a symbol @code{*DEFAULT*}. The corresponding
handler will handle @code{PI}s that no other handler will. If the
@code{*DEFAULT*} @var{PI-TAG} is not specified,
@code{ssax:make-pi-parser} will make
one, which skips the body of the @code{PI}.
@c JP
@var{my-pi-handlers}:
(@var{PI-TAG} . @var{PI-HANDLER})のペアの連想リスト。
@var{PI-TAG}は@var{NCName}のシンボル、@code{PI}ターゲット。
@var{PI-HANDLER}は@var{port} @var{pi-tag} @var{seed}を引数とする手続きで、
@var{port}では@code{PI}ターゲットの後の最初のシンボルを指しています。
ハンドラは、@code{PI}を終了する組み合わせとなる'@code{?>}'を含む、
@code{PI}の残りを読み込みます。ハンドラは新しいseedを返します。
@var{PI-TAG}の1つは、シンボル@code{*DEFAULT*}でしょう。
これに対応するハンドラは、他のハンドラが扱わない@code{PI}を処理します。
@code{*DEFAULT*} @var{PI-TAG}が指定されていない場合は、
@code{ssax:make-pi-parser}は、@code{PI}のボディをスキップするパーザを
作ります。
@c COMMON

@c EN
The output of the @code{ssax:make-pi-parser} is a procedure
@var{port} @var{pi-tag} @var{seed},
that will parse the current @code{PI} accoding to user-specified handlers.
@c JP
@code{ssax:make-pi-parser}が返すのは、@var{port} @var{pi-tag} @var{seed}を
取る手続きで、ユーザ指定のハンドラに従い現在の@code{PI}をパーズします。
@c COMMON
@end defmac

@defmac ssax:make-elem-parser my-new-level-seed my-finish-element my-char-data-handler my-pi-handlers
@c MOD sxml.ssax
@c EN
Create a parser to parse and process one element, including its
character content or children elements. The parser is typically
applied to the root element of a document.
@c JP
その文字内容や子要素をも含む１つの要素をパーズし処理するパーザを作ります。
このパーザは通常、ドキュメントのルート要素の適用されます。
@c COMMON

@table @var
@item my-new-level-seed
@c EN
procedure @var{elem-gi} @var{attributes} @var{namespaces} @var{expected-content} @var{seed} @*
where @var{elem-gi} is a @var{RES-NAME} of the element
about to be processed.
This procedure is to generate the seed to be passed
to handlers that process the content of the element.
@c JP
@var{elem-gi} @var{attributes} @var{namespaces} @var{expected-content} @var{seed} @*
を引数に取る手続きで、@var{elem-gi}は処理されようとしている要素の@var{RES-NAME}です。
この手続きは、要素の内容を処理するハンドラに渡されるseedを生成します。
@c COMMON
@c This is the function identified as 'fdown' in the denotational
@c semantics of the XML parser given in the title comments to this
@c file.

@item my-finish-element
@c EN
procedure @var{elem-gi} @var{attributes} @var{namespaces} @var{parent-seed} @var{seed} @*
This procedure is called when parsing of @var{elem-gi} is finished.
The @var{seed} is the result from the last content parser (or
from @var{my-new-level-seed} if the element has the empty content).
@var{Parent-seed} is the same seed as was passed to @var{my-new-level-seed}.
The procedure is to generate a seed that will be the result
of the element parser.
@c JP
@var{elem-gi} @var{attributes} @var{namespaces} @var{parent-seed} @var{seed} @*
を引数に取る手続きです。この手続きは、@var{elem-gi}のパージングが完了した時に
呼ばれます。
@var{seed}は、最後に呼ばれたパーザからの(あるいは、
要素が空要素であった場合は、@var{my-new-level-seed}からの)結果です。
@var{parent-seed}は、@var{my-new-level-seed}へ渡されたのと同じseedです。
この手続きは、パーザの結果となるseedを生成するためのものです。
@c COMMON
@c This is the function identified as 'fup' in the denotational
@c semantics of the XML parser given in the title comments to this
@c file.

@item my-char-data-handler
@c EN
A @var{STR-HANDLER}.
@c JP
@var{STR-HANDLER}。
@c COMMON

@item my-pi-handlers
@c EN
See @code{ssax:make-pi-handler} above.
@c JP
@code{ssax:make-pi-handler}を参照して下さい。
@c COMMON
@end table

@c EN
The generated parser is a:
procedure @var{start-tag-head} @var{port} @var{elems} @var{entities}
@var{namespaces} @var{preserve-ws?} @var{seed}. @*
The procedure must be called after the start tag token has been
read. @var{Start-tag-head} is an @var{UNRES-NAME} from the start-element tag.
@var{Elems} is an instance of @code{xml-decl::elems}.
See @code{ssax:complete-start-tag::preserve-ws?}
@c JP
生成されたパーザは:
@var{start-tag-head} @var{port} @var{elems} @var{entities} @var{namespaces}
@var{preserve-ws?} @var{seed} @*
を引数に取る手続きです。
この手続きは、開始タグのトークンが読み込まれた後に呼ばれなければなりません。
@var{start-tag-head}は要素の開始タグの@var{UNRES-NAME}です。
@var{elems}は@code{xml-decl::elems}のインスタンスです。
@code{ssax:complete-start-tag::preserve-ws?}も参照して下さい。
@c COMMON

@c EN
Faults detected:
@c JP
こちらも参照のこと。
@c COMMON
@example
 VC: XML-Spec.html#elementvalid
 WFC: XML-Spec.html#GIMatch
@end example
@end defmac

@defmac ssax:make-parser user-handler-tag user-handler-proc @dots{}
@c MOD sxml.ssax
@c EN
Create an XML parser, an instance of the XML parsing framework.
This will be a SAX, a DOM, or a specialized parser depending
on the supplied user-handlers.

@var{user-handler-tag} is a symbol that identifies a procedural expression
that follows the tag. Given below are tags and signatures of the
corresponding procedures. Not all tags have to be specified. If some
are omitted, reasonable defaults will apply.
@c JP
XMLパージングフレームワークのインスタンスである、XMLパーザを作ります。
これは、提供されるユーザハンドラによって、SAX、DOM、あるいは特化された
パーザになります。

@var{user-handler-tag}はシンボルで、タグに続く手続き的な式を識別します。
以下にタグと対応する手続きのシグネチャを示します。
全てのタグが指定される必要はありません。
いくつかが省略されると、合理的なデフォルトのものが適用されます。
@c COMMON

@table @code
@item tag: @var{DOCTYPE}
@c EN
handler-procedure: @var{port} @var{docname} @var{systemid} @var{internal-subset?} @var{seed}

If @var{internal-subset?} is @code{#t}, the current position in the port
is right after we have read @code{#\[} that begins the internal DTD subset.
We must finish reading of this subset before we return
(or must call skip-internal-subset if we aren't interested in reading it).
The port at exit must be at the first symbol after the whole
DOCTYPE declaration.

The handler-procedure must generate four values: @*
@var{elems} @var{entities} @var{namespaces} @var{seed}@*
See @code{xml-decl::elems} for @var{elems}.
It may be @code{#f} to switch off the validation.
@var{namespaces} will typically contain @var{USER-PREFIX}es for selected @var{URI-SYMB}s.
The default handler-procedure skips the internal subset,
if any, and returns @code{(values #f '() '() seed)}.
@c JP
ハンドラ手続きの引数: @var{port} @var{docname} @var{systemid} @var{internal-subset?} @var{seed}

@var{internal-subset?}が@code{#t}なら、ポートでの現在の位置は内部DTDサブセットの
開始となる@code{#\[}を読んだ直後です。
手続きから戻る前に、このサブセットの残りの読み込みを完了しなければなりません
(あるいは、それを読むことに興味がなければ、skip-internal-subsetを呼ばなければなりません)。
終了時のポートでの位置は、DOCTYPE宣言全体のあとの最初のシンボルでなければなりません。

ハンドラ手続きは4つの値: @*
@var{elems} @var{entities} @var{namespaces} @var{seed} @*
を生成しなければなりません。
@var{elems}については、@code{xml-decl::elems}を参照して下さい。
妥当性検査をオフにするためには、@code{#f}になるでしょう。
@var{namespaces}は、通常、選択された@var{URI-SYMB}に対して@var{USER-PREFIX}を含む
でしょう。
デフォルトのハンドラ手続きは、内部サブセットがあってもそれをスキップし、
@code{(values #f '() '() seed)}を返します。
@c COMMON

@item tag: @var{UNDECL-ROOT}
@c EN
handler-procedure: @var{elem-gi} @var{seed} @*
where @var{elem-gi} is an @var{UNRES-NAME} of the root element. This procedure
is called when an XML document under parsing contains @emph{no} @code{DOCTYPE}
declaration.
The handler-procedure, as a DOCTYPE handler procedure above,
must generate four values: @*
@var{elems} @var{entities} @var{namespaces} @var{seed}@*
The default handler-procedure returns @code{(values #f '() '() seed)}.
@c JP
ハンドラ手続きの引数: @var{elem-gi} @var{seed} @*
@var{elem-gi}はルート要素の@var{UNRES-NAME}です。
この手続きは、パージング中のXML文書が@code{DOCTYPE}宣言を@emph{含まない}時に
呼ばれます。
ハンドラ手続きは、上ではDOCTYPEハンドラですが、4つの値: @*
@var{elems} @var{entities} @var{namespaces} @var{seed}@*
を生成しなければなりません。
デフォルトのハンドラ手続きは、@code{(values #f '() '() seed)}を返します。
@c COMMON

@item tag: @var{DECL-ROOT}
@c EN
handler-procedure: @var{elem-gi} @var{seed} @*
where @var{elem-gi} is an @var{UNRES-NAME} of the root element. This procedure
is called when an XML document under parsing does contains the @code{DOCTYPE}
declaration.
The handler-procedure must generate a new @code{seed} (and verify
that the name of the root element matches the doctype, if the handler
so wishes).
The default handler-procedure is the identity function.
@c JP
ハンドラ手続きの引数: @var{elem-gi} @var{seed} @*
@var{elem-gi}は、ルート要素の@var{UNRES-NAME}です。
この手続きは、パージング中のXML文書が@code{DOCTYPE}宣言を含む場合に呼ばれます。
このハンドラ手続きは、新しい@code{seed}を生成しなければなりません
(そして、ハンドラが望めば、ルート要素の名前がDOCTYPEにマッチするかを
検証します)。
デフォルトのハンドラ手続きは、それ自身を返す手続きです。
@c COMMON

@item tag: @var{NEW-LEVEL-SEED}
@c EN
handler-procedure: see @code{ssax:make-elem-parser}, @var{my-new-level-seed}
@c JP
ハンドラ手続きの引数: @code{ssax:make-elem-parser}と@var{my-new-level-seed}を参照して下さい。
@c COMMON

@item tag: @var{FINISH-ELEMENT}
@c EN
handler-procedure: see @code{ssax:make-elem-parser}, @var{my-finish-element}
@c JP
ハンドラ手続きの引数: @code{ssax:make-elem-parser}と@var{my-finish-element}を参照して下さい。
@c COMMON

@item tag: @var{CHAR-DATA-HANDLER}
@c EN
handler-procedure: see @code{ssax:make-elem-parser}, @var{my-char-data-handler}
@c JP
ハンドラ手続きの引数: @code{ssax:make-elem-parser}と@var{my-char-data-handler}を参照して下さい。
@c COMMON

@item tag: @var{PI}
@c EN
handler-procedure: see @code{ssax:make-pi-parser}. @*
The default value is @code{'()}.
@c JP
ハンドラ手続きの引数: @code{ssax:make-pi-parser}を参照して下さい。@*
デフォルトの値は、@code{'()}です。
@c COMMON
@end table

@c EN
The generated parser is a @*
procedure @var{PORT} @var{SEED}

This procedure parses the document prolog and then exits to
an element parser (created by ssax:make-elem-parser) to handle
the rest.
@c JP
生成されるパーザは、@*
@var{PORT} @var{SEED}を取る手続き、@*
です。

この手続きは、ドキュメントのプロローグをパーズして、
その残りを処理するために(ssax:make-elem-parserで作られた)パーザへ
引き継いで終了します。
@c COMMON

@example
 [1]  document ::=  prolog element Misc*
 [22] prolog ::= XMLDecl? Misc* (doctypedec | Misc*)?
 [27] Misc ::= Comment | PI |  S

 [28] doctypedecl ::=  '<!DOCTYPE' S Name (S ExternalID)? S?
                        ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
 [29] markupdecl ::= elementdecl | AttlistDecl
                      | EntityDecl
                      | NotationDecl | PI
                      | Comment
@end example
@end defmac

@c EN
A few utility procedures that turned out useful.
@c JP
いくつかの便利なユーティリティ手続きがあります。
@c COMMON

@defun ssax:reverse-collect-str fragments
@c MOD sxml.ssax
@c EN
given the list of @var{fragments} (some of which are text strings)
reverse the list and concatenate adjacent text strings.
@c JP
@var{fragments}(そのいくつかはテキスト文字列)のリストを渡すと、
そのリストを逆順にして隣り合ったテキスト文字列を連結します。
@c COMMON
@end defun

@defun ssax:reverse-collect-str-drop-ws fragments
@c MOD sxml.ssax
@c EN
given the list of fragments (some of which are text strings)
reverse the list and concatenate adjacent text strings.
We also drop "unsignificant" whitespace, that is, whitespace
in front, behind and between elements. The whitespace that
is included in character data is not affected.
We use this procedure to "intelligently" drop "insignificant"
whitespace in the parsed SXML. If the strict compliance with
the XML Recommendation regarding the whitespace is desired, please
use the @code{ssax:reverse-collect-str} procedure instead.
@c JP
fragments(そのいくつかはテキスト文字列)のリストを渡すと、
そのリストを逆順にして隣り合ったテキスト文字列を連結します。
``重要でない''空白文字、つまり、最初や最後、要素の間にある空白文字を
削除します。文字データに含まれる空白文字には影響を与えません。
この手続きは、パーズされたSXMLにある``重要でない''空白文字を
``知的に''削除するために使います。空白文字に関して、厳密に
XML勧告に準拠したい場合は、代わりに手続き
@code{ssax:reverse-collect-str}を使って下さい。
@c COMMON
@end defun

@defun ssax:xml->sxml port namespace-prefix-assig
@c MOD sxml.ssax
@c EN
This is an instance of a SSAX parser above that returns an SXML
representation of the XML document to be read from @var{port}.
@var{Namespace-prefix-assig} is a list of
@code{(@var{USER-PREFIX} . @var{URI-STRING})}
that assigns @var{USER-PREFIX}es to certain namespaces identified by
particular @var{URI-STRING}s. It may be an empty list.
The procedure returns an SXML tree. The port points out to the
first character after the root element.
@c JP
これは、上のSSAXパーザのインスタンスで、@var{port}から読み込まれる
XMLドキュメントのSXML表現を返します。
@var{namespace-prefix-assig}は、@code{(@var{USER-PREFIX} . @var{URI-STRING})}
のリストで、特定の@var{URI-STRING}で識別されるある名前空間を
@var{USER-PREFIX}に割り当てます。これは空リストでも構いません。
この手続きは、SXMLツリーを返します。
ポートでの位置は、ルート要素の後の最初の文字を指します。
@c COMMON
@end defun

@c ----------------------------------------------------------------------
@node SXML query language, Manipulating SXML structure, Functional XML parser, Library modules - Utilities
@section @code{sxml.sxpath} - SXML query language
@c NODE SXMLクエリ言語, @code{sxml.sxpath} - SXMLクエリ言語

@deftp {Module} sxml.sxpath
@mdindex sxml.sxpath
@c EN
SXPath is a query language for SXML, an instance of XML Information
set (Infoset) in the form of s-expressions.

It is originally written by Oleg Kiselyov, and
improved by Dmitry Lizorkin and Kirill Lisovsky.
This module also incorporates
various procedures written for SXPath by Dmitry Lizorkin and Kirill Lisovsky.

Current version is based on sxpathlib.scm,v 3.915,
sxpath.scm,v 1.1, and sxpath-ext.scm,v 1.911.
@c JP
SXPathは、XML Information set (Infoset)のインスタンスのS式フォームである
SXMLのためのクエリ言語です。

これは最初にOleg Kiselyovによって書かれ、Dmitry LizorkinとKirill Lisovsky
によって改良されました。
このモジュールにはまた、Dmitry LizorkinとKirill LisovskyによりSXPathのために
書かれたたくさんの手続きが盛り込まれています。

現在のバージョンは、sxpathlib.scm v3.915、sxpath.scm v1.1、sxpath-ext.scm v1.911を
ベースにしています。
@c COMMON
@end deftp

@c EN
This manual is mostly derived from the comments in the
original source files.

The module consists of three layers.
@c JP
このマニュアルは、そのほとんどがオリジナルのソースファイルのコメントより
導出されています。

このモジュールは3つのレイヤから構成されます。
@c COMMON
@enumerate
@item
@c EN
Basic converters and applicators, which provides the means to
access and translate SXML tree.
@c JP
SXMLツリーへのアクセスやその変換の手段を提供する基本的なコンバータや
アプリケータ(適用子)。
@c COMMON
@item
@c EN
High-level query language compiler,
which takes abbreviated SXPath and
returns a Scheme function that selects a nodeset
that satisfies the specified path from the given nodeset.
@c JP
省略形のSXPathを取り、与えられたノードセットから指定されたパスを満足する
ノードセットを選択するScheme関数を返す、高レベルなクエリ言語コンパイラ。
@c COMMON
@item
@c EN
Extension libraries, which implements
SXML counterparts to W3C XPath Core Functions Library.
@c JP
W3CのXPathコア関数ライブラリのSXML版を実装する拡張ライブラリ。
@c COMMON
@end enumerate

@c ----------------------------------------------------------------------
@menu
* SXPath basic converters and applicators::
* SXPath query language::
* SXPath extension::
@end menu

@node SXPath basic converters and applicators, SXPath query language, SXML query language, SXML query language
@subsection SXPath basic converters and applicators
@c NODE SXPathの基本的なコンバータとアプリケータ

@c EN
A converter is a function
@c JP
コンバータは、以下を満たす関数です。
@c COMMON
@example
  type Converter = Node|Nodeset -> Nodeset
@end example
@c EN
A converter can also play a role of a predicate: in that case, if a
converter, applied to a node or a nodeset, yields a non-empty
nodeset, the converter-predicate is deemed satisfied. Throughout
this file a nil nodeset is equivalent to @code{#f} in denoting a failure.
@c JP
コンバータは、述語としての役割を担うこともあります。
その場合、コンバータが、ノードやノードセットに適用され、空ではないノードセットを
返す場合、述語としてのコンバータは満足したものとみなされます。
このファイルを通して、nilノードセットは失敗を表す@code{#f}と等価です。
@c COMMON

@defun nodeset? x
@c MOD sxml.sxpath
@c EN
Returns @code{#t} if given object is a nodeset.
@c JP
与えられたオブジェクトがノードセットならば、@code{#t}を返します。
@c COMMON
@end defun

@defun as-nodeset x
@c MOD sxml.sxpath
@c EN
If @var{x} is a nodeset - returns it as is, otherwise wrap it in a list.
@c JP
@var{x}がノードセットならば、それをそのまま返し、そうでなければそれを
リストでラップして返します。
@c COMMON
@end defun

@defun sxml:element? obj
@c MOD sxml.sxpath
@c EN
Predicate which returns @code{#t}
if @var{obj} is SXML element, otherwise returns @code{#f}.
@c JP
@var{obj}がSXMLの要素であれば@code{#t}を返し、そうでなければ@code{#f}を
返す述語です。
@c COMMON
@end defun

@defun ntype-names?? crit
@c MOD sxml.sxpath
@c EN
The function @code{ntype-names??} takes a list of acceptable node names as a
criterion and returns a function, which, when applied to a node,
will return @code{#t} if the node name is present in criterion list
and @code{#f} otherwise.
@c JP
関数@code{ntype-names??}は、判定基準として受け付け可能なノード名のリストを取り、
関数を返します。この関数は、ノードに適用された際、そのノード名が判定基準リストに
含まれていれば@code{#t}を、含まれていなければ@code{#f}を返す関数です。
@c COMMON
@example
 ntype-names?? :: ListOfNames -> Node -> Boolean
@end example
@end defun

@defun ntype?? crit
@c MOD sxml.sxpath
@c EN
The function @code{ntype??} takes a type criterion and returns
a function, which, when applied to a node, will tell if the node satisfies
the test.
@c JP
関数@code{ntype??}は、型に関する判定基準を取り、関数を返します。
この関数は、ノードに適用された際、そのノードがそのテストを満足するかを
返します。
@c COMMON
@example
  ntype?? :: Crit -> Node -> Boolean
@end example

@c EN
The criterion @var{crit} is
one of the following symbols:
@c JP
判定基準@var{crit}は、以下のシンボルのうちの1つです。
@c COMMON
@table @code
@item id
@c EN
tests if the Node has the right name (id)
@c JP
そのノードが正しい名前(id)を持っているかをテストします。
@c COMMON
@item @@
@c EN
tests if the Node is an @var{attributes-list}.
@c JP
そのノードが@var{attributes-list}であるかをテストします。
@c COMMON
@item *
@c EN
tests if the Node is an @var{Element}.
@c JP
そのノードが@var{Element}であるかをテストします。
@c COMMON
@item *text*
@c EN
tests if the Node is a text node.
@c JP
そのノードがテキストノードであるかをテストします。
@c COMMON
@item *data*
@c EN
tests if the Node is a data node
(text, number, boolean, etc., but not pair).
@c JP
そのノードがデータノード(テキスト、数値、真偽値などで、ペアではない)であるか
をテストします。
@c COMMON
@item *PI*
@c EN
tests if the Node is a @code{PI} node.
@c JP
そのノードが@code{PI}ノードであるかをテストします。
@c COMMON
@item *COMMENT*
@c EN
tests if the Node is a @code{COMMENT} node.
@c JP
そのノードが@code{COMMENT}ノードであるかをテストします。
@c COMMON
@item *ENTITY*
@c EN
tests if the Node is a @code{ENTITY} node.
@c JP
そのノードが@code{ENTITY}ノードであるかをテストします。
@c COMMON
@item *any*
@c EN
@code{#t} for any type of Node.
@c JP
どんなタイプのノードに対しても@code{#t}を返します。
@c COMMON
@end table
@end defun

@defun ntype-namespace-id?? ns-id
@c MOD sxml.sxpath
@c EN
This function takes a namespace-id, and returns a predicate
@code{Node -> Boolean}, which is @code{#t}
for nodes with this very namespace-id.
@var{ns-id} is a string.
@code{(ntype-namespace-id?? #f)} will be @code{#t}
for nodes with non-qualified names.
@c JP
この関数は、名前空間IDを取り、述語@code{Node -> Boolean}を
返します。この述語はまさにその名前空間IDを持つノードに対しては
@code{#t}を返します。@var{ns-id}は文字列です。
@code{(ntype-namespace-id?? #f)}は、完全修飾されていない名前を
持つノードに対して@code{#t}を返します。
@c COMMON
@end defun

@defun sxml:invert pred
@c MOD sxml.sxpath
@c EN
This function takes a predicate and returns it inverted .
That is if the given predicate yields @code{#f} or '@code{()} the inverted one
yields the given node (@code{#t}) and vice versa.
@c JP
この関数は、述語を取り、それを反対にして返します。
与えられた述語が@code{#f}や'@code{()}を返す場合、反対にされたものは
与えられたノード(@code{#t})を返します。
@c COMMON
@end defun

@defun node-eq? other
@defunx node-equal? other
@c MOD sxml.sxpath
@c EN
Curried equivalence converter-predicates, i.e.
@c JP
等価な述語としてのコンパータにカリー化します。すなわち、
@c COMMON
@example
  ((node-eq? a) b)    @equiv{} (eq? a b)
  ((node-equal? a) b) @equiv{} (equal? a b)
@end example
@end defun

@defun node-pos n
@c MOD sxml.sxpath

@example
 node-pos:: N -> Nodeset -> Nodeset, or
 node-pos:: N -> Converter
@end example

@c EN
Select the @var{N}'th element of a Nodeset and return as a singular Nodeset;
Return an empty nodeset if the Nth element does not exist.
@code{((node-pos 1) Nodeset)} selects the node at the head of the Nodeset,
if exists;
@code{((node-pos 2) Nodeset)} selects the Node after that, if
exists.
@var{N} can also be a negative number: in that case the node is picked from
the tail of the list.
@code{((node-pos -1) Nodeset)} selects the last node of a non-empty nodeset;
@code{((node-pos -2) Nodeset)} selects the last but one node, if exists.
@c JP
ノードセットの@var{N}番目の要素を選択し、1つの要素を持つノードセットを返します。
N番目の要素が存在しなければ、空のノードセットを返します。
@code{((node-pos 1) Nodeset)}は、ノードセットの先頭ノードがあればそれを選択します。
@code{((node-pos 2) Nodeset)}は、2番目のノードがあればそれを選択します。
@var{N}は負の数でも構いません。その場合、ノードはリストの末尾から数えられます。
@code{((node-pos -1) Nodeset)}は、空ではないノードセットの最後のノードを選択します。
@code{((node-pos -2) Nodeset)}は、最後から2番目のノードがあればそれを選択します。
@c COMMON
@end defun

@defun sxml:filter pred?
@c MOD sxml.sxpath

@example
 filter:: Converter -> Converter
@end example

@c EN
A filter applicator, which introduces a filtering context. The argument
converter is considered a predicate, with either @code{#f}
or nil result meaning failure.
@c JP
フィルタリングを行う、フィルタアプリケータです。
引数のコンバータは、@code{#f}あるいはnilとなることが失敗を意味する述語と
みなされます。
@c COMMON
@end defun

@defun take-until pred?
@c MOD sxml.sxpath

@example
 take-until:: Converter -> Converter, or
 take-until:: Pred -> Node|Nodeset -> Nodeset
@end example

@c EN
Given a converter-predicate and a nodeset, apply the predicate to
each element of the nodeset, until the predicate yields anything but
@code{#f} or nil. Return the elements of the input nodeset that have
been processed
till that moment (that is, which fail the predicate).
@code{take-until} is a variation of the filter above:
@code{take-until} passes
elements of an ordered input set till (but not including) the first
element that satisfies the predicate.
The nodeset returned by @code{((take-until (not pred)) nset)} is a subset --
to be more precise, a prefix -- of the nodeset returned by
@code{((filter pred) nset)}.
@c JP
述語としてのコンバータとノードセットが与えられると、
ノードセットの各要素に述語を適用し、
述語が@code{#f}あるいはnil以外を返すと、
(その述語が失敗した)その時点までに処理された要素を返します。
@code{take-until}は、上のフィルタのバリエーションの1つです。
@code{take-until}は、その述語を満足する最初の要素(それ自体は含まない)まで、
順序付けられた入力のセットの要素をパスします。
@code{((take-until (not pred)) nset)}により返されるノードセットは、
@code{((filter pred) nset)}により返されるノードセットのサブセット
-- 具体的には接頭辞 --になります。
@c COMMON
@end defun

@defun take-after pred?
@c MOD sxml.sxpath

@example
take-after:: Converter -> Converter, or
take-after:: Pred -> Node|Nodeset -> Nodeset
@end example

@c EN
Given a converter-predicate and a nodeset, apply the predicate to
each element of the nodeset, until the predicate yields anything but
@code{#f} or
nil. Return the elements of the input nodeset that have not been processed:
that is, return the elements of the input nodeset that follow the first
element that satisfied the predicate.
@code{take-after} along with @code{take-until}
partition an input nodeset into three
parts: the first element that satisfies a predicate, all preceding
elements and all following elements.
@c JP
述語としてのコンバータとノードセットを与えると、
述語をノードセットの各要素に適用し、
述語が@code{#f}かnil以外を返すと、
まだ述語が適用されていない要素を返します。
つまり、述語を満足する最初の要素の後に続く要素を返します。
@code{take-after}と@code{take-until}を一緒に使うと、
入力のノードセットを3つのパート:
述語を満足する最初の要素、その要素の前の部分、その要素の後の部分に
分けます。
@c COMMON
@end defun

@defun map-union proc lst
@c MOD sxml.sxpath
@c EN
Apply proc to each element of lst and return the list of results.
If proc returns a nodeset, splice it into the result.

From another point of view,
@code{map-union} is a function Converter->Converter,
which places an argument-converter in a joining context.
@c JP
procをlstの各要素に適用し、結果のリストを返します。
procがノードセットを返す場合、それを結果につなぎ合わせます。

別の観点から見ると、@code{map-union}はConverter->Converter関数で、
結合を行いたいコンテキストでの引数としてのコンバータに
位置します。
@c COMMON
@end defun

@defun node-reverse node-or-nodeset
@c MOD sxml.sxpath

@example
node-reverse :: Converter, or
node-reverse:: Node|Nodeset -> Nodeset
@end example

@c EN
Reverses the order of nodes in the nodeset.
This basic converter is needed to implement a reverse document order
(see the XPath Recommendation).
@c JP
ノードセットでのノードの順番を逆順にします。
この基本的なコンバータは、逆順のドキュメントオーダーを実装するために
必要です。(XPath勧告を参照して下さい。)
@c COMMON
@end defun

@defun node-trace title
@c MOD sxml.sxpath

@example
 node-trace:: String -> Converter
@end example

@c EN
@code{(node-trace title)} is an identity converter. In addition it prints out
a node or nodeset it is applied to, prefixed with the 'title'.
This converter is very useful for debugging.
@c JP
@code{(node-trace title)}は、それ自身を返すコンバータです。
また、自身が適用されるノードやノードセットを、'title'という
プリフィックスを付けてプリントします。
このコンバータは、デバッグの際にとても便利です。
@c COMMON
@end defun

@c EN
What follow are Converter combinators,
higher-order functions that transmogrify a converter
or glue a sequence of converters into a single, non-trivial
converter. The goal is to arrive at converters that correspond to
XPath location paths.

From a different point of view, a combinator is a fixed, named
@emph{pattern} of applying converters. Given below is a complete set of
such patterns that together implement XPath location path
specification. As it turns out, all these combinators can be built
from a small number of basic blocks: regular functional composition,
map-union and filter applicators, and the nodeset union.
@c JP
コンバータの組み合わせに続くものは、コンバータを一変させる、
あるいはコンバータのシーケンスを1つの強力なコンバータにつなぎ合わせる
高階関数です。そのゴールは、XPathのロケーションパスに対応する
コンバータとなることです。

別の観点から見ると、コンバータは、コンバータ群の適用の固定され
名前の付いた@emph{パターン}とみなせます。
以下に挙げるのは、XPathのロケーションパスの仕様を実装する
そのようなパターンの完全なセットです。
結局のところ、これら全てのコンビネータはいくつかの基本的なブロック、
通常の関数的なコンポジション、map-unionとfilterアプリケータ、
ノードセットユニオンなどから構築することができます
@c COMMON

@defun select-kids test-pred?
@c MOD sxml.sxpath

@example
select-kids:: Pred -> Node -> Nodeset
@end example
@c EN
Given a Node, return an (ordered) subset its children that satisfy
the Pred (a converter, actually).
@c JP
ノードを与えると、述語(実際はコンバータ)を満足するその子要素の
(順序付けられた)サブセットを返します。
@c COMMON

@example
select-kids:: Pred -> Nodeset -> Nodeset
@end example
@c EN
The same as above, but select among children of all the nodes in
the Nodeset.
@c JP
上と同じですが、ノードセットの全てのノードの子要素から選択します。
@c COMMON
@end defun

@defun node-self pred
@c MOD sxml.sxpath

@example
 node-self:: Pred -> Node -> Nodeset, or
 node-self:: Converter -> Converter
@end example

@c EN
Similar to select-kids but apply to the Node itself rather
than to its children. The resulting Nodeset will contain either one
component, or will be empty (if the Node failed the Pred).
@c JP
select-kidsに似ていますが、自身をその子要素に適用するのでは
なく、ノードそれ自身に適用します。
結果のノードセットは、1つのコンポーネントを含むか、
空(ノードが述語を満足しない場合)になります。
@c COMMON
@end defun

@defun node-join . selectors
@c MOD sxml.sxpath

@example
 node-join:: [LocPath] -> Node|Nodeset -> Nodeset, or
 node-join:: [Converter] -> Converter
@end example

@c EN
join the sequence of location steps or paths as described
in the title comments above.
@c JP
上のタイトルコメントで説明されるようなロケーションステップ
あるいはロケーションパスのシーケンスをつなぎ合わせます。
@c COMMON
@end defun

@defun node-reduce . converters
@c MOD sxml.sxpath

@example
 node-reduce:: [LocPath] -> Node|Nodeset -> Nodeset, or
 node-reduce:: [Converter] -> Converter
@end example

@c EN
A regular functional composition of converters.
From a different point of view,
@code{((apply node-reduce converters) nodeset)}
is equivalent to
@code{(foldl apply nodeset converters)}
i.e., folding, or reducing, a list of converters with the nodeset
as a seed.
@c JP
コンバータの通常の関数的なコンポジションです。
見方を変えると、@code{((apply node-reduce converters) nodeset)}は
@code{(foldl apply nodeset converters)}と等価です。
すなわち、コンバータのリストをノードセットをseedとして畳み込みや分解
を行うようなものです。
@c COMMON
@end defun

@defun node-or . converters
@c MOD sxml.sxpath

@example
 node-or:: [Converter] -> Converter
@end example

@c EN
This combinator applies all converters to a given node and
produces the union of their results.
This combinator corresponds to a union, '@code{|}' operation for XPath
location paths.
@c JP
このコンビネータは、全てのコンバータを与えられたノードに適用し、
それらの結果のユニオンを作ります。
このコンビネータは、XPathのロケーションパスでの'@code{|}'オペレーション
であるユニオンに対応します。
@c COMMON
@end defun

@defun node-closure test-pred?
@c MOD sxml.sxpath

@example
 node-closure:: Converter -> Converter
@end example

@c EN
Select all @emph{descendants} of a node that satisfy a converter-predicate.
This combinator is similar to @code{select-kids} but applies to
grand... children as well.
This combinator implements the "@code{descendant::}" XPath axis.
Conceptually, this combinator can be expressed as
@c JP
述語としてのコンバータを満足するノードの全ての@emph{子孫}を選択します。
このコンビネータは@code{select-kids}に似ていますが、孫要素やその
子要素達にも適用を行います。
このコンビネータは、XPathの軸である``@code{descendant::}''を実装します。
概念的には、このコンビネータは以下のように表現することができます。
@c COMMON
@example
 (define (node-closure f)
      (node-or
        (select-kids f)
	 (node-reduce (select-kids (ntype?? '*)) (node-closure f))))
@end example

@c EN
This definition, as written, looks somewhat like a fixpoint, and it
will run forever.  It is obvious however that sooner or later
@code{(select-kids (ntype?? '*))} will return an empty nodeset. At
this point further iterations will no longer affect the result and
can be stopped.
@c JP
この定義は、字面の通り、フィックスポイントのような何かで、
永久に実行し続けます。しかし、いつかは@code{(select-kids (ntype?? '*))}
が空のノードセットを返すことは明白です。その時点では、以降の
イテレーションはその結果に影響を及ぼさず停止されることができます。
@c COMMON
@end defun

@c ----------------------------------------------------------------------
@node SXPath query language, SXPath extension, SXPath basic converters and applicators, SXML query language
@subsection SXPath query language
@c NODE SXPathクエリ言語

@defun sxpath abbrpath . ns-binding
@c MOD sxml.sxpath
Evaluates an abbreviated SXPath. Returns a procedure that when applied
on a node or nodeset will return a nodeset matching the given path.

@example
 sxpath:: AbbrPath -> Converter, or
 sxpath:: AbbrPath -> Node|Nodeset -> Nodeset
@end example

@c COMMON
@var{AbbrPath} is a list or a string. If it is a list, it is
translated to the full SXPath according to the following rewriting
rules. More informal explanation follows shortly. If it is a string,
it is an XPath query.

Note that these are abstract rules to show how it works, and not the
running code examples. The nonterminals @i{sxpath1} and @i{sxpathr}
don't exist as APIs. The term @i{txpath} is an internal function that
interprets XPath query given as a string.

@c COMMON
@example
 (sxpath '()) -> (node-join)
 (sxpath '(path-component ...)) ->
                (node-join (@i{sxpath1} path-component) (sxpath '(...)))
 (@i{sxpath1} '//) -> (node-or
                     (node-self (ntype?? '*any*))
                     (node-closure (ntype?? '*any*)))
 (@i{sxpath1} '(equal? x)) -> (select-kids (node-equal? x))
 (@i{sxpath1} '(eq? x))    -> (select-kids (node-eq? x))
 (@i{sxpath1} '(or@@ ...))  -> (select-kids (ntype-names??
                                          (cdr '(or@@ ...))))
 (@i{sxpath1} '(not@@ ...)) -> (select-kids (sxml:invert
                                         (ntype-names??
                                          (cdr '(not@@ ...)))))
 (@i{sxpath1} '(ns-id:* x)) -> (select-kids
                                      (ntype-namespace-id?? x))
 (@i{sxpath1} ?symbol)     -> (select-kids (ntype?? ?symbol))
 (@i{sxpath1} ?string)     -> (@i{txpath} ?string)
 (@i{sxpath1} procedure)   -> procedure
 (@i{sxpath1} '(?symbol ...)) -> (@i{sxpath1} '((?symbol) ...))
 (@i{sxpath1} '(path reducer ...)) ->
                (node-reduce (sxpath path) (@i{sxpathr} reducer) ...)
 (@i{sxpathr} number)      -> (node-pos number)
 (@i{sxpathr} path-filter) -> (filter (sxpath path-filter))
@end example

@c COMMON

SXPath in its simplest form is a list of path components. The result
procedure will follow the same path and return the matching node
list. For example @code{(one two three)} will find element @code{one}
then @code{two} inside it and @code{three} inside element
@code{two}. The equivalent XPath would be @code{one/two/three}.

There are a few special path components (see @code{ntype??} for the
complete list):

@table @code
@item *
matches an element node.
@item //
matches any one or many consecutive path components.
@item *text*
matches a text node (@code{text()} in XPath).
@item *data*
matches any data node (e.g. text, number, boolean, etc.,
but not pair).
@item @@
selects the attribute list node.
@end table

A path component could be a list in one of these forms:

@table @code
@item (equal? x)
matches if the node under examination matches @var{x} using
@code{node-equal?}
@item (eq? x)
matches if the node under examination matches @var{x} using
@code{node-eq?}
@item (or@@ ...)
matches if the element name is one of the specified symbols.
@item (not@@ ...)
matches if the element name is not one of the specified symbols.
@item (ns-id:* x)
matches the node if it's with namespace @var{x}
@item (<path> n)
matches the @var{n}-th node matching same path component. @var{n}
starts from 1. Negative numbers start from the end of the node list
backward. This is @code{path[n]} syntax in XPath.
@item (<path> (<predicate>...))
matches a path component @var{path} and @code{(sxpath (<predicate>...))}
on those nodes are not empty. This is @code{path[predicate...]} syntax
in XPath.
@end table

If the path component is a string, it is interpreted as an XPath query
string.

If the path component is a procedure, the procedure takes three
arguments: the nodeset being examined, the root node and the variable
bindings.

The root node is usually the entire sxml being applied. However if you
apply the result sxpath procedure with two arguments, root-node will
be the second argument.

When applied with three arguments, the variable bindings are the third
one. This lets you pass arguments to the procedure.

@c COMMON

@smalllisp
;; select all <book> elements whose style attribute value is equal to
;; the <bookstore> element's specialty attribute value.
(sxpath "//book[/bookstore/@@specialty=@@style]")
;; a similar query but this time make sure specialty of _all_
;; bookstores is matched
(let ([match-specialty
       (lambda (node root var-binding)
         (let ([style (car ((sxpath '(@@ style *text*)) node))]
               [all-specialty ((sxpath '(bookstore @@ specialty *text*)) node)])
           (fold (lambda (specialty last-result)
                   (and last-result (string=? style specialty)))
                        #t
                        all-specialty)))])
  (sxpath `(// (book (,match-specialty)))))

;; select all <bookstore> elements that are inside top-level <book>
;; element
(sxpath '(book bookstore))
;; select all <bookstore> elements from anywhere
(sxpath '(// bookstore))
;; select attribute "name" in the top-level <book> element
(sxpath '(book @@ name))
;; select all <bookstore> and <bookshop> elements that are inside
;; top-level <book> element
(sxpath '(book (or@@ bookstore bookshop)))
;; select all elements except <movie> that are inside top-level <book>
;; element
(sxpath '(book (not@@ movie @@)))
;; select the attribute "name" of the second <bookstore> element
(sxpath '(book (bookstore 2) @@ name))
;; select the attribute "name" of all <bookstore> elements that has
;; attribute "recommended"
(sxpath '(book (bookstore (@@ recommended)) @@ name))
;; select the attribute "name" of all <bookstore> elements whose
;; "rating" attribute is 3
(sxpath '(book (bookstore (@@ rating (eq? 3))) @@ name))
;; select the attribute "rating" whose value is greater than 3 from
;; all <bookstore> elements
(let ([greater (lambda (nodeset root-node var-binding)
                 (filter (lambda (node)
                           (> (string->number (sxml:string-value node))
                              3))
                         nodeset))])
  (sxpath `(book bookstore @@ rating ,greater)))
@end smalllisp
@end defun

@c EN
Some wrapper functions around @code{sxpath}:
@c JP
@code{sxpath}には、いくつかのラッパ関数があります。
@c COMMON

@defun if-sxpath path
@c MOD sxml.sxpath
@c EN
@code{sxpath} always returns a list, which is @code{#t} in Scheme.
@code{if-sxpath} returns @code{#f} instead of empty list.
@c JP
@code{sxpath}は、常にリストを返し、それはSchemeでは@code{#t}となります。
@code{if-sxpath}は、空リストの代わりに@code{#f}を返します。
@c COMMON
@end defun

@defun if-car-sxpath path
@c MOD sxml.sxpath
@c EN
Returns first node found, if any.
Otherwise returns @code{#f}.
@c JP
もし存在すれば、最初に見つかったノードを返します。
そうでなければ、@code{#f}を返します。
@c COMMON
@end defun

@defun car-sxpath path
@c MOD sxml.sxpath
@c EN
Returns first node found, if any.
Otherwise returns empty list.
@c JP
もし存在すれば、最初に見つかったノードを返します。
そうでなければ、空リストを返します。
@c COMMON
@end defun

@defun sxml:id-alist node . lpaths
@c MOD sxml.sxpath
@c EN
Built an index as a list of
@code{(@var{ID_value} . @var{element})} pairs for given
node.  @var{lpaths} are location paths for attributes of type ID.
@c JP
与えられたノードについて、@code{(@var{ID_value} . @var{element})}の
ペアのリストをインデックスとして構築します。
@var{lpaths}は、タイプIDの属性のロケーションパスです。
@c COMMON
@end defun

@c ----------------------------------------------------------------------
@node SXPath extension,  , SXPath query language, SXML query language
@subsection SXPath extension
@c NODE SXPathの拡張

@c EN
SXML counterparts to W3C XPath Core Functions Library.
@c JP
W3CのXPathコア関数ライブラリのSXML版です。
@c COMMON

@defun sxml:string object
@c MOD sxml.sxpath
@c EN
The counterpart to XPath @code{string} function (section 4.2 XPath Rec.)
Converts a given object to a string.
NOTE:
@c JP
XPathの@code{string}関数(XPath勧告のセクション4.2)に対応するものです。
与えられたオブジェクトを文字列に変換します。
注意:
@c COMMON
@enumerate
@item
@c EN
When converting a nodeset - a document order is not preserved
@c JP
ノードセットを変換する時は、ドキュメントオーダーは保持されません。
@c COMMON
@item
@c EN
@var{number->string} function returns the result in a form which is slightly
different from XPath Rec. specification
@c JP
@var{number->string}関数は、その結果をXPath勧告の仕様とは少し違った
フォームで返します。
@c COMMON
@end enumerate
@end defun

@defun sxml:boolean object
@c MOD sxml.sxpath
@c EN
The counterpart to XPath @code{boolean} function (section 4.3 XPath Rec.)
Converts its argument to a boolean.
@c JP
XPathの@code{boolean}関数(XPath勧告のセクション4.3)に対応するものです。
引数を真偽値に変換します。
@c COMMON
@end defun

@defun sxml:number obj
@c MOD sxml.sxpath
@c EN
The counterpart to XPath @code{number} function (section 4.4 XPath Rec.)
Converts its argument to a number
NOTE:
@c JP
XPathの@code{number}関数(XPath勧告のセクション4.4)に対応するものです。
引数を数値に変換します。
注意:
@c COMMON
@enumerate
@item
@c EN
The argument is not optional (yet?).
@c JP
引数は(まだ?)オプションではありません。
@c COMMON
@item
@c EN
@code{string->number} conversion is not IEEE 754 round-to-nearest.
@c JP
@code{string->number}の変換は、IEEE 754の四捨五入ではありません。
@c COMMON
@item
@c EN
NaN is represented as 0.
@c JP
NaNは、0として表現されます。
@c COMMON
@end enumerate
@end defun

@defun sxml:string-value node
@c MOD sxml.sxpath
@c EN
Returns a string value for a given node in accordance to
XPath Rec. 5.1 - 5.7
@c JP
XPath勧告のセクション5.1 - 5.7にしたがって、与えられたノードの
文字列値を返します。
@c COMMON
@end defun


@defun sxml:node? node
@c MOD sxml.sxpath
@c EN
According to XPath specification 2.3, this test is true for any
XPath node.
For SXML auxiliary lists and lists of attributes has to be excluded.
@c JP
XPathの仕様2.3にしたがい、このテストはいかなるXPathノードに
対しても真を返します。
SXMLの補助的なリストや属性のリストは除外されます。
@c COMMON
@end defun

@defun sxml:attr-list obj
@c MOD sxml.sxpath
@c EN
Returns the list of attributes for a given SXML node.
Empty list is returned if the given node is not an element,
or if it has no list of attributes
@c JP
与えられたSXMLノードの属性のリストを返します。
与えられたノードが要素ではないか、属性のリストを持っていない場合は、
空リストが返されます。
@c COMMON
@end defun

@defun sxml:id id-index
@c MOD sxml.sxpath
@c EN
Select SXML element by its unique IDs.  (XPath Rec. 4.1)
Returns a converter that takes @var{object},
which is a nodeset or a datatype which can be converted to a string by means
of a '@code{string}' function.

@var{id-index} is @code{( (id-value . element) (id-value . element) ... )}.

This index is used for selection of an element by its unique ID.
@c JP
SXML要素を、そのユニークなIDによって選択します(XPath勧告 4.1)。
@var{object}を引数に取るコンバータを返します。
この@var{object}は、ノードセットか、'@code{string}'関数により
文字列に変換できるデータタイプです。

@var{id-index}は、@code{( (id-value . element) (id-value . element) ... )}です。

このインデックスは、要素をそのユニークなIDによって選択するために使われます。
@c COMMON
@end defun

@c EN
Comparators for XPath objects:
@c JP
XPathオブジェクトの比較子:
@c COMMON

@defun sxml:equality-cmp bool-op number-op string-op
@c MOD sxml.sxpath
@c EN
A helper for XPath equality operations: @code{=} , @code{!=}
@var{bool-op}, @var{number-op} and
@var{'string-op} are comparison operations for
a pair of booleans,  numbers and strings respectively.
@c JP
XPathの等値比較: @code{=}、@code{!=}のためのヘルパです。
@var{bool-op}、@var{number-op}、@var{'string-op}はそれぞれ、
真偽値、数値、文字列のペアのための比較子です。
@c COMMON
@end defun

@defun sxml:equal? a b
@defunx sxml:not-equal? a b
@c MOD sxml.sxpath
@c EN
Counterparts of XPath equality operations: @code{=} , @code{!=},
using default equality tests.
@c JP
XPathの等値比較: @code{=}、@code{!=}に対応するもので、
デフォルトの等値テストを使います。
@c COMMON
@end defun

@defun sxml:relational-cmp op
@c MOD sxml.sxpath
@c EN
Creates a relational operation ( @code{<} , @code{>} , @code{<=} , @code{>=} )
for two XPath objects.
@code{op} is comparison procedure: @code{<} , @code{>} , @code{<=} or @code{>=}.
@c JP
2つのXPathオブジェクトの関係比較( @code{<}、@code{>}、@code{<=}、@code{>=} )
を作ります。
@code{op}は、比較を行う手続き: @code{<}、@code{>}、@code{<=}、@code{>=}です。
@c COMMON
@end defun

@c EN
XPath axises.
An order in resulting nodeset is preserved.
@c JP
XPathの軸。
結果のノードセットにおける順序は維持されます。
@c COMMON

@defun sxml:attribute test-pred?
@c MOD sxml.sxpath
@c EN
Attribute axis.
@c JP
属性の軸です。
@c COMMON
@end defun

@defun sxml:child test-pred?
@c MOD sxml.sxpath
@c EN
Child axis.
This function is similar to '@code{select-kids}', but it returns an empty
child-list for PI, Comment and Entity nodes.
@c JP
子要素の軸です。
この関数は、'@code{select-kids}'に似ていますが、処理命令やコメント、
実体ノードについては、空の子リストを返します。
@c COMMON
@end defun

@defun sxml:parent test-pred?
@c MOD sxml.sxpath
@c EN
Parent axis.

Given a predicate, it returns a function
@code{RootNode -> Converter}
which yields a
@code{ node -> parent }
converter then applied to a rootnode.

Thus, such a converter may be constructed using
@code{ ((sxml:parent test-pred) rootnode) }
and returns a parent of a node it is applied to.
If applied to a nodeset, it returns the
list of parents of nodes in the nodeset. The rootnode does not have
to be the root node of the whole SXML tree -- it may be a root node
of a branch of interest.
The @code{parent::} axis can be used with any SXML node.
@c JP
親の軸です。

述語を与えると、@code{RootNode -> Converter}関数を返します。
この関数は、rootnodeに適用されると、@code{node -> parent}と
なります。

このようなコンバータは、@code{ ((sxml:parent test-pred) rootnode) }
を使って構築され、それが適用されたノードの親を帰します。
ノードセットに適用された場合、そのノードセットにあるノードの
親のリストを返します。
rootnodeはSXMLツリー全体のルートノードである必要はありません。
興味の対象となるブランチ(枝)のルートノードでも構いません。
@code{parent::}軸は、どんなSXMLノードにも使えます。
@c COMMON
@end defun

@defun sxml:ancestor test-pred?
@c MOD sxml.sxpath
@c EN
Ancestor axis
@c JP
祖先の軸です。
@c COMMON
@end defun

@defun sxml:ancestor-or-self test-pred?
@c MOD sxml.sxpath
@c EN
Ancestor-or-self axis
@c JP
祖先と自分の軸です。
@c COMMON
@end defun

@defun sxml:descendant test-pred?
@c MOD sxml.sxpath
@c EN
Descendant axis
@c JP
子孫の軸です。
@c COMMON
@end defun

@defun sxml:descendant-or-self test-pred?
@c MOD sxml.sxpath
@c EN
Descendant-or-self axis
@c JP
子孫と自分の軸です。
@c COMMON
@end defun

@defun sxml:following test-pred?
@c MOD sxml.sxpath
@c EN
Following axis
@c JP
後続するものの軸です。
@c COMMON
@end defun

@defun sxml:following-sibling test-pred?
@c MOD sxml.sxpath
@c EN
Following-sibling axis
@c JP
後続する兄弟の軸です。
@c COMMON
@end defun

@defun sxml:namespace test-pred?
@c MOD sxml.sxpath
@c EN
Namespace axis
@c JP
名前空間の軸です。
@c COMMON
@end defun

@defun sxml:preceding test-pred?
@c MOD sxml.sxpath
@c EN
Preceding axis
@c JP
先行するものの軸です。
@c COMMON
@end defun

@defun sxml:preceding-sibling test-pred?
@c MOD sxml.sxpath
@c EN
Preceding-sibling axis
@c JP
先行する兄弟の軸です。
@c COMMON
@end defun

@c EN
Popular shortcuts:
@c JP
ポピュラーなショートカット:
@c COMMON

@defun sxml:child-nodes nodeset
@c MOD sxml.sxpath
@example
((sxml:child sxml:node?) nodeset)
@end example
@end defun

@defun sxml:child-elements nodeset
@c MOD sxml.sxpath
@example
((select-kids sxml:element?) nodeset)
@end example
@end defun


@c ----------------------------------------------------------------------
@node Manipulating SXML structure, Serializing XML and HTML from SXML, SXML query language, Library modules - Utilities
@section @code{sxml.tools} - Manipulating SXML structure
@c NODE SXML構造を操作する, @code{sxml.tools} - SXML構造を操作する

@deftp {Module} sxml.tools
@mdindex sxml.tools

@c EN
This module is a port of Kirill Lisofsky's sxml-tools,
a collection of convenient procedures that work on
SXML structure.
The current version is derived from sxml-tools CVS revision 3.13.

The manual entry is mainly derived from the comments in the original
source code.
@c JP
現在のバージョンは、sxml-toolsのCVSのリビジョン3.13から導出されています。

マニュアルのエントリは主に、オリジナルのソースコードから導出されています。
@c COMMON
@end deftp

@c ----------------------------------------------------------------------
@menu
* SXML predicates::
* SXML accessors::
* SXML modifiers::
* SXPath auxiliary utilities::
* SXML to markup conversion::
@end menu

@c ----------------------------------------------------------------------
@node SXML predicates, SXML accessors, Manipulating SXML structure, Manipulating SXML structure
@subsection SXML predicates
@c NODE SXMLの述語

@defun sxml:empty-element? obj
@c MOD sxml.tools
@c EN
A predicate which returns @code{#t} if given element @var{obj} is empty.
Empty element has no nested elements, text nodes, @code{PI}s,
Comments or entities
but it may contain attributes or namespace-id.
It is a SXML counterpart of XML @code{empty-element}.
@c JP
与えられた要素@var{obj}が空なら@code{#t}を返す述語です。
空要素は、ネストした要素、テキストノード、@code{PI}、コメントや実体を
持ちませんが、属性や名前空間IDは持つかもしれません。
それは、XMLの@code{empty-element}のSXML版です。
@c COMMON
@end defun

@defun sxml:shallow-normalized? obj
@c MOD sxml.tools
@c EN
Returns @code{#t} if the given @var{obj} is shallow-normalized SXML element.
The element itself has to be normalized but its nested elements are not tested.
@c JP
与えられた@var{obj}が浅く正規化されたSXML要素であれば@code{#t}を返します。
要素それ自体は正規化されていなければなりませんが、ネストした要素は
テストされません。
@c COMMON
@end defun

@defun sxml:normalized? obj
@c MOD sxml.tools
@c EN
Returns @code{#t} if the given @var{obj} is normalized SXML element.
The element itself and all its nested elements have to be normalised.
@c JP
与えられた@var{obj}が正規化されたSXML要素であれば@code{#t}を返します。
要素それ自体とその全てのネストした要素が正規化されていなければなりません。
@c COMMON
@end defun

@defun sxml:shallow-minimized? obj
@c MOD sxml.tools
@c EN
Returns @code{#t} if the given @var{obj} is shallow-minimized SXML element.
The element itself has to be minimised but its nested elements are not tested.
@c JP
与えられた@var{obj}が浅く最小化されたSXML要素であれば@code{#t}を返します。
要素それ自体は最小化されていなければなりませんが、そのネストした要素は
テストされません。
@c COMMON
@end defun

@defun sxml:minimized? obj
@c MOD sxml.tools
@c EN
Returns @code{#t} if the given @var{obj} is minimized SXML element.
The element itself and all its nested elements have to be minimised.
@c JP
与えられた@var{obj}が最小化されたSXML要素であれば@code{#t}が返されます。
要素それ自体とその全てのネストした要素が最小化されていなければなりません。
@c COMMON
@end defun

@c ----------------------------------------------------------------------
@node SXML accessors, SXML modifiers, SXML predicates, Manipulating SXML structure
@subsection SXML accessors
@c NODE SXMLへのアクセッサ

@defun sxml:name obj
@c MOD sxml.tools
@c EN
Returns a name of a given SXML node.
It's just an alias of @code{car}, but introduced for the sake of encapsulation.
@c JP
与えられたSXMLノードの名前を返します。
これは単に@code{car}のエイリアスに過ぎませんが、カプセル化のために導入されています。
@c COMMON
@end defun

@defun sxml:element-name obj
@c MOD sxml.tools
@c EN
A version of @code{sxml:name}, which returns @code{#f}
if the given @var{obj} is not a SXML element.
Otherwise returns its name.
@c JP
@code{sxml:name}の、与えられた@var{obj}がSXML要素ではない場合は@code{#f}を返す
バージョンです。@var{obj}がSXML要素であれば、その名前を返します。
@c COMMON
@end defun

@defun sxml:node-name obj
@c MOD sxml.tools
@c EN
Safe version of @code{sxml:name}, which returns @code{#f}
if the given @var{obj} is not a SXML node.
Otherwise returns its name.
@c JP
@code{sxml:name}の、与えられた@var{obj}がSXMLノードでない場合は@code{#f}を返す、
安全なバージョンです。@var{obj}がSXMLノードであれば、その名前を返します。
@c COMMON
@end defun

@defun sxml:ncname obj
@c MOD sxml.tools
@c EN
Returns Local Part of Qualified Name (Namespaces in XML production [6])
for given obj, which is "@code{:}"-separated suffix of its Qualified Name.
If a name of a node given is @code{NCName} (Namespaces in XML production [4]),
then it is returned as is.
Please note that while SXML name is a symbol this function returns a string.
@c JP
与えられたobjの完全修飾名(Namespaces in XML production [6])のローカルパート、
つまりその完全修飾名を``@code{:}''で分割した後ろの部分を返します。
与えられたノードの名前が@code{NCName}(Namespaces in XML production [4])であれば、
それをそのまま返します。
SXMLの名前はシンボルですが、この関数は文字列を返すことに注意して下さい。
@c COMMON
@end defun

@defun sxml:name->ns-id sxml-name
@c MOD sxml.tools
@c EN
Returns namespace-id part of given name, or @code{#f} if it's LocalName
@c JP
与えられた名前の名前空間ID部分を返します。与えられた名前がLocalNameの
場合は@code{#f}を返します。
@c COMMON
@end defun

@defun sxml:content obj
@c MOD sxml.tools
@c EN
Returns the content of given SXML element or nodeset (just text and element
nodes) representing it as a list of strings and nested elements in document
order.  This list is empty if @var{obj} is empty element or empty list.
@c JP
与えられたSXML要素かノードセット(テキストノードと要素ノードのみ)の内容を、
ドキュメントオーダーにしたがった文字列のリストとネストした要素として
返します。このリストは、@var{obj}が空要素や空リストの場合は空です。
@c COMMON
@end defun

@defun sxml:content-raw obj
@c MOD sxml.tools
@c EN
Returns all the content of normalized SXML element except
@var{attr-list} and @var{aux-list}.
Thus it includes @code{PI}, @code{COMMENT} and @code{ENTITY}
nodes as well as @code{TEXT} and @code{ELEMENT} nodes
returned by @code{sxml:content}.
Returns  a list of nodes in document order or empty list if @var{obj} is empty
element or empty list.
This function is faster than @code{sxml:content}.
@c JP
正規化されたSXML要素の全ての内容を、@var{attr-list}と@var{aux-list}を除いて
返します。
したがってそれは、@code{PI}、@code{COMMENT}、@code{ENTITY}
ノードとともに、@code{sxml:content}によって返される@code{TEXT}や@code{ELEMENT}も含みます。
戻り値は、ドキュメントオーダーにしたがったノードのリストか、
@var{obj}が空要素や空リストの場合は空リストになります。
この関数は、@code{sxml:content}よりも高速です。
@c COMMON
@end defun

@c EN
In SXML normal form, an element is represented by a list as this:
@c JP
SXMLの通常のフォームでは、1つの要素は次のようなリストで表現されます。
@c COMMON
@example
  (@var{name} @var{attr-list} @var{aux-list} @var{content} @dots{})
@end example
@c EN
where @var{attr-list} is a list beginning with @code{@@},
and @var{aux-list} is a list beginning with @code{@@@@}.

In the minimized form,
@var{Aux-list} can be omitted when it is empty.
@var{Attr-list} can be omitted when it is empty @emph{and}
@var{aux-list} is absent.

The following procedures extract @var{attr-list} and @var{aux-list}.
@c JP
@var{attr-list}は@code{@@}で始まるリストで、@var{aux-list}は@code{@@@@}で
始まるリストです。

最小化されたフォームでは、@var{aux-list}は空であれば省略できます。
@var{attr-list}は、それが空で@emph{かつ}@var{aux-list}がなければ省略できます。

以下の手続きは、@var{attr-list}と@var{aux-list}を抽出するものです。
@c COMMON

@defun sxml:attr-list-node obj
@c MOD sxml.tools
@c EN
Returns @var{attr-list} for a given @var{obj},
or @code{#f} if it is absent
@c JP
与えられた@var{obj}の@var{attr-list}を返します。
@var{attr-list}が存在しなければ@code{#f}を返します。
@c COMMON
@end defun

@defun sxml:attr-as-list obj
@c MOD sxml.tools
@c EN
Returns @var{attr-list} wrapped in list,
or '@code{((@@))} if it is absent and @var{aux-list} is present,
or '@code{()} if both lists are absent.
@c JP
@var{attr-list}をリストにラップして返します。
@var{attr-list}が存在せず@var{aun-list}がある場合は'@code{((@@))}を返します。
両方とも存在しない場合には'@code{()}を返します。
@c COMMON
@end defun

@defun sxml:aux-list-node obj
@c MOD sxml.tools
@c EN
Returns @var{aux-list} for a given @var{obj},
or @code{#f} if it is absent.
@c JP
与えられた@var{obj}の@var{aux-list}を返します。
@var{attr-list}が存在しなければ@code{#f}を返します。
@c COMMON
@end defun

@defun sxml:aux-as-list obj
@c MOD sxml.tools
@c EN
Returns @var{aux-list} wrapped in list,
or '@code{()} if it is absent.
@c JP
@var{aux-list}をリストにラップして返します。
@var{aux-list}が存在しなければ'@code{()}を返します。
@c COMMON
@end defun

@defun sxml:attr-list-u obj
@c MOD sxml.tools
@c EN
Returns the list of attributes for given element or nodeset.
Analog of @code{((sxpath '(@@ *)) @var{obj})}.
Empty list is returned if there is no list of attributes.

The @code{-u} suffix indicates it can be used for non-normalized
SXML node.  ('u' stands for 'universal').
@c JP
与えられた要素かノードセットの属性のリストを返します。
@code{((sxpath '(@@ *)) @var{obj})}と類似です。
属性のリストがない場合は空リストが返されます。
@c COMMON
@end defun

@defun sxml:aux-list obj
@c MOD sxml.tools
@c EN
Returns the list of auxiliary nodes for given element or nodeset.
Analog of @code{((sxpath '(@@@@ *)) @var{obj})}.
Empty list is returned if a list of auxiliary nodes is absent.
@c JP
与えられた要素かノードセットの補助ノードのリストを返します。
@code{((sxpath '(@@@@ *)) @var{obj})}と類似です。
補助ノードのリストがない場合は空リストが返されます。
@c COMMON
@end defun

@defun sxml:aux-list-u obj
@c MOD sxml.tools
@c EN
Returns the list of auxiliary nodes for given element or nodeset.
Analog of @code{((sxpath '(@@@@ *)) @var{obj})}.
Empty list is returned if a list of auxiliary nodes is absent.

The @code{-u} suffix indicates it can be used for non-normalized
SXML node.  ('u' stands for 'universal').
@c JP
与えられた要素かノードセットの補助ノードのリストを返します。
@code{((sxpath '(@@@@ *)) @var{obj})}と類似です。
補助ノードのリストがない場合は空リストが返されます。

@code{-u}が付くものは、正規化されていないSXMLノードに対しても
使えるということを示しています。('u'は'universal'の意味です。)
@c COMMON
@end defun

@defun sxml:aux-node obj aux-name
@c MOD sxml.tools
@c EN
Return the first aux-node with @var{aux-name}
given in SXML element @var{obj}
or @code{#f} is such a node is absent.
Note: it returns just the @emph{first} node found even if multiple nodes are
present, so it's mostly intended for nodes with unique names .
@c JP
与えられたSXML要素@var{obj}で@var{aux-name}という名前の付いている最初の
補助ノードを返します。そのようなノードがない場合は@code{#f}を返します。
注意: 複数のノードがあっても@emph{最初に}見つかったノードのみを
返します。したがって、ユニークな名前を持っているノード群に対して
使われることを意図しています。
@c COMMON
@end defun

@defun sxml:aux-nodes obj aux-name
@c MOD sxml.tools
@c EN
Return a list of aux-node with @var{aux-name}
given in SXML element @var{obj}
or '@code{()} if such a node is absent.
@c JP
与えられたSXML要素@var{obj}で@var{aux-name}とうい名前の付いている補助ノードの
リストを返します。そのようなノードがなければ'@code{()}を返します。
@c COMMON
@end defun

@defun sxml:attr obj attr-name
@c MOD sxml.tools
@c EN
Accessor for an attribute @var{attr-name} of
given SXML element @var{obj}.
It returns:
the value of the attribute if the attribute is present, or
@code{#f} if there is no such an attribute in the given element.
@c JP
与えられたSXML要素@var{obj}の@var{attr-name}という属性へのアクセッサです。
戻り値は、その属性が存在すればその属性の値、与えられた要素に
そのような属性がなければ@code{#f}です。
@c COMMON
@end defun

@defun sxml:num-attr obj attr-name
@c MOD sxml.tools
@c EN
Accessor for a numerical attribute @var{attr-name}
of given SXML element @var{obj}.
It returns:
a value of the attribute as the attribute as a number if the attribute
is present and its value may be converted to number using @code{string->number},
or @code{#f} if there is no such an attribute in the given element or
its value can't be converted to a number.
@c JP
与えられたSXML要素@var{obj}の@var{attr-name}という数値の属性への
アクセッサです。
戻り値は、その属性が存在してその値が@code{string->number}により数値へ
変換できる場合はその属性を数値としてその属性の値、
与えられた要素にそのような属性がないかその値が数値へ変換できない場合は
@code{#f}です。
@c COMMON
@end defun

@defun sxml:attr-u obj attr-name
@c MOD sxml.tools
@c EN
Accessor for an attribute @var{attr-name}
of given SXML element @var{obj} which
may also be an attributes-list or nodeset (usually content of SXML element).

It returns:
the value of the attribute if the attribute is present,
or @code{#f} if there is no such an attribute in the given element.

The @code{-u} suffix indicates it can be used for non-normalized
SXML node.  ('u' stands for 'universal').
@c JP
与えられたSXML要素@var{obj}の@var{attr-name}という名前の属性への
アクセッサです。@var{obj}は、(通常はSXML要素の内容である)
属性リストやノードセットでも構いません。

戻り値は、その属性が存在すればその属性の値、与えられた要素に
そのような属性がない場合は@code{#f}です。

@code{-u}が付くものは、正規化されていないSXMLノードに対しても
使えるということを示しています。('u'は'universal'の意味です。)
@c COMMON
@end defun

@defun sxml:ns-list obj
@c MOD sxml.tools
@c EN
Returns the list of namespaces for given element.
Analog of @code{((sxpath '(@@@@ *NAMESPACES* *)) @var{obj})}
Empty list is returned if there is no list of namespaces.
@c JP
与えられた要素の名前空間のリストを返します。
@code{((sxpath '(@@@@ *NAMESPACES* *)) @var{obj})}と類似です。
名前空間のリストがない場合は空リストが返されます。
@c COMMON
@end defun

@defun sxml:ns-id->nodes obj namespace-id
@c MOD sxml.tools
@c EN
Returns the list of namespace-assoc's for given @var{namespace-id} in
SXML element @var{obj}.
Analog of @code{((sxpath '(@@@@ *NAMESPACES* namespace-id)) @var{obj})}.
Empty list is returned if there is no namespace-assoc with
@var{namespace-id} given.
@c JP
SXML要素@var{obj}で、与えられた@var{namespace-id}に対応する名前空間の
連想リストのリストを返します。
@code{((sxpath '(@@@@ *NAMESPACES* namespace-id)) @var{obj})}と類似です。
与えられた@var{namespace-id}に対応する名前空間の連想リストがない場合は
空リストが返されます。
@c COMMON
@end defun

@defun sxml:ns-id->uri obj namespace-id
@c MOD sxml.tools
@c EN
Returns a URI for @var{namespace-id} given, or
@code{#f} if there is no namespace-assoc with @var{namespace-id} given.
@c JP
与えられた@var{namespace-id}に対応するURIを返します。
与えられた@var{namespace-id}に対応する名前空間の連想リストがない場合は
@code{#f}を返します。
@c COMMON
@end defun

@defun sxml:ns-uri->id obj uri
@c MOD sxml.tools
@c EN
Returns a namespace-id for namespace URI given.
@c JP
与えられた名前空間URIに対応する名前空間IDを返します。
@c COMMON
@end defun

@defun sxml:ns-id ns-assoc
@c MOD sxml.tools
@c EN
Returns namespace-id for given namespace-assoc list.
@c JP
与えられた名前空間連想リストに対応する名前空間IDを返します。
@c COMMON
@end defun

@defun sxml:ns-uri ns-assoc
@c MOD sxml.tools
@c EN
Returns URI for given namespace-assoc list.
@c JP
与えられた名前空間連想リストに対応するURIを返します。
@c COMMON
@end defun

@defun sxml:ns-prefix ns-assoc
@c MOD sxml.tools
@c EN
It returns namespace prefix for given namespace-assoc list.
Original (as in XML document) prefix for namespace-id given
has to be strored as the third element in namespace-assoc list
if it is different from namespace-id.
If original prefix is omitted in namespace-assoc then
namespace-id is used instead.
@c JP
与えられた名前空間連想リストに対応する名前空間接頭辞を返します。
与えられた名前空間IDの(XML文書における)オリジナルの接頭辞は、
それが名前空間IDと異なる場合は、名前空間連想リストの3番目の要素として
格納されなければなりません。
名前空間連想リストでオリジナルの接頭辞が省略されている場合は、
代わりに名前空間IDが使われます。
@c COMMON
@end defun

@c ----------------------------------------------------------------------
@node SXML modifiers, SXPath auxiliary utilities, SXML accessors, Manipulating SXML structure
@subsection SXML modifiers
@c NODE SXMLのモディファイヤ

@c EN
Constructors and mutators for normalized SXML data.
These functions are optimized for normalized SXML data.
They are not applicable to arbitrary non-normalized SXML data.

Most of the functions are provided in two variants:
@c JP
正規化されたSXMLデータのコンストラクタやミューテータです。
これらの関数は、正規化されたSXMLデータに最適化されています。
任意の正規化されていないSXMLデータには適用できません。

ほとんどの関数には2つのバージョンがあります。
@c COMMON
@enumerate
@item
@c EN
side-effect intended functions for linear update of given elements.
Their names are ended with exclamation mark.
Note that the returned value of this variant is unspecified,
unless explicitly noted.
An example: @code{sxml:change-content!}.
@c JP
与えられた要素のその場での更新のために副作用が意図された関数。
これらの名前はエクスクラメーションマークで終わっています。
このバージョンの戻り値は、特に断りのない限り未定義です。
例としては、@code{sxml:change-content!}が挙げられます。
@c COMMON
@item
@c EN
pure functions without side-effects which return modified elements.
An example: @code{sxml:change-content}.
@c JP
変更された要素を返す、副作用のない純粋な関数。
例としては、@code{sxml:change-content}が挙げられます。
@c COMMON
@end enumerate

@defun sxml:change-content obj new-content
@defunx sxml:change-content! obj new-content
@c MOD sxml.tools
@c EN
Change the content of given SXML element to @var{new-content}.
If @var{new-content} is an empty list then the @var{obj} is transformed
to an empty element.
The resulting SXML element is normalized.
@c JP
与えられたSXML要素の内容を、@var{new-content}に変更します。
@var{new-content}が空リストの場合は、@var{obj}は空要素に変更されます。
結果のSXML要素は正規化されています。
@c COMMON
@end defun

@defun sxml:change-attrlist obj new-attrlist
@defunx sxml:change-attrlist! obj new-attrlist
@c MOD sxml.tools
@c EN
The resulting SXML element is normalized.
If @var{new-attrlist} is empty,
the cadr of @var{obj} is @code{(@@)}.
@c JP
結果のSXML要素は正規化されています。
@var{new-attrlist}が空の場合は、@var{obj}のcadrは@code{(@@)}になります。
@c COMMON
@end defun

@defun sxml:change-name obj new-name
@defunx sxml:change-name! obj new-name
@c MOD sxml.tools
@c EN
Change a name of SXML element destructively.
@c JP
SXML要素の名前を破壊的に変更します。
@c COMMON
@end defun

@defun sxml:add-attr obj attr
@c MOD sxml.tools
@c EN
Returns SXML element @var{obj} with attribute @var{attr} added,
or @code{#f} if the attribute with given name already exists.
@var{attr} is @code{(@var{attr-name} @var{attr-value})}.
Pure functional counterpart to @code{sxml:add-attr!}.
@c JP
属性@var{attr}が追加されたSXML要素@var{obj}を返します。
与えられた名前の属性がすでに存在する場合は@code{#f}を返します。
@var{attr}は@code{(@var{attr-name} @var{attr-value})}です。
@code{sxml:add-attr!}に対応する純粋関数的な関数です。
@c COMMON
@end defun

@defun sxml:add-attr! obj attr
@c MOD sxml.tools
@c EN
Add an attribute @var{attr} for an element @var{obj}.
Returns @code{#f} if the attribute with given name already exists.
The resulting SXML node is normalized.
Linear update counterpart to @code{sxml:add-attr}.
@c JP
要素@var{obj}に属性@var{attr}を追加します。
与えられた名前の属性がすでに存在する場合は@code{#f}を返します。
結果のSXMLノードは正規化されています。
@code{sxml:add-attr}に対応するその場で更新する関数です。
@c COMMON
@end defun

@defun sxml:change-attr obj attr
@c MOD sxml.tools
@c EN
Returns SXML element @var{obj} with changed value of
attribute @var{attr}, or @code{#f}
if where is no attribute with given name.
@var{attr} is @code{(@var{attr-name} @var{attr-value})}.
@c JP
属性@var{attr}の値が変更されたSXML要素@var{obj}を返します。
与えられた名前の属性がない場合は@code{#f}を返します。
@var{attr}は@code{(@var{attr-name} @var{attr-value})}です。
@c COMMON
@end defun

@defun sxml:change-attr! obj attr
@c MOD sxml.tools
@c EN
Change value of the attribute for element @var{obj}.
@var{attr} is @code{(@var{attr-name} @var{attr-value})}.
Returns @code{#f} if where is no such attribute.
@c JP
要素@var{obj}の属性の値を変更します。
@var{attr}は@code{(@var{attr-name} @var{attr-value})}です。
そのような属性がない場合は@code{#f}を返します。
@c COMMON
@end defun

@defun sxml:set-attr obj attr
@defunx sxml:set-attr! obj attr
@c MOD sxml.tools
@c EN
Set attribute @var{attr} of element @var{obj}.
If there is no such attribute the new one is added.
@c JP
要素@var{obj}の属性@var{attr}をセットします。
そのような属性がない場合は新しい属性として追加されます。
@c COMMON
@end defun

@defun sxml:add-aux obj aux-node
@c MOD sxml.tools
@c EN
Returns SXML element @var{obj}
with an auxiliary node @var{aux-node} added.
@c JP
補助ノード@var{aux-node}が追加されたSXML要素@var{obj}を返します。
@c COMMON
@end defun

@defun sxml:add-aux! obj aux-node
@c MOD sxml.tools
@c EN
Add an auxiliary node @var{aux-node} for an element @var{obj}.
@c JP
要素@var{obj}に補助ノード@var{aux-node}を追加します。
@c COMMON
@end defun

@defun sxml:squeeze obj
@defunx sxml:squeeze! obj
@c MOD sxml.tools
@c EN
Eliminates empty lists of attributes and aux-lists for given SXML element
@var{obj} and its descendants ("minimize" it).
Returns a minimized and normalized SXML element.
@c JP
与えられたSXML要素@var{obj}とその子孫について、空のリストである属性
および補助リストを排除します(最小化)。
最小化され、正規化されたSXML要素が返されます。
@c COMMON
@end defun

@defun sxml:clean obj
@c MOD sxml.tools
@c EN
Eliminates empty lists of attributes and all aux-lists for given SXML element
@var{obj} and its descendants.
Returns a minimized and normalized SXML element.
@c JP
与えられたSXML要素@var{obj}とその子孫について、空リストである属性と、
全ての補助リストを削除します。
最小化され、正規化されたSXML要素が返されます。
@c COMMON
@end defun

@c ----------------------------------------------------------------------
@node SXPath auxiliary utilities, SXML to markup conversion, SXML modifiers, Manipulating SXML structure
@subsection SXPath auxiliary utilities
@c NODE SXPathの補助的ユーティリティ

@c EN
These are convenience utilities to extend SXPath functionalities.
@c JP
これらは、SXPathの機能を拡張する便利なユーティリティです。
@c COMMON

@defun sxml:add-parents obj . top-ptr
@c MOD sxml.tools
@c EN
Returns an SXML nodeset with a 'parent pointer' added.
A parent pointer is an aux node of the form @code{(*PARENT* @var{thunk})},
where @var{thunk} returns the parent element.
@c JP
SXMLノードセットに'親へのポインタ'を追加したものを返します。
親へのポインタは、@code{(*PARENT* @var{thunk})}というフォームを持つ
補助ノードです。@var{thunk}は親要素を返します。
@c COMMON
@end defun

@defun sxml:node-parent rootnode
@c MOD sxml.tools
@c EN
Returns a fast 'node-parent' function, i.e.
a function of one argument - SXML element - which returns its parent
node using @code{*PARENT*} pointer in aux-list.
'@code{*TOP-PTR*} may be used as a pointer to root node.
It return an empty list when applied to root node.
@c JP
高速な'node-parent'関数を返します。
すなわち、SXML要素を1引数として取り、補助リストで
@code{*PARENT*}ポインタを使ってその親ノードを返す関数を返します。
'@code{*TOP-PTR*}はルートノードへのポインタとして使われます。
ルートノードに対して適用されると空リストを返します。
@c COMMON
@end defun

@defun sxml:lookup id index
@c MOD sxml.tools
@c EN
Lookup an element using its ID.
@c JP
要素をそのIDを使って探します。
@c COMMON
@end defun

@c ----------------------------------------------------------------------
@node SXML to markup conversion,  , SXPath auxiliary utilities, Manipulating SXML structure
@subsection SXML to markup conversion
@c NODE SXMLからマークアップへの変換

@c EN
Procedures to generate XML or HTML marked up text from SXML.
For more advanced conversion, see the SXML serializer
(@ref{Serializing XML and HTML from SXML}).

@c JP
SXMLからXMLやHTMLなどのマークアップされたテキストを生成する手続き。
もっと高尚な変換器を得たいだけならば、
@ref{Serializing XML and HTML from SXML}をチェックして下さい。
@c COMMON

@defun sxml:clean-feed . fragments
@c MOD sxml.tools
@c EN
Filter the 'fragments'.
The fragments are a list of strings, characters,
numbers, thunks, @code{#f} -- and other fragments.
The function traverses the tree depth-first, and returns a list
of strings, characters and executed thunks,
and ignores @code{#f} and '@code{()}.

If all the meaningful fragments are strings, then
@code{(apply string-append ... )}
to a result of this function will return its string-value.

It may be considered as a variant of Oleg Kiselyov's
@code{SRV:send-reply}:
While @code{SRV:send-reply} displays fragments, this function returns the list
of meaningful fragments and filter out the garbage.
@c JP
'fragments'をフィルタします。
fragmentsは、文字列、文字、数値、手続き、@code{#f}、他のフラグメントの
リストです。
この関数はツリーを深さ優先でトラバースし、
文字列、文字、実行された手続きのリストを返し、
@code{#f}と'@code{()}を無視します。

全ての意味のあるフラグメントは文字列で、
この関数の結果に@code{(apply string-append ... )}を
適用すると、そのstring-valueを返します。

これは、Oleg Kiselyovの@code{SRV:send-reply}の変種であるとみなすことが
できるでしょう。
@code{SRV:send-reply}はフラグメントを印字(display)しますが、
この関数は意味のあるフラグメントのリストを返し、ごみをふるい落とします。
@c COMMON
@end defun

@defun sxml:attr->xml attr
@c MOD sxml.tools
@c EN
Creates the XML markup for attributes.
@c JP
属性のXMLマークアップを作ります。
@c COMMON
@end defun

@defun sxml:string->xml string
@c MOD sxml.tools
@c EN
Return a string or a list of strings where all the occurrences of
characters @code{<}, @code{>},
@code{&}, @code{"}, or @code{'} in a given string are
replaced by corresponding
character entity references. See also @code{sxml:string->html}.
@c JP
与えられた文字列中の全ての@code{<}、@code{>}、@code{&}、@code{``}、
@code{'}を対応する文字実体参照に置き換えた、文字列あるいは
文字列のリストを返します。
@code{sxml:string->html}も参照して下さい。
@c COMMON
@end defun

@defun sxml:sxml->xml tree
@c MOD sxml.tools
@c EN
A version of dispatch-node specialized and optimized for SXML->XML
transformation.
@c JP
SXML->XML変換に特化され最適化されたバージョンのノードディスパッチです。
@c COMMON
@end defun

@defun sxml:attr->html attr
@c MOD sxml.tools
@c EN
Creates the HTML markup for attributes.
@c JP
属性のHTMLマークアップを作ります。
@c COMMON
@end defun

@defun sxml:string->html string
@c MOD sxml.tools
@c EN
Given a string, check to make sure it does not contain characters
@var{<}, @var{>}, @var{&},
@var{"} that require encoding.
See also @code{html-escape-string}
in @ref{Simple HTML document construction}.
@c JP
与えられた文字列で、それがエンコーディングを必要とする文字、
@var{<}、@var{>}、@var{&}、@var{``}を含まないことをチェックします。
@ref{Simple HTML document construction}の
@code{html-escape-string}も参照して下さい。
@c COMMON
@end defun

@defun sxml:non-terminated-html-tag? tag
@c MOD sxml.tools
@c EN
This predicate yields @code{#t} for "non-terminated" HTML 4.0 tags.
@c JP
この述語は、``終了タグのない''HTML 4.0のタグに対して@code{#t}を
返します。
@c COMMON
@end defun

@defun sxml:sxml->html tree
@c MOD sxml.tools
@c EN
A version of dispatch-node specialized and optimized for SXML->HTML
transformation.
@c JP
SXML->HTML変換に対して特化され最適化されたバージョンのノードディスパッチ
です。
@c COMMON
@end defun

@c ----------------------------------------------------------------------
@node Serializing XML and HTML from SXML, Text terminal control, Manipulating SXML structure, Library modules - Utilities
@section @code{sxml.serializer} -  Serializing XML and HTML from SXML
@c NODE SXMLからXMLとXHTMLのシリアライゼーション, @code{sxml.serializer} - SXMLからXMLとXHTMLのシリアライゼーション

@deftp {Module} sxml.serializer
@mdindex sxml.serializer
@c EN
This module contains a full-featured serializer from SXML into XML and
HTML, partially conforming to XSLT 2.0 and XQuery 1.0 Serialization
(@uref{http://www.w3.org/TR/2005/CR-xslt-xquery-serialization-20051103/}).
It's more powerful than sxml:sxml->xml and sxml:sxml->html from
sxml.tools.

The manual entry is mainly derived from the comments in the original
source code.
@c JP
このモジュールはSXMLからXMLとHTMLへの変換を行う、様々な機能を持つ
シリアライザを提供します。XSLT2.0とXQuery1.0に部分的に適合しています。
(@uref{http://www.w3.org/TR/2005/CR-xslt-xquery-serialization-20051103/})。
sxml.toolsのsxml:sxml->xmlとsxml:sxml->htmlよりも強力です。

マニュアルのエントリは主に、オリジナルのソースコードから取られてています。
@c COMMON
@end deftp

@c ----------------------------------------------------------------------
@menu
* Simple SXML serializing::
* Custom SXML serializing::
@end menu

@c ----------------------------------------------------------------------
@node Simple SXML serializing, Custom SXML serializing, Serializing XML and HTML from SXML, Serializing XML and HTML from SXML
@subsection Simple SXML serializing
@c NODE 簡単なSXML変換

@c EN
The SXML serializer provides some convenient high-level converters which
should be enough for most tasks.
@c JP
高レベルの、簡単に使えるシリアライザです。大抵の目的にはこれで十分使えるでしょう。
@c COMMON

@defun srl:sxml->xml sxml-obj :optional port-or-filename
@c MOD sxml.serializer
@c EN
Serializes the @var{sxml-obj} into XML, with indentation to facilitate
readability by a human.

If @var{port-or-filename} is not supplied, the functions return a
string that contains the serialized representation of the
@var{sxml-obj}.

If @var{port-or-filename} is supplied and is a port, the functions
write the serialized representation of @var{sxml-obj} to this port and
return an unspecified result.

If @var{port-or-filename} is supplied and is a string, this string is
treated as an output filename, the serialized representation of
@var{sxml-obj} is written to that filename and an unspecified result
is returned. If a file with the given name already exists, the effect
is unspecified.
@c JP
@var{sxml-obj}をXMLへと変換します。出力は人間が読みやすいように
インデントされます。

@var{port-or-filename}が与えられなければ、
戻り値は@var{sxml-obj}の変換結果の文字列になります。

@var{port-or-filename}がポートならば、そのポートにXMLを書き出します。
戻り値は不定です。

@var{port-or-filename}が文字列ならば、その名のファイルにXMLを書き出し
ます。戻り値は不定です。そのようなファイルが既に存在する場合、
結果は不定です。
@c COMMON
@end defun

@defun srl:sxml->xml-noindent sxml-obj :optional port-or-filename
@c MOD sxml.serializer
@c EN
Serializes the @var{sxml-obj} into XML, without indentation.

Argument @var{port-or-filename} works like described in
@code{srl:sxml->xml}.
@c JP
@code{srl:sxml->xml}と同じように動作しますが、インデントを行いません。

引数@var{port-or-filename}は@code{srl:sxml->xml}と同様に動作します。
@c COMMON
@end defun

@defun srl:sxml->html sxml-obj :optional port-or-filename
@c MOD sxml.serializer
@c EN
Serializes the @var{sxml-obj} into HTML, with indentation to
facilitate readability by a human.

Argument @var{port-or-filename} works like described in @code{srl:sxml->xml}.
@c JP
@var{sxml-obj}をHTMLへと変換します。出力は人間が読みやすいように
インデントされます。

引数@var{port-or-filename}は@code{srl:sxml->xml}と同様に動作します。
@c COMMON
@end defun

@defun srl:sxml->html-noindent sxml-obj :optional port-or-filename
@c MOD sxml.serializer
@c EN
Serializes the @var{sxml-obj} into HTML, without indentation.

Argument @var{port-or-filename} works like described in @code{srl:sxml->xml}.
@c JP
@code{srl:sxml->html}と同じように動作しますが、インデントを行いません。

引数@var{port-or-filename}は@code{srl:sxml->xml}と同様に動作します。
@c COMMON
@end defun

@c ----------------------------------------------------------------------
@node Custom SXML serializing,  , Simple SXML serializing, Serializing XML and HTML from SXML
@subsection Custom SXML serializing
@c NODE カスタムSXML変換

@c EN
These functions provide full access to all configuration parameters of
the XML serializer.
@c JP
以下の手続きはXMLシリアライザの全ての設定パラメータへのアクセスを提供
します。
@c COMMON

@defun srl:parameterizable sxml-obj :optional port-or-filename params*
@c MOD sxml.serializer
@c EN
Generalized serialization procedure, parameterizable with all the
serialization parameters supported by this implementation.
@c JP
汎用シリアライズ手続、この実装でサポートするすべてのシリアライズパラメー
タのパラメータ化。
@c COMMON

@c EN
@var{sxml-obj} - an SXML object to serialize
@c JP
@var{sxml-obj} - シリアライズするSXMLオブジェクト。
@c COMMON

@c EN
@var{port-or-filename} - either @code{#f}, a port or a string; works
like in srl:sxml->xml (@ref{Simple SXML serializing}).
@c JP
@var{port-or-filename} - @code{#f}あるいはポートあるいは文字列のどれか。
srl:sxml->xmlのものと同じ働きをします(@ref{Simple SXML serializing})。
@c COMMON

@c EN
@var{params} - each parameter is a cons of param-name (a symbol) and
param-value.  The available parameter names and their values are
described below:
@c JP
@var{params} - 各パラメータはパラメータ名(シンボル)とパラメータ値との
コンス対。利用可能なパラメータ名とその値については後述。
@c COMMON

@c EN
@code{method} - Either the symbol @code{xml} or @code{html}.  For a
detailed explanation of the difference between XML and HTML methods,
see XSLT 2.0 and XQuery 1.0 Serialization (@uref{http://www.w3.org/TR/2005/CR-xslt-xquery-serialization-20051103/}).
@c JP
@code{method} - シンボル@code{xml}か@code{html}のどちらか。XMLメソッド
とHTMLメソッドの相違についての詳しい説明は、XSLT 2.0 と XQuery
Serialization
(@uref{http://www.w3.org/TR/2005/CR-xslt-xquery-serialization-20051103/})
を参照してください。
@c COMMON

@c EN
@code{indent} - Whether the output XML should include whitespace for
human readability (@code{#t} or @code{#f}).  You can also supply a
string, which will be used as the indentation unit.
@c JP
@code{indent} - 出力の XML が読みやすさのために空白を含むかどうか
(@code{#t}あるいは@code{#f})。文字列を設定することもでき、その場合
インデント単位に使われます。
@c COMMON

@c EN
@code{omit-xml-declaration?} - Whether the XML declaration should be
omitted.  Default: @code{#t}.
@c JP
@code{omit-xml-declaration?} - XML宣言を省略するかどうか。デフォルトは
@code{#t}。
@c COMMON

@c EN
@code{standalone} - Whether to define the XML document as standalone in
the XML declaration.  Should be one of the symbols @code{yes},
@code{no} or @code{omit}, the later causing standalone declaration to
be suppressed.  Default: @code{omit}.
@c JP
@code{standalone} - XML ドキュメントを XML 宣言でスタンドアローンとし
て定義するかどうか。@code{yes}、@code{no}、@code{omit}のうちいずれかの
シンボルでなければならない。デフォルトは @code{omit}
@c COMMON

@c EN
@code{version} - The XML version used in the declaration.  A string or
a number.  Default: @code{"1.0"}.
@c JP
@code{version} - XML宣言中のXMLバージョン。文字列または数。デフォルト
は@code{"1.0"}。
@c COMMON

@c EN
@code{cdata-section-elements} - A list of SXML element names (as
symbols).  The contents of those elements will be escaped as CDATA
sections.
@c JP
@code{cdata-section-elements} - SXML要素の名前(シンボル)のリスト。これ
らの要素の中身はCDATAセクションと同様にエスケープされる。
@c COMMON

@c EN
@code{ns-prefix-assig} - A list of @code{(cons prefix namespace-uri)},
where each @code{prefix} is a symbol and each @code{namespace-uri} a
string.  Will serialize the given namespaces with the corresponding
prefixes.
@c JP
@code{ns-prefix-assig} - @code{(cons prefix namespace-uri)}のリスト。
各@code{prefix}はシンボルで、@code{namespace-uri}は文字列。
対応する接頭辞をつけて与えられた名前空間をシリアライズする。
@c COMMON

@c EN
ATTENTION: If a parameter name is unexpected or a parameter value is
ill-formed, the parameter is silently ignored!
@c JP
注意： パラメータ名が期待された名前ではない場合、あるいはパラメータ値
が不正な形式である場合にはそのようなパラメータは警告なしで無視されます。
@c COMMON

@c EN
Example usage:

@lisp
(srl:parameterizable
  '(tag (@@ (attr "value")) (nested "text node") (empty))
  (current-output-port)
  '(method . xml)  ; XML output method is used by default
  '(indent . "\t")  ; use a single tabulation to indent
  '(omit-xml-declaration . #f)  ; add XML declaration
  '(standalone . yes)  ; denote a standalone XML document
  '(version . "1.0"))  ; XML version
@end lisp
@c JP
使用実例：
@lisp
(srl:parameterizable
  '(tag (@@ (attr "value")) (nested "text node") (empty))
  (current-output-port)
  '(method . xml)  ; XML出力をデフォールト
  '(indent . "\t")  ; インデントは一つのタブ
  '(omit-xml-declaration . #f)  ; XML宣言をつける
  '(standalone . yes)  ; 「standalone」宣言もつける
  '(version . "1.0"))  ; XMLのバージョン
@end lisp
@c COMMON

@lisp
param ::= (cons param-name param-value)
param-name ::= symbol

cdata-section-elements
value ::= (listof sxml-elem-name)
sxml-elem-name ::= symbol

indent
value ::= 'yes | #t | 'no | #f | whitespace-string

method
value ::= 'xml | 'html

ns-prefix-assig
value ::= (listof (cons prefix namespace-uri))
prefix ::= symbol
namespace-uri ::= string

omit-xml-declaration?
value ::= 'yes | #t | 'no | #f

standalone
value ::= 'yes | #t | 'no | #f | 'omit

version
value ::= string | number
@end lisp
@end defun

@defun srl:sxml->string sxml-obj cdata-section-elements indent method ns-prefix-assig omit-xml-declaration? standalone version
@c MOD sxml.serializer
@c EN
Same as @code{srl:parameterizable} returning a string and without the
overhead of parsing parameters.  This function interface may change in
future versions of the library.
@c JP
@code{srl:parameterizable}と同様ですが、文字列を返し、パラメータ解析のオーバヘッ
ドはありません。この関数のインタフェースはこのライブラリの将来のバージョ
ンでは変更されるかもしれません。
@c COMMON
@end defun

@defun srl:display-sxml sxml->obj port-or-filename cdata-section-elements indent method ns-prefix-assig omit-xml-declaration? standalone version
@c MOD sxml.serializer
@c EN
Same as @code{srl:parameterizable} writing output to
@var{port-or-filename} and without the overhead of parsing parameters.
This function interface may change in
future versions of the library.
@c JP
@code{srl:parameterizable}と同様ですが、結果を
@var{port-or-filename}に書き出します。パラメータ解析のオーバーヘッドはありません。
この関数のインタフェースはこの
ライブラリの将来のバージョンでは変更されるかもしれません。
@c COMMON
@end defun

@c ----------------------------------------------------------------------
@node Text terminal control, CSV tables, Serializing XML and HTML from SXML, Library modules - Utilities
@section @code{text.console} - Text terminal control
@c NODE テキスト端末制御, @code{text.console} - テキスト端末制御

@deftp {Module} text.console
@mdindex text.console
@c EN
This module provides a simple interface for character terminal control.
Currently we support vt100 compatible terminals and Windows
console.

This module doesn't depend on external library such as @code{curses}
and works with Gauche alone, but
what it can do is limited; for example, you can't get an event
when shift key alone is pressed.  For finer controls, you need
some extension libraries.

For an example of the features in this module, see 
@file{snake.scm} in the examples directory of Gauche source distribution.
@c JP
このモジュールは文字端末を制御する簡単なインタフェースを提供します。
今のところ、vt100互換端末とWindowsコンソールがサポートされています。

@code{curses}等の外部ライブラリには依存しておらず、Gaucheだけで使うことができますが、
出来ることは限られています。
例えばシフトキーだけが押されたタイミングでイベントを受け取ることはできません。
より細かい制御には、何らかの外部拡張ライブラリが必要になるでしょう。

このモジュールの機能の例としては、
Gaucheソースのexamplesディレクトリにある@file{snake.scm}を見てください。
@c COMMON
@end deftp

@c EN
@subheading Console objects
@c JP
@subheading コンソールオブジェクト
@c COMMON

@deftp {Class} <vt100>
@clindex vt100
@c MOD text.console
@c EN
Represents a vt100-compatible terminal.   An instance of this class
can be passed to the ``console'' argument of the following generic
functions.
@c JP
vt100互換端末を表します。このクラスのインスタンスは
以降のジェネリックファンクションの ``console'' 引数に渡せます。
@c COMMON

@defivar {<vt100>} iport
@c EN
Input port connected to the terminal.  The default value is
the standard input port.
@c JP
端末に接続されている入力ポートです。デフォルトは標準入力です。
@c COMMON
@end defivar

@defivar {<vt100>} oport
@c EN
Output port connected to the terminal.  The default value is
the standard output port.
@c JP
端末に接続されている出力ポートです。デフォルトは標準出力です。
@c COMMON
@end defivar

@defivar {<vt100>} input-delay
@c EN
The terminal send back special keys encoded in an input escape sequence.
In order to distinguish such keys from the actual ESC key, we time the
input---if the subsequent input doesn't come within @code{input-delay}
microseconds, we interpret the input as individual keystroke, rather
than a part of an escape sequence.  The default value is @code{1000} (1ms).
@c JP
端末は、特殊キーが押された場合、ESCから始まるエスケープシーケンスを送って来ます。
実際にESCキーが押された場合と区別するために、入力の間隔を測っています。
後続の入力が@code{input-delay}μs以内に来なかった場合はそこでシーケンスが終了したと
みなし、受け取っているシーケンスが有効なエスケープシーケンスを構成しなければ
個別にキー入力されたとみなします。デフォルトは@code{1000}、すなわち1msです。
@c COMMON
@end defivar
@end deftp

@deftp {Class} <windows-console>
@clindex windows-console
@c EN
Represents Windows console.  This class is defined on all platforms,
but its useful methods are only available on Windows-native runtime.

It doesn't have public slots.
@c JP
Windowsコンソールを表します。このクラス自体は全てのプラットフォームで
定義されていますが、有用なメソッドはWindowsネイティブのランタイムでしか提供されません。

パブリックなスロットはありません。
@c COMMON
@end deftp

@c EN
The application has to check the runtime to see what kind of console
is available.  A suggested flow is as follows.
@c JP
アプリケーションは実行時にどの種類のコンソールが利用可能かを見極めなければなりません。
推奨される手順は次のとおりです。
@c COMMON
@itemize
@item 
@c EN
If @code{has-windows-console?} returns true, create @code{<windows-console>}
instance.
You don't need @code{cond-expand}; @code{has-windows-console?} returns
@code{#f} on non-Windows platforms.
@c JP
@code{has-windows-console?}が真の値を返したなら、@code{<windows-console>}の
インスタンスを作ります。
@code{has-windows-console?}はWindowsプラットフォーム以外では常に@code{#f}を
返すので、@code{cond-expand}は不要です。
@c COMMON
@item 
@c EN
Check the environment variable @code{TERM}.  If it is set and
satisfies @code{vt100-compatible?}, you can create
@code{<vt100>} instance.
(Note: It is possible that you end up using @code{<vt100>} console
on Windows; e.g. @code{gosh} running on MSYS shell.)
@c JP
環境変数@code{TERM}を調べます。それが定義されていて、@code{vt100-compatible?}を
満たすなら、@code{<vt100>}のインスタンスを作ります。
(Windows上でも@code{<vt100>}端末を使うことになる可能性もあります。
例えば@code{gosh}がMSYSシェルから使われている場合です。)
@c COMMON
@item
@c EN
Otherwise, console isn't available.
@c JP
いずれでもなければ、端末は使えません。
@c COMMON
@end itemize

@c EN
The following procedure packages this flow.
@c JP
次の手続きは上の手順を実装しています。
@c COMMON

@defun make-default-console :key if-not-available
@c MOD text.console
@c EN
Determines a suitable console class of the running process and
returns its instance.

If no suitable console is available, the behavior depends on the
@var{if-not-available} keyword argument.  If it is @code{:error},
which is default, an error is signalled.  If it is @code{#f},
the procedure returns @code{#f}. 
@c JP
実行中のプロセスで使える端末のインスタンスを作成して返します。

適切な端末クラスが無い場合、振る舞いは@var{if-not-available}キーワード引数に
依存します。デフォルトである@code{:error}の場合はエラーが報告されます。
@code{#f}の場合はこの手続きが@code{#f}を返します。
@c COMMON
@end defun

@defun vt100-compatible? string
@c MOD text.console
@c EN
Given the string value of the environment variable @code{TERM},
returns @code{#t} if the terminal can be handled by @code{<vt100>} console,
@code{#f} otherwise.
@c JP
環境変数@code{TERM}の値を文字列で受け取り、それが@code{<vt100>}端末として
扱えるなら@code{#t}を、そうでなければ@code{#f}を返します。
@c COMMON
@end defun


@subheading Console control

@deffn {Generic function} call-with-console console proc :key mode
@c MOD text.console
Takes over the control of the console, and calls @var{proc} with
@var{console} as the only argument.   The console is set to
the @var{mode}, which must be a symbol @code{with-terminal-mode}
accepts: @code{raw}, @code{rare} or @code{cooked}.  By default
the console is set to @code{rare} mode, which turn off the echoing
and passes most of keystrokes to the program, but it intercepts
terminal controls (like @code{Ctrl-C} for interrupt and
@code{Ctrl-Z} for suspend; the actual key depends on terminal
settings, though.)

If @var{proc} raises an unhandled error, this generic function
resets the terminal mode before returning.  It does not clear
the screen.
@end deffn

@deffn {Generic function} putch console char
@c MOD text.console
Display a character at the current cursor position, and
move the current cursor position.
@end deffn

@deffn {Generic function} putstr console string
@c MOD text.console
Display a string from the current cursor position, and
move the current cursor position.
@end deffn

@deffn {Generic function} beep console
@c MOD text.console
Ring the beep, or flash the screen (visible bell) if possible.
@end deffn

@deffn {Generic function} getch console
@c MOD text.console
Fetch a keypress from the console.  This blocks until
any key is pressed.

The return value may be one of the following values:

@table @asis
@item A character
A key for the character is pressed.  It may be a control code
if the control key is pressed with the key; that is, if the user
presses Ctrl-A, @code{#\x01} will be returned.
@item A symbol
Indicates a special key; the following keys are supported:
@code{KEY_UP}, @code{KEY_DOWN}, @code{KEY_LEFT}, @code{KEY_RIGHT},
@code{KEY_HOME}, @code{KEY_END}, @code{KEY_INS}, @code{KEY_DEL},
@code{KEY_PGDN}, @code{KEY_PGUP}, @code{KEY_F1}, @code{KEY_F2},
@code{KEY_F3}, @code{KEY_F4}, @code{KEY_F5}, @code{KEY_F6},
@code{KEY_F7}, @code{KEY_F8}, @code{KEY_F9}, @code{KEY_F10},
@code{KEY_F11}, @code{KEY_F12}.
(Note: DELETE key is usually mapped to @code{#\x7f}, but it depends on
the terminal).
@item A list of symbol @code{ALT} and a character.
Indicates the character key is pressed with Alt key.  For example,
if the user presses Alt-a, @code{(ALT #\a)} is returned (assuming
CAPSLOCK is off).
@item EOF
Indicates the input is closed somehow.
@end table

Modifier keys except @code{ALT} are not treated separately but
included in the returned keycode.  Assuming CAPSLOCK is off,
if the user press @code{a}, @code{Shift}+@code{a}, and @code{Ctrl}+@code{a},
the returned value is @code{#\a}, @code{#\A} and @code{#\x01}, respectively.
@code{Ctrl}+@code{Shift}+@code{a} can't be distinguished from 
@code{Ctrl}+@code{a}.  @code{ALT}+@code{a}, @code{ALT}+@code{Shift}+@code{a},
and @code{ALT}+@code{Ctrl}+@code{a} will be @code{(ALT #\a)},
@code{(ALT #\A)} and @code{(ALT #\x01)}, respectively.
@end deffn

@deffn {Generic function} chready? console
@c MOD text.console
Returns true if there's a key sequence to be read in the console's
input.
@end deffn

@deffn {Generic function} query-cursor-position console
@c MOD text.console
Returns two values, the current cursor's x and y position.
The top-left corner is (0,0).
@end deffn

@deffn {Generic function} move-cursor-to console row column
@c MOD text.console
Move cursor to the specified position.  The top-left corner is (0,0).
@end deffn

@deffn {Generic function} reset-terminal console
@c MOD text.console
Reset terminal.  Usually this sets the
character attributes to the default,
clears the screen, and moves the cursor to (0, 0).
@end deffn

@deffn {Generic function} clear-screen console
@c MOD text.console
Clear entire screen.
@end deffn

@deffn {Generic function} clear-to-eol console
@c MOD text.console
Clear characters from the current cursor position to the
end of the line.
@end deffn

@deffn {Generic function} clear-to-eos console
@c MOD text.console
Clear characters from the current cursor position to the
end of the screen.
@end deffn

@deffn {Generic function} hide-cursor console
@deffnx {Generic function} show-cursor console
@c MOD text.console
Hide/show the cursor.
@end deffn

@deffn {Generic function} cursor-down/scroll-up console
@c MOD text.console
If the cursor is at the bottom line of the screen,
scroll up the contents and clear the bottom line; the cursor stays
the same position.  If the cursor is not at the bottom line of
the screen, move the cursor down.
@end deffn

@deffn {Generic function} cursor-up/scroll-down console
@c MOD text.console
If the cursor is at the top line of the screen,
scroll down the contents and clear the top line; the cursor stays
the same position.  If the cursor is not at the top line of
the screen, move the cursor up.
@end deffn

@deffn {Generic function} query-screen-size console
@c MOD text.console
Returns two values, the width and height of the screen.

Note: This may affect what's shown in the console.
It is recommended that you only call this before redrawing
the entire screen and save the result.
@end deffn

@deffn {Generic function} set-character-attribute console spec
@c MOD text.console
Set the console so that the subsequent characters will be written
with attributes specified by @var{spec}.

The character attributes spec is a list in the following format:

@example
(<fgcolor> [<bgcolor> . <option> ...])
@end example

where:

@example
<fgcolor> : <color> | #f     ; #f means default
<bgcolor> : <color> | #f
<color>  : black | red | green | yellow | blue | magenta | cyan | white
<option> : bright | reverse | underscore
@end example

For example, you can set characters to be written in red with 
black background and underscore, you can call:

@example
(set-character-attribute con '(red black underscore))
@end example

That the options may seem rather limited in the age of
full-color bitmap displays.  That's what it used to be, young lads.
@end deffn

@deffn {Generic function} reset-character-attribute console
@c MOD text.console
Reset character attributes to the default.
@end deffn

@deffn {Generic function} with-character-attribute console attrs thunk
@c MOD text.console
Sets the console's attributes to @var{attrs} and calls @var{thunk},
then restores the attributes.  Even if @var{thunk} throws an error,
attributes are restored.

Note: You should be able to nest this, but currently nesting
isn't working.
@end deffn


@c ----------------------------------------------------------------------
@node CSV tables, Calculate difference of text streams, Text terminal control, Library modules - Utilities
@section @code{text.csv} - CSV tables
@c NODE CSVテーブル, @code{text.csv} - CSVテーブル

@deftp {Module} text.csv
@mdindex text.csv
@c EN
Provides a function to parse/generate CSV (comma separated value) tables,
including the format defined in RFC4180.  You can customize the
separator and quoter character to deal with variations of CSV formats.

CSV table is consisted by a series of @var{records}, separated by
a newline.  Each record contains number of @var{fields}, separated
by a separator character (by default, a comma).  A field can contain
comma or newline if quoted, i.e. surrounded by double-quote characters.
To include double-quote character in a quoted field, use two
consecutive double-quote character.   Usually, the whitespaces around
the field are ignored.
@c JP
RFC4180に定義されたフォーマットを含む、
CSV (カンマ区切りの値) の表をパーズ/生成するための手続きを提供します。
区切り文字やクオート文字をカスタマイズすることで、CSVに似たフォーマットを
広くカバーすることができます。

CSV の表は、改行で区切られた @var{record} の連続で構成されます。
それぞれのレコードは、区切り文字(デフォルトではカンマ)で区切られた
複数の @var{field} を含みます。フィールドは、クォートされている
(二重引用符で囲まれている)場合は、カンマや改行を含むことができます。
クォートされたフィールドに二重引用符を含めるには、2つの連続する
二重引用符を使います。通常、フィールドの前後の空白は無視されます。
@c COMMON

@c EN
Since use cases of CSV-like files vary, we provide layered API
to be combined flexibly.
@c JP
CSV様のファイルの使われ方は多様なので、このモジュールでは柔軟に組み合わせることが出来る
多層的なAPIを提供します。
@c COMMON
@end deftp

@c EN
@subheading Low-level API
@c JP
@subheading 低レベルAPI
@c COMMON

@c EN
The bottom layer of API is to convert text into list of lists and vice versa.
@c JP
一番下の層のAPIは、テキストとリストのリストとを相互変換するものです。
@c COMMON

@defun make-csv-reader separator :optional (quote-char #\")
@c MOD text.csv
@c EN
Returns a procedure with one optional argument, an input port.
When the procedure is called, it reads one record from the port
(or, if omitted, from the current input port)
and returns a list of fields.
If input reaches EOF, it returns EOF.
@c JP
入力ポートを省略可能引数として取る手続きを返します。
手続きが呼ばれると、ポート(省略された場合は現在の入力ポート)からレコードを1つ読み込み、
フィールドのリストを返します。入力ポートが EOF に達すると、EOF を返します。
@c COMMON
@end defun

@defun make-csv-writer separator :optional newline (quote-char #\") special-char-set
@c MOD text.csv
@c EN
Returns a procedure with two arguments, output port and
a list of fields.  When the procedure is called, it
outputs a @var{separator}-separated fields with proper escapes,
to the output port.   Each field value must be a string.
The separator argument can be a character or a string.
@c JP
出力ポートとフィールドのリストの2つの引数を取る手続きを返します。
手続きが呼ばれると、@var{separator} で区切られたフィールドを
正しくエスケープして出力ポートに出力します。各フィールドの値は文字列でなければなりません。
@var{separator}は文字または文字列です。
@c COMMON

@c EN
You can also specify the record delimiter
string by @var{newline}; for example, you can pass @code{"\r\n"}
to prepare a file to be read by Windows programs.
@c JP
レコードの区切り文字列を@var{newline} で指定することもできます。例えば、ファイルが Windows の
プログラムでも読めるように、@code{"\r\n"} を渡すことができます。
@c COMMON

@c EN
The output of field is quoted when it contains special characters---
which automatically includes characters
in @var{separator}, @var{quote-char} and @var{newline} argument,
plus the characters in the char-set given to @var{special-char-set};
its default is @code{#[;\s]}.
@c JP
フィールドの出力は、その中に特殊文字が含まれていた場合にクオートされます。
@var{separator}, @var{quote-char}, @var{newline}に含まれる文字は
自動的に特殊文字と認識されます。さらに
@var{special-char-set}に文字集合を渡すと、それも特殊文字として扱われます。
省略時は@code{#[;\s]}が使われます。
@c COMMON
@end defun

@c EN
@subheading Middle-level API
@c JP
@subheading 中レベルAPI
@c COMMON

@c EN
Occasionally, CSV files generated from spreadsheet contains
superfluous rows/columns and we need to make sense of them.
Here are some utilities to help them.
@c JP
スプレッドシート等で作成されたCSVファイルはしばしば、
不要な行や列を含んでいたり、
行や列の内容から有効なデータの場所を探したりする必要があります。
そのために役に立つユーティリティが用意してあります。
@c COMMON

@c EN
A typical format of such spreadsheet-generated CSV file has
the following properties:
@c JP
スプレッドシート等によって生成される典型的なCSVには以下の特徴があります。
@c COMMON

@enumerate
@item
@c EN
There's a ``header row'' near the top; not necessarily the very
first row, but certainly it comes before any real data.  It signifies
the meaning of each column of the data.  
There may be superfluous columns inserted just for cosmetics,
and sometimes the order of columns are changed when the original spreadsheet
is edited.  So we need some
flexibility to interpret the input data.
@c JP
最初の方に、「ヘッダ行」があります。一番最初の行とは限りませんが、
データの実体より前に現れ、データの各列の意味を決めます。
しばしば、見た目のためだけに余分な列が挿入されたり、
編集によって列が入れ替わったりすることもあるので、
ヘッダ行を見てどの列に何があるか判断する必要があります。
@c COMMON

@item
@c EN
``Record rows'' follow the header row.  It contains actual data.
There may be superfluous rows inserted just for cosmetics.
Also, it's often the case that the end of data isn't marked clearly
(you find large number of rows of empty strings, for example).
@c JP
ヘッダ行の後に続く「レコード行」。ここにデータの実体があります。
見た目のためだけに余分な行が挿入されていることもあります。
また、データの終わりがきちんと示されていないことも多いです (例えば、
CSVの末尾に全ての列が空文字列である行がぞろぞろとくっついている、等。)
@c COMMON
@end enumerate

@c EN
The main purpose of middle-level CSV parser is to take the output
of low-level parser, which is a list of lists of strings, and
find the header row, and then convert the subsequent record rows
into tuples according to the header row.  A tuple is just a list of
strings, but ordered in the same way as the specified header spec.
@c JP
中レベルCSVパーザの主目的は、低レベルパーザの出力である文字列のリストのリストを
受け取って、ヘッダ行を探し出し、続くレコード行をヘッダ行の内容に沿って
タプルに変換することにあります。ここで、タプルは単なる文字列のリストですが、
指定されたヘッダ仕様に沿った順序で並べてあるものとします。
@c COMMON

@defun csv-rows->tuples rows header-specs :key required-slots allow-gap?
@c MOD text.csv
@c EN
Convert input rows (a list of lists of strings)
to a list of tuples.
A tuple is a list of slot values.

First, it looks for a header row that
matches the given @var{header-spec}.  Once the header row is found,
parse the subsequent rows as record row according to the header
and convert them to tuples.
If no header is found, @code{#f} is returned.
@c JP
入力行(文字列のリスト)のリストを、タプルのリストに変換します。
タプルはスロットの値のリストです。

まず@var{header-spec}にマッチするヘッダ行が探されます。ヘッダ行が見つかったら、
それにしたがって後続の行をレコード行として解釈し、各行をタプルへと変換します。
ヘッダ行が見つからなければ、@code{#f}が返されます。
@c COMMON

@c EN
@var{Header-specs} is a list of header spec, each of which can be either
a string, a regexp, or a predicate on a string.  If it's a string,
a column that exactly matches the string is picked.  If it's a regexp,
a column that matches the regexp is picked.  And if it's a predicate,
as you might have already guessed, a column that satisfies the predicate
is picked.

The order fo @var{header-specs} determines the order of columns of
output tuples.
@c JP
@var{header-specs}はヘッダ仕様のリストです。各要素は文字列、正規表現、
あるいは文字列を取る述語手続きのいずれかです。文字列の場合、その文字列と正確に
一致する内容を持つ列が選ばれます。正規表現なら内容がそれと一致する列、
述語手続きなら、内容がその述語を満たすような列がそれぞれ選ばれます。

@var{header-specs}に現れる順番が、出力タプルの列の順番を決めます。
@c COMMON

@c EN
@var{Required-slots} determines if the input row is a valid record row
or not.  The structure of @var{required-slots} is as follows:
@c JP
@var{required-slots}は、入力行が有効なレコード行かそうでないかを決めます。
@var{required-slots}の構造は以下のとおりです。
@c COMMON

@example
   <required-slots> : (<spec> ...)
   <spec> : <header-spec> | (<header-spec> <predicate>)
@end example

@c EN
The @code{<header-spec>} compared to the elements of @var{header-slot}
(by @code{equal?}) to figure out which columns to check.  A single
@code{<header-spec>} in @code{<spec>} means that the column shouldn't be
empty for a valid record row.  If @var{<spec>} is a list of
@code{<header-spec>} and @code{<predicate>}, then the value of the
column corresponds to the @var{<header-spec>} is passed to @var{<predicate>}
to determine if it's a valid record row.

If @var{required-slots} is omitted or an empty list, any row with
at least one non-empty column to be included in the tuple.
@c JP
@code{<header-spec>}はどの列の要素をチェックすべきかを指定します。
@var{header-slot}に現れる要素のいずれかと@code{equal?}でなければなりません。
@code{<header-spec>}だけが@code{<spec>}として与えられていた場合は、
その列が空であってはいけない、ということを意味します。
@code{<header-spec>}と@code{<predicate>}が与えられた場合は、
レコード行の該当列の値(文字列)が述語手続き@code{<predicate>}に与えられ、
それが偽を返したらその行は有効でないということになります。
@c COMMON

@c EN
If @var{allow-gap?} is @code{#t}, it keeps reading rows until the end,
skipping invalid rows.  If @var{allow-gap?} is @code{#f} (default), 
it stops reading once it sees an invalid row after headers.
@c JP
@var{allow-gap?}が@code{#t}であった場合、無効な行を飛ばしながら、
入力データは最後まで処理されます。@var{allow-gap?}が@code{#f}であった場合(デフォルト)は、
無効な行が出てきた時点で処理を打ちきります。
@c COMMON

@c EN
Let's see an example.  Suppose we have the following CSV file as
@file{data.csv}.  It has extra rows and columns, as is often seen
in spreadsheet-exported files.
@c JP
例を見てみましょう。次のデータが@file{data.csv}というファイルに書かれているとします。
スプレッドシートからエクスポートされるデータによくあるように、不要な行や列が混ざっています。
@c COMMON

@smallexample
,,,,,,,,
"Exported data",,,,,,,,
,,,,,,,,
,,Year,Country,,Population,GDP,,Note
,,1958,"Land of Lisp",,39994,"551,435,453",,
,,1957,"United States of Formula Translators",,115333,"4,343,225,434",,Estimated
,,1959,"People's Republic of COBOL",,82524,"3,357,551,143",,
,,1970,"Kingdom of Pascal",,3785,,,"GDP missing"
,,,,,,,,
,,1962,"APL Republic",,1545,"342,335,151",,
@end smallexample

@c EN
You can extract tuples of Country, Year, GDP and Population,
as follows:
@c JP
ここから、Country, Year, GDP, Populationの値からなるタプルのリストを
次のとおり取り出せます。
@c COMMON

@smallexample
(use text.csv)
(use gauche.generator)

(call-with-input-file "data.csv" 
  (^p (csv-rows->tuples 
       (generator->list (cute (make-csv-reader #\,) p))
       '("Country" "Year" "GDP" "Population"))))
 @result{}
  (("Land of Lisp" "1958" "551,435,453" "39994")
   ("United States of Formula Translators" "1957" "4,343,225,434" "115333")
   ("People's Republic of COBOL" "1959" "3,357,551,143" "82524")
   ("Kingdom of Pascal" "1970" "" "3785"))
@end smallexample

@c EN
Note that irrelevant rows are skipped, and columns in the results
are ordered as specified in the @var{header-specs}.
@c JP
無関係な行は無視されており、また結果の列は@var{header-specs}に渡した順序に
整列されていることに注目してください。
@c COMMON

@c EN
Since there's a gap (empty row) after the ``Kingdom of Pascal'' entry,
@code{csv-rows->tuples} stops processing there by default.  If you want
to include ``APL Republic'', you have to pass @code{:allow-gap? #t}
to @code{csv-rows->tuples}.
@c JP
``Kingdom of Pascal''の列の後にギャップ(空の列)があるため、
@code{csv-rows->tuples}はそこで処理を打ち切っています。
ギャップの後の``APL Republic''まで含めたければ、@code{csv-rows->tuples}に
@code{:allow-gap? #t}を渡してください。
@c COMMON

@c EN
The next example gives @code{:required-slots} option to eliminate
rows with missing some of Year, Country or GDP---thus ``Kingdom of Pascal''
is omitted from the result, while ``APL Republic'' is included
because of @code{:allow-gap?} argument.
(It also checks Year has exactly 4 digits.)
@c JP
次の例では、@code{:required-slots}引数を与えて、
Year、Country、GDPのデータの一つ以上が欠けている行を除外しています。
したがって``Kingdom of Pascal''は結果から除かれます。一方、
@code{:allow-gap?}引数のために``APL Republic''が含まれます。
(この例ではYearが4桁ぴったりの数値であるかどうかもチェックしています。)
@c COMMON

@smallexample
(call-with-input-file "data.csv" 
  (^p (csv-rows->tuples 
       (generator->list (cute (make-csv-reader #\,) p))
       '("Country" "Year" "GDP" "Population")
        :required-slots '(("Year" #/^\d@{4@}$/) "Country" "GDP")
        :allow-gap? #t)))
 @result{}
 (("Land of Lisp" "1958" "551,435,453" "39994")
  ("United States of Formula Translators" "1957" "4,343,225,434" "115333")
  ("People's Republic of COBOL" "1959" "3,357,551,143" "82524")
  ("APL Republic" "1962" "342,335,151" "1545"))
@end smallexample
@end defun

@c EN
The following two procedures are ingredients of 
@code{csv-rows->tuples}:
@c JP
以下の二つの手続きは@code{csv-rows->tuples}の材料です。
@c COMMON


@defun make-csv-header-parser header-specs
@c MOD text.csv
@c EN
Create a procedure that takes a row (a list of strings) and checks if
if it matches the criteria specified by @var{header-specs}.
(See @code{csv-rows->tuples} above about @var{header-specs}.)
If the input satisfies the spec, it returns a permuter vector that maps
the tuple positions to the input column numbers.
Otherwise, it returns @code{#f}.
@c JP
行(文字列のリスト)を受け取り、それが@var{header-specs}で指定される条件に
一致するかどうかを調べます。
(@var{header-specs}については上の@code{csv-rows->tuples}を見てください。)
もし引数が条件を満たしたなら、置換ベクタを返します。
置換ベクタはタプルの位置を入力行の列番号へとマップするもので。
一致しなかった場合は@code{#f}を返します。
@c COMMON

@c EN
The permuter vector is a vector of integers,
where K-th element being I means the K-th item of the tuple should be
taken from I-th column.
@c JP
置換ベクタは整数のベクタです。K番目の要素がIであることは、
タプルのK番目の要素が入力のI番目の列から取られることを示します。
@c COMMON

@c EN
Let's see the example.  Suppose we know that the input contains
the following row as the header row:
@c JP
例を見てみましょう。入力に、以下の形の行がヘッダ行として含まれていることが
わかっているとします。
@c COMMON

@example
(define *input-row*
  '("" "" "Year" "Country" "" "Population" "GDP" "Notes"))
@end example

@c EN
We want to detect that row, but we only needs
Country, Year, GDP and Population columns, in that order.  So we create
a header parser as follows:
@c JP
こういう形の行を見つけたいわけですが、取り出すデータとしては、
@code{Country}、@code{Year}、@code{GDP}、@code{Population}だけが
この順で必要であるとします。この場合、ヘッダパーザを
次のとおり構成できます。
@c COMMON

@example
(define header-parser
  (make-csv-header-parser '("Country" "Year" "GDP" "Population")))
@end example

@c EN
Applying this header parser to the input data returns the permuter vector:
@c JP
このヘッダパーザを想定される入力行に適用すれば、置換ベクタが返ってきます:
@c COMMON

@example
(header-parser *input-row*)
 @result{} #(3 2 6 5)
@end example

@c EN
It means, the first item of tuple (Country) is in the 3rd column of the input,
the second item of tuple (Year) is in the 2nd column of the input,
and so on.  This permuter vector can be used to parse record rows to
get tuples.
@c JP
返り値の意味は、タプルの第0要素(@code{Country})は入力の第3列にあり、
タプルの第1要素(@code{Year})は入力の第2列にある、といった具合です。
置換ベクタはレコード行をパーズしてタプルを生成するのに使えます。
@c COMMON
@end defun

@defun make-csv-record-parser header-slots permuter :optional required-slots
@c MOD text.csv
@c EN
Create a procedure that converts one input row into a tuple.

@var{Permuter} is the vector returned by @code{make-csv-header-parser}.

See @code{cvs-rows->tuples} above for @var{header-slots} and
@var{required-slots} arguments.
@c JP
入力の1行をタプルへと変換する手続きを作って返します。

@var{permuter}は@code{make-csv-header-parser}が返す置換ベクタです。

@var{header-slots}及び@var{required-slots}引数については
上の@code{cvs-rows->tuples}を見てください。
@c COMMON
@end defun


@c ----------------------------------------------------------------------
@node Calculate difference of text streams, EDN parsing and construction, CSV tables, Library modules - Utilities
@section @code{text.diff} - Calculate difference of text streams
@c NODE テキストストリームの相違点を計算する, @code{text.diff} - テキストストリームの相違点を計算する

@deftp {Module} text.diff
@mdindex text.diff
@c EN
This module calculates the difference of two text streams or strings,
using @code{util.lcs} (@pxref{The longest common subsequence}).
@c JP
このモジュールでは、@code{util.lcs} (@ref{The longest common subsequence}参照)を
使って、2つのテキストストリーム、あるいは2つの文字列の相違点を計算します。
@c COMMON
@end deftp

@defun diff src-a src-b :key reader eq-fn
@c MOD text.diff
@c EN
Generates an "edit list" from text sources @var{src-a} and @var{src-b}.

Each of text sources, @var{src-a} and @var{src-b}, can be either an input
port or a string.  If it is a string, it is converted to a string input
port internally.  Then, the text streams from both sources are converted
to sequences by calling @var{reader} repeatedly on them; the default
of @var{reader} is @code{read-line}, and those sequences are
passed to @code{lcs-edit-list} to calculate the edit list.
The equality function @var{eq-fn} is also passed to @code{lcs-edit-list}.

An edit list is a set of commands that turn the text sequence
from @code{src-a} to the one from @code{src-b}.
See the description of @code{lcs-edit-list} for
the detailed explanation of the edit list.
@c JP
テキストソース@var{src-a}と@var{src-b}から``編集リスト''を生成します。

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

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

@example
(diff "a\nb\nc\nd\n" "b\ne\nd\nf\n")
@result{}
  (((- 0 "a"))
   ((- 2 "c") (+ 1 "e"))
   ((+ 3 "f")))
@end example
@end defun

@defun diff-report src-a src-b :key reader eq-fn writer
@c MOD text.diff
@c EN
A convenience procedure to take the diff of two text sources
and display the result nicely.  This procedure calls @code{lcs-fold}
to calculate the difference of two text sources.  The meanings of
@var{src-a}, @var{src-b}, @var{reader} and @var{eq-fn} are the
same as @code{diff}'s.
@c JP
2つのテキストソースのdiffをとって、その結果をきれいに表示するための
簡易手続きです。この手続きは、2つのテキストソースの相違点を計算する
ために@code{lcs-fold}を呼び出します。@var{src-a}、@var{src-b}、
@var{reader}、@var{eq-fn}の意味は、@code{diff}の場合と同じです。
@c COMMON

@c EN
@var{Writer} is a procedure that takes two arguments, the text element
and a type, which is either a symbol @code{+},
a symbol @code{-}, or @code{#f}.   If the text element is only
in @var{src-a}, @var{writer} is called with the element and
@code{-}.  If the text element is only in @var{src-b},
it is called with the element and @code{+}.  If the text element
is in both sources, it is called with the element and
@code{#f}.   The default procedure of @var{writer} prints
the passed text element to the current output port
in unified-diff-like format:
@c JP
@var{writer}は2つの引数、テキスト要素とタイプ(シンボル@code{+}、
シンボル@code{-}、あるいは@code{#f}のいずれか)を取る手続きです。
テキスト要素が@var{src-a}にしかない場合は、@var{writer}がそのテキスト要素と
@code{-}とともに呼ばれます。テキスト要素が@var{src-b}にしかない場合は、
@var{writer}はそのテキスト要素と@code{+}とともに呼ばれます。
テキスト要素が両方のソースにある場合は、@var{writer}はそのテキスト要素と
@code{#f}とともに呼ばれます。@var{writer}のデフォルトの手続きは、
渡されたテキスト要素を現在の出力ポートにユニファイドdiffのようなフォーマットで
出力します。
@c COMMON
@example
(diff-report "a\nb\nc\nd\n" "b\ne\nd\nf\n")
@end example
displays:
@example
- a
  b
- c
+ e
  d
+ f
@end example
@end defun

@c ----------------------------------------------------------------------
@node EDN parsing and construction, Running external editor, Calculate difference of text streams, Library modules - Utilities
@section @code{text.edn} - EDN parsing and construction
@c NODE EDNのパーズと構築, @code{text.edn} - EDNのパーズと構築

@deftp {Module} text.edn
@mdindex text.edn
@c EN
EDN (Extensible Data Notation) is a subset of Clojure literals
for data exchange.  This module provides utilities to read and write EDN
format.  See @url{https://github.com/edn-format/edn} for the details of EDN.
@c JP
EDN (Extensible Data Notation)はデータ交換用に定められた、
Clojureのリテラル構文のサブセットです。このモジュールはEDNの読み書きをする
ユーティリティを提供します。EDNの詳細については
@url{https://github.com/edn-format/edn}を参照してください。
@c COMMON

@multitable @columnfractions .2 .2 .6
@item EDN @tab Gauche @tab Note
@item @code{true} @tab @code{#t} @tab
@item @code{false} @tab @code{#f} @tab
@item @code{nil} @tab @code{nil}
@c EN
@tab Clojure's nil is not a symbol but a special value; since Clojure
can't have a symbol named nil, we can map it to Gauche's symbol @code{nil}.
@c JP
@tab Clojureのnilはシンボルではなく特殊な値ですが、
Clojureにはnilというシンボルは存在できないので、
Gaucheのシンボル@code{nil}に対応させています。
@c COMMON
@item number @tab @code{<real>}
@c EN
@tab Integers and floating point numbers.
The @code{N} and @code{M} suffixes in Clojure are ignored.
@c JP
@tab 整数と浮動小数点数。
Clojureの@code{N}と@code{M}サフィックスは無視されます。
@c COMMON
@item symbol @tab @code{<symbol>}
@c EN
@tab Clojure's symbol name has some restrictions, so not all Gauche symbols
map to EDN symbols.
Clojure's namespace-prefixed symbol, e.g. @code{foo/bar} simply maps to
Gauche's symbol @code{foo/bar}; we provide utility procedure to extract
namespace and basename parts.
@c JP
@tab Clojureのシンボル名には制約があるので、
全てのGaucheのシンボルがEDNシンボルとして使えるわけではありません。
Clojureの名前空間つきシンボル(例: @code{foo/bar}) はGauche側では
単に@code{foo/bar}という名前を持つシンボルの扱いになります。
この名前から名前空間とシンボル名を取り出すユーティリティが提供されます。
@c COMMON
@item keyword @tab @code{<keyword>}
@c EN
@tab Clojure has keywords distinct from symbols.  They are mapped to Gauche's
keywords (which is a subtype of symbols).
Gauche's keywords can also be symbols, but
no Clojure symbols begin with @code{:} so there won't be a conflict.
@c JP
@tab Clojureはキーワードとシンボルを別の型にしています。
ClojureキーワードはGaucheキーワード(シンボルのサブタイプ)に対応します。
Clojureのシンボルは@code{:}で始まることはないので、混同が起きることはありません。
@c COMMON
@item list @tab @code{<list>}
@c EN
@tab Clojure lists are Gauche lists.  Note that Clojure doesn't allow
improper lists.
@c JP
@tab ClojureのリストはGaucheのリストになります。
Clojureにはドットリスト(improper list)が無いことに注意してください。
@c COMMON
@item vector @tab @code{<vector>}
@c EN
@tab Clojure vectors are Gauche vectors.
@c JP
@tab ClojureのベクタはGaucheのベクタになります。
@c COMMON
@item map @tab @code{<hash-table>}
@c EN
@tab Clojure's map becomes Gauche's hashtable with @code{edn-comparator}
for hashing and comparison.
@c JP
@tab Clojureのマップは、Gaucheでは@code{edn-comparator}をハッシュ関数と比較に
使うハッシュテーブルになります。
@c COMMON
@item set @tab @code{<set>}
@c EN
@tab Clojure's set becomes Gauche's set with @code{edn-comparator}
for comparison.  @xref{R7RS sets} for interface of sets.
@c JP
@tab Clojureのセットは、Gaucheでは@code{edn-comparator}を比較に使う
@code{<set>}オブジェクトになります。@code{<set>}については@xref{R7RS sets}参照。
@c COMMON
@item tagged object @tab @code{<edn-object>}
@c EN
@tab Tagged objects are mapped to @code{<edn-object>} by default. 
You can customize the parser/writer to map tagged objects with a
specific tag to a specific Gauche objects.
@c JP
@tab タグつきオブジェクトはデフォルトで@code{<edn-object>}のインスタンスになります。
タグつくオブジェクトの解釈をカスタマイズして、特定のGaucheオブジェクトに結びつけることも
できます。
@c COMMON
@end multitable
@end deftp

@c EN
@subheading Parsing
@c JP
@subheading パーザ
@c COMMON

@deftp {Condition Type} <edn-parse-error>
@c EN
When the parser encounters an error, this condition is thrown.
Inherits @code{<error>}.
@c JP
パーザのエラーはこのコンディションで通知されます。@code{<error>}を継承しています。
@c COMMON
@end deftp

@defun parse-edn :optional iport
@c MOD text.edn
@c EN
Read one EDN representation from the given input port, and returns
Gauche object created from it.  If @var{iport} is omitted,
current input port is assumed.

When the parser encounters unparsable sequence, 
it raises @code{<edn-parse-error>}.

Note that @var{iport} may be read ahead for characters. Suppose
the input consists of @code{abc@{:a b@}}, i.e. a symbol immediately
followed by a map.  The parser need to read @code{@{} to know the
end of the symbol. The read-ahead brace isn't pushed back
to the @var{iport}.  So it would be a problem if you keep reading
more EDN subsequently.   Use @code{parse-edn*} if you want to read
multiple objects.
@c JP
EDN表現を与えられた入力ポートから読み込み、パーズ結果をGaucheオブジェクトとして
返します。@var{iport}が省略された場合は現在の入力ポートが使われます。

パーズが失敗した場合は@code{<edn-parse-error>}が投げられます。

@var{iport}から文字が先読みされる可能性があることに注意してください。
例えば入力が@code{abc@{:a b@}}、つまりシンボルの直後にマップが来ていたとします。
パーザは@code{@{}まで読んでシンボルの終了を知り、シンボル@code{abc}を返しますが、
その時点で読まれていた@code{@{}はポートに戻されないので、
続けて@var{iport}からEDNを読む場合に問題となります。
複数のEDNオブジェクトを読み込む場合は@code{parse-edn*}を使ってください。
@c COMMON
@end defun

@defun parse-edn* :optional iport
@c MOD text.edn
@c EN
Read EDN representations repeatedly from the given input port
and returns a list of them.  If @var{iport} is omitted,
current input port is assumed.

When the parser encounters unparsable sequence, 
it raises @code{<edn-parse-error>}.
@c JP
与えられた入力ポートから、EOFに達するまでEDN表現を読み込み、結果のGaucheオブジェクトの
リストを返します。@var{iport}が省略された場合は現在の入力ポートが使われます。

パーズが失敗した場合は@code{<edn-parse-error>}が投げられます。
@c COMMON
@end defun

@defun parse-edn-string str
@c MOD text.edn
@c EN
A convenience procedure to parse EDN representation in a string @var{str},
and returns the read object.

When the parser encounters unparsable sequence, 
it raises @code{<edn-parse-error>}.
@c JP
EDN表現を文字列から読み込む便利手続きです。

パーズが失敗した場合は@code{<edn-parse-error>}が投げられます。
@c COMMON

@example
(parse-edn-string "[1 2 (3 4) @{:a 5@}]")
 @result{} #(1 2 (3 4) #<hash-table general 0x1f05780>)
@end example
@end defun

@c EN
@subheading Constructing
@c JP
@subheading 構築
@c COMMON

@defun construct-edn obj :optional oport
@c MOD text.edn
@c EN
Write out an EDN representation of object @var{obj}
to the output port @var{oport}.  If @var{oport} is omitted,
current output port is assumed.

If @var{obj} contains an object that doesn't have a defined
EDN representation, a generic function @var{edn-write} is called
on it.  See Customization heading below.  If no method is defined for
the object, an error is signaled.
@c JP
オブジェクト@var{obj}のEDN表現を出力ポート@var{oport}に書き出します。
@var{oport}が省略された場合は現在の出力ポートが使われます。

@var{obj}中にEDNで表現できないオブジェクトがあった場合、
ジェネリック関数@var{edn-write}が呼ばれます。下のカスタマイズの項を参照してください。
適切なメソッドが定義されていなけばエラーが投げられます。
@c COMMON
@end defun

@defun construct-edn-string obj
@c MOD text.edn
@c EN
Returns an EDN representation of @var{obj} in a string.

If @var{obj} contains an object that doesn't have a defined
EDN representation, a generic function @var{edn-write} is called
on it.  See Customization heading below.  If no method is defined for
the object, an error is signaled.
@c JP
@var{obj}のEDN表現を文字列で返します。

@var{obj}中にEDNで表現できないオブジェクトがあった場合、
ジェネリック関数@var{edn-write}が呼ばれます。下のカスタマイズの項を参照してください。
適切なメソッドが定義されていなけばエラーが投げられます。
@c COMMON

@example
@end example
(construct-edn-string '#(1 2 "abc"))
 @result{} "[1 2 \"abc\"]"
@end defun

@c EN
@subheading Utilities
@c JP
@subheading ユーティリティ
@c COMMON

@defun edn-equal? a b
@c MOD text.edn
@c EN
Test equality of two objects that are read from EDN representation.
@c JP
EDN表現から読まれた二つのオブジェクトが、EDNのセマンティクスで等しいかどうかを調べます。
@c COMMON
@end defun

@defvar edn-comparator
@c MOD text.edn
@c EN
A comparator that uses @code{edn-equal?} for the equality predicate.
Corresponding has function is also included.
EDN maps and sets become Gauche hash-tables and sets with this comparator.
@c JP
@code{edn-equal?}で等価性を判定する比較器です。ハッシュ関数も含まれます。
EDNのマップとセットは、この比較器を使うGaucheのハッシュテーブルとセットになります。
@c COMMON
@end defvar

@defun edn-map key value @dots{}
@defunx edn-set item @dots{}
@c MOD text.edn
@c EN
Convenience procedures to create hash-tables and sets compatible
for EDN.
@c JP
EDNに使えるハッシュテーブルとセットを構築する便利手続きです。
@c COMMON
@end defun

@deftp {Class} <edn-object>
@clindex edn-object
@c MOD text.edn
@c EN
EDN tagged object becomes an instance of this class by default.
The instance has the following slots, both are immutable:
@c JP
EDNのタグつきオブジェクトは、デフォルトではこの暮らすのインスタンスになります。
以下のスロットがあります。どちらも変更不可です。
@c COMMON

@defivar <edn-object> tag
@c EN
Object's tag.  A symbol.
@c JP
シンボル。オブジェクトのタグです。
@c COMMON
@end defivar

@defivar <edn-object> payload
@c EN
Object's payload.  Can be any object that can be representable in EDN.
@c JP
オブジェクトの内容です。EDNで表現可能なオブジェクト。
@c COMMON
@end defivar

@c EN
For example, when you read @code{#myobject @{:a 1 :b 2@}},
the tag is @code{myobject} and the payload is a hashtable
containing mapping @code{@{:a 1 :b 2@}}.
@c JP
例えば、@code{#myobject @{:a 1 :b 2@}}を読んだ場合、
タグは@code{myobject}、内容は@code{@{:a 1 :b 2@}}を読んだ結果のハッシュテーブルに
なります。
@c COMMON
@end deftp

@defun make-edn-object tag payload
@c MOD text.edn
@c EN
Returns a new @code{<edn-object>} instance.
Note: Arguments are not checked.  It's caller's responsibility to
pass valid arguments to guarantee it's serializable as EDN.
@c JP
新たな@code{<edn-object>}のインスタンスを作って返します。
引数がEDN表現可能かどうかのチェックはされません。
呼び出し側が有効な引数を渡す必要があります。
@c COMMON
@end defun

@defun edn-object? obj
@c MOD text.edn
@c EN
Returns @code{#t} iff @var{obj} is an instance of @code{<edn-object>}.
@c JP
@var{obj}が@code{<edn-object>}のインスタンスなら@code{#t}を、そうでなければ
@code{#f}を返します。
@c COMMON
@end defun

@defun edn-object-tag edn-object
@defunx edn-object-payload edn-object
@c MOD text.edn
@c EN
Returns the tag and the payload of @var{edn-object}, respectively.
@c JP
@var{edn-object}のタグと内容をそれぞれ返します。
@c COMMON
@end defun

@defun edn-symbol-prefix symbol
@defunx edn-symbol-basename symbol
@c MOD text.edn
@c EN
Return prefix and basename part of the symbol, respectively.
@c JP
シンボルの、プリフィクスとベース名をそれぞれ返します。
@c COMMON

@example
(edn-symbol-prefix 'foo/bar) @result{} foo
(edn-symbol-basename 'foo/bar) @result{} bar

(edn-symbol-prefix 'bar) @result{} #f
(edn-symbol-basename 'bar) @result{} bar
@end example
@end defun

@defun edn-valid-symbol-name? str
@c MOD text.edn
@c EN
Returns @code{#t} iff a string @var{str} can be a valid Clojure symbol name.
It may have namespace prefix.
@c JP
文字列@var{str}がClojureのシンボル名として有効なら@code{#t}を、そうでなければ
@code{#f}を返します。@var{str}には名前空間を含めることもできます。
@c COMMON
@end defun

@c EN
@subheading Customization
@c JP
@subheading カスタマイズ
@c COMMON

@c EN
You can map EDN tagged objects to other Gauche objects.
@c JP
EDNのタグつきオブジェクトを、他のGaucheオブジェクトへとマップすることが出来ます。
@c COMMON

@defun register-edn-object-handler! tag handler
@c MOD text.edn
@c EN
@var{Tag} is a symbol, and @var{handler} is @code{#f} or a procedure
that takes a tag symbol and a payload object.

@var{Tag} must have a name valid as Clojure symbol, or an error
is signaled.

After the parser reads a tagged object with a symbol @var{tag}
and payload, it calls @var{handler}, and the returned object
becomes the result of the parser, instead of @code{<edn-object>}.
Registering @code{#f} removes the previously registered handler.

This procedure is thread-safe.

The following example makes EDN @code{#u8vector[1 2 3 4]} to be read
as @code{#u8(1 2 3 4)}:
@c JP
@var{tag}はシンボル、@var{handler}は@code{#f}もしくは
タグと内容を引数に取る手続きです。

@var{tag}はClojureのシンボルとして有効な名前でなければなりません。
さもなくばエラーが投げられます。

パーザが@var{tag}をタグに持つタグつきオブジェクトを読んだら、
そのタグと内容を引数にして@var{handler}を呼び出し、返り値を
パーズ結果とします。@var{handler}に@code{#f}を渡した場合は
既に登録されたハンドラを(もしあれば)削除します。

この手続きはスレッドセーフです。

以下の例はEDNの@code{#u8vector[1 2 3 4]}を
@code{#u8(1 2 3 4)}として読み込みます。
@c COMMON

@example
(register-edn-object-handler! 'u8vector 
                              (^[tag vec] (vector->u8vector vec)))
@end example
@end defun

@defun edn-object-handler tag
@c MOD text.edn
@c EN
Returns a handler registered with a symbol @var{tag}.  If a handler
is not registered for @var{tag}, @code{#f} is returned.
This procedure is thread-safe.
@c JP
@var{tag}に登録されたハンドラを返します。ハンドラが登録されていなければ@code{#f}を返します。
この手続きはスレッドセーフです。
@c COMMON
@end defun

@deffn {Generic Function} edn-write obj
@c MOD text.edn
@c EN
Write EDN representation of @var{obj} to the current output port.
The @code{construct-edn} procedure calls this internally.

To write out a Gauche object as EDN tagged object, define a method to
this generic function.   In the method you can call @code{edn-write}
recursively to write out components of the object.

The following example writes @code{#u8(1 2 3 4)} as
EDN @code{#u8vector[1 2 3 4]}:
@c JP
@var{obj}のEDN表現を現在の出力ポートに書き出します。
@code{construct-edn}は内部的にこれを呼んでいます。

GaucheオブジェクトをEDNタグつきオブジェクトとして書き出したい場合に、
このジェネリック関数にメソッドを定義します。メソッド中で、オブジェクトの要素を
再帰的に書き出す場合はそれぞれに@code{edn-write}を呼び出してください。

以下の例は、@code{#u8(1 2 3 4)}をEDNの@code{#u8vector[1 2 3 4]}として
書き出します。
@c COMMON

@example
(define-method edn-write ((x <u8vector>))
  (display "#u8vector")
  (edn-write (u8vector->vector x)))
@end example
@end deffn

@c ----------------------------------------------------------------------
@node Running external editor, Gap buffer, EDN parsing and construction, Library modules - Utilities
@section @code{text.external-editor} - Running external editor
@c NODE 外部エディタの起動, @code{text.external-editor} - 外部エディタの起動

@deftp {Module} text.external-editor
@mdindex text.external-editor
A convenience module to invoke external editor program.
This is mainly to be used from REPL, but can be useful for
other purposes.
@end deftp

@defun ed path-or-proc :key editor load-after
@c MOD text.external-editor
Starts an external editor.  The editor program path is determined
in the following order:

@itemize @bullet
@item
The @var{editor} keyword argument, if it's a string.
@item
The value of @code{*editor*} in the user module, if defined.
@item
The value of the environment variable @code{GAUCHE_EDITOR}.
@item
The value of the environment variable @code{EDITOR}.
@item
If none works, the behavior depends on the value of :editor keyword
argument:
@table @code
@item #f
Just returns @code{#f}.
@item error
Throws an error.
@item ask
Asks the user.
@item message
Prints message and returns @code{#f}.
@end table
@end itemize

Returns @code{#t} for normal termination.

The editor program may be called in one of the following way:

@example
EDITOR filename
EDITOR +lineno filename
@end example

The latter expects to locate the cursor on the specified line number
in the filename.

The file to open is determined by a generic function @code{ed-pick-file}.
It should return @code{(@var{filename} @var{lineno})},
or @code{#f} to indicate that it couldn't determine the file to edit.

The @var{load-after} argument controls whether the file is loaded
into the process after the file is modified.  It must be one of
the following values:
@table @code
@item #t
Load the file once editor exits and the file is modified.
@item #f
Do not load the file.
@item ask
Ask the user if the file should be loaded or not.
@end table

NB: Common Lisp's @code{ed} can be invoked without argument.  For our usage,
though, that feature doesn't seem too useful---it's more likely that
repl IS inside an editor so we only need to open a specific file in
a buffer.  Emacsclient requires filename, so it further complicates things.
For now we just require one argument.
@end defun

@defun ed-string string :key editor
@c MOD text.external-editor
Invoke an external editor (as described in @code{ed}) with @var{string}
being the initial content.  Once editor exits,
returns the edited content as a string.
@end defun

@deffn {Generic Function} ed-pick-file obj
@c MOD text.external-editor
Determine what to edit.  It must return a list of
filename and line number, or @code{#f} if it can't find appropriate file to
edit.

Methos for strings, procedures and @code{<top>} are already defined.
If @var{obj} is a string, it is taken as a filename.
If @var{obj} is a procedure and its source location is available,
the source file and the location is returned.
Otherwise, @code{#f} is returned.
@end deffn

@c ----------------------------------------------------------------------
@node Gap buffer, Localized messages, Running external editor, Library modules - Utilities
@section @code{text.gap-buffer} - Gap buffer
@c NODE ギャップバッファ, @code{text.gap-buffer} - ギャップバッファ

@deftp {Module} text.gap-buffer
@mdindex text.gap-buffer
This module provides a gap buffer, a data structure useful for
editable text.

A gap buffer is a vector of characters with a ``cursor'', where
you can insert or delete a character in O(1) time.  Most of
the editing API operate on the current cursor position.
@end deftp

@defun make-gap-buffer :key initial-capacity
@c MOD text.gap-buffer
Creates a fresh gap buffer and returns it.  The initial content
is emtpy.

The keyword argument
@var{initial-capacity} must be a positive exact integer if given,
and specifies the initial capacity of the buffer.  The buffer is
automatically extended if necessary, so the argument is only a 
hint; if you know you'll insert a long string, for example,
you can create a buffer that's large enough to hold it to avoid
reallocation overhead.
@end defun

@defun string->gap-buffer string :optional pos whence start end
@c MOD text.gap-buffer
Creates a gap buffer large enough to contain the given @var{string},
and returns it.

The initial cursor position is set at the end of the string by default.
The @var{pos} and @var{whence} argument can set the initial
cursor position.  The @var{whence} argument must be either a symbol
@code{beginning} or a symbol @code{end}, and @var{pos} must be an exact
integer offset from the whence.  For example, @var{pos} = 10 and 
@var{whence} = @code{beginning} sets the cursor at the 10th character
of the string from the beginning, and @var{pos} = -1 and @var{whence} = 
@code{end} sets the cursor position at one character before the end
of the string.  If the combination of @var{pos} and @var{whence}
points the outside of the string, an error is signaled.

The optional @var{start} and @var{end} trims the input string before 
creating the gap buffer.
@end defun

@defun gap-buffer? obj
@c MOD text.gap-buffer
Returns @code{#t} iff @var{obj} is a gap buffer.
@end defun

@defun gap-buffer-copy gbuf
@c MOD text.gap-buffer
Returns a fresh copy of a gap buffer @var{gbuf}, with the same content
and cursor position.
@end defun

@defun gap-buffer->string gbuf :optional start end
@defunx gap-buffer->generator gbuf :optional start end
@c MOD text.gap-buffer
Retrieve the content of a gap buffer @var{gbuf} as a string or
a generator of characters, respectively.  The optional @var{start} and
@var{end} arguments are nonnegative exact integers of character index
in the content of the buffer, and limits the output within the specified
range.

If you modify the content of gap buffer before the returned generator
is exhausted, consistent behavior isn't guaranteed.
@end defun

@defun gap-buffer-pos gbuf
@c MOD text.gap-buffer
Returns the current cursor position of @var{gbuf}, in a nonnegative
exact integer.
@end defun

@defun gap-buffer-capacity gbuf
@c MOD text.gap-buffer
Returns the currently allocated storage size of @var{gbuf}.
If you insert more characters into @var{gbuf}, the storage is automatically
expanded.
@end defun

@defun gap-buffer-content-length gbuf
@c MOD text.gap-buffer
Returns the length of current content of @var{gbuf},
in the number of characters.
@end defun

@defun gap-buffer-gap-at? gbuf whence
@c MOD text.gap-buffer
The @var{whence} argument must be either a symbol @code{beginning}
or a symbol @code{end}.  Returns @code{#t} iff the current cursor position
of @var{gbuf} is at the beginning or at the end, respectively.
@end defun

@defun gap-buffer-ref gbuf index :optional fallback
@c MOD text.gap-buffer
Returns @var{index}-th character of @var{gbuf}.  If @var{index} is
out of range, @var{fallback} is returned if given, or an error
is raised.
@end defun

@defun gap-buffer-set! gbuf index char
@c MOD text.gap-buffer
Replaces @var{index}-th character of @var{gbuf} with @var{char}.
If @var{index} is out of range, an error is signaled.
@end defun

@defun gap-buffer-move! gbuf pos :optional whence
@c MOD text.gap-buffer
Moves the cursor position of @var{gbuf} to a position @var{pos}, which
must be an exact integer.  The position @var{pos} is relative to
@var{whence}, which must be either one of the symbols @code{beginning},
@var{current} or @code{end}.
@end defun

@defun gap-buffer-insert! gbuf content
@c MOD text.gap-buffer
Inserts @var{content}, which must be a character or a string,
at the current cursor position of @var{gbuf}.
The current cursor position is moved to the end of the inserted content.
@end defun

@defun gap-buffer-delete! gbuf size
@c MOD text.gap-buffer
Delets @var{size} characters from the current cursor position
of @var{gbuf}.  It is an error if @var{size} overruns.
@end defun

@defun gap-buffer-clear! gbuf
@c MOD text.gap-buffer
Makes @var{gbuf} empty.
@end defun

@defun gap-buffer-replace! gbuf size content
@c MOD text.gap-buffer
This is a combination of @code{(gap-buffer-delete! gbuf size)} and
@code{(gap-buffer-insert! gbuf content)}. 
The @var{size} argument must be a nonnegative exact integer,
and the @var{content} argument must be either a string or a character.
@end defun

@defun gap-buffer-edit! gbuf edit-command
@c MOD text.gap-buffer
This is a convenience procedure to ``replay'' editing of the gap buffer
@var{gbuf}.  The @var{edit-command} argument must be either one of the
following:

@table @code
@item (i @var{pos} @var{string})
Insert @var{string} at a position @var{pos}.
@item (d @var{pos} @var{length})
Delete @var{length} characters from a position @var{pos}.
@item (c @var{pos} @var{length} @var{string})
Change: Delets @var{length} characters from a position @var{pos},
then insert @var{string}.
@end table

Here, @var{pos} must be a nonnegative exact integer specifying the
position in the gap buffer.

One of the appliations of this procedure is to handle undo/redo list.
@end defun


@c ----------------------------------------------------------------------
@node Localized messages, Simple HTML document construction, Gap buffer, Library modules - Utilities
@section @code{text.gettext} - Localized messages
@c NODE 地域化メッセージ, @code{text.gettext} - 地域化メッセージ

@deftp {Module} text.gettext
@mdindex text.gettext
@c EN
This module provides utilities to deal with localized messages.
The API is compatible to GNU's gettext, and the messages
are read from @file{*.po} and @file{*.mo} files,
so that you can use the GNU gettext
toolchain to prepare localized messages.
However, the code is written from scratch by Alex Shinn and
doesn't depend on GNU's gettext library.
@c JP
このモジュールは地域化メッセージを扱うユーティリティを提供します。
API は GNU の gettext と互換性があり、メッセージは @file{*.po} および
@file{*.mo} ファイルから読み込まれます。それゆえ、GNU の gettext toolchain
をつかって地域化メッセージを準備することができます。しかし、このコードは
Alex Shinn によってスクラッチから書き起こされたものであり、GNU の
gettext ライブラリには依存していません。
@c COMMON

@c EN
This implementation extends GNU's gettext API in the following ways:
@itemize @bullet
@item
It can read from multiple message files in cascaded way,
allowing applications to share a part of message files.
@item
It supports multiple locale/domain simultaneously.
@end itemize
@c JP
この実装は GNU の gettext API を以下のように拡張したものです。
@itemize @bullet
@item
複数のメッセージファイルから、カスケードされた方法で読み込むことができます。
これにより、アプリケーションはメッセージファイルの部分を共有できます。
@item
複数のロケール/ドメインを同時に扱えます。
@end itemize
@c COMMON

@c EN
SRFI-29 (@pxref{Localization}) provides another means of message
localization.  A portable program may wish to use srfi-29, but
generally @code{text.gettext} is recommended in Gauche scripts
because of its flexibility and compatibility to existing message files.
@c JP
SRFI-29 (@ref{Localization}参照) はこれとは別のメッセージの地域化
機構を提供しています。ポータブルなプログラムでは、SRFI-29 の方がよいこと
もありますが、一般には、Gauche スクリプトでは、@code{text.gettext} の
方を推奨します。それは、既存のメッセージファイルとの互換性と柔軟性の
ためです。
@c COMMON
@end deftp

@c EN
@subheading Gettext-compatible API
@c JP
@subheading gettext-互換の API
@c COMMON

@defun textdomain domain-name :optional locale dirs cdir cached? lookup-cached?
@c MOD text.gettext
@c EN
Sets up the default domain and other parameters for
the application.  The setting affects to the following @code{gettext}
call.

@var{Domain} is a string or list of strings specifying the domain
(name of @file{.mo} or @file{.po} files) as in C gettext.
You can pass @code{#f} as @var{domain-name} just to get the default
domain accessor procedure.
You can alo pass multiple domains to @var{domain-name}.
@c JP
アプリケーション用に、デフォルトのドメインとそのほかのパラメータを
設定します。この設定は、以降の @code{gettext} の呼出しに影響を与えます。

@var{domain} は文字列または文字列のリストで、ドメイン(@file{.mo} あるいは
@file{.po} ファイル名)を C の gettext と同じように指定します。
@code{#f} を @var{domain-name} として渡すと、デフォルトのドメインアクセサ
手続きが得られます。また、複数のドメインを @var{domain-name}にあたえる
ことができます。
@c COMMON
@example
(textdomain '("myapp" "gimp"))  ; search 1st myapp, then gimp
(gettext "/File/Close")         ; "Close" from gimp unless overridden
@end example

@c EN
@var{Locale} is a string or list of strings in the standard Unix format of
@code{LANG[_REGION][.ENCODING]}.  You can also pass a list of locales
to specify fallbacks.
@c JP
@var{locale} は文字列または文字列のリストで、標準的なUnixのフォーマット
@code{LANG[_REGION][.ENCODING]} です。フォールバックを指定するロケール
のリストを渡すこともできます。
@c COMMON

@example
(textdomain "myapp" '("ru" "uk"))  ; search 1st Russian then Ukranian,
(gettext "Hello, World!")          ; which are somewhat similar
@end example

@c EN
@var{Dirs} is the search path of directories which should hold the
@file{LOCALE/CDIR/} directories which contain the actual message catalogs.
This is always appended with the system default, e.g.
@file{"/usr/share/locale"}, and may also inherit from the
@code{GETTEXT_PATH} colon-delimited environment variable.

@var{Cdir} is the category directory, defaulting to either the
@code{LC_CATEGORY}
environment variable or the appropriate system default
(e.g. @code{LC_MESSAGES}).  You generally won't need this.

@var{Cached?}
means to cache individual messages, and defaults to @code{#t}.

@var{Lookup-cached?}
means to cache the lookup dispatch generated by these
parameters, and defaults to @code{#t}.

@code{Textdomain} just passes these parameters to the internal
@code{make-gettext},
and binds the result to the global dispatch used by @code{gettext}.
You may build these closures manually for convenience in using multiple
separate domains or locales at once (useful for server environments).
See the description of @code{make-gettext} below.

@code{Textdomain} returns an @emph{accessor procedure} which
packages information of the domain.  See @code{make-gettext} below
for the details.
@c JP
@var{dirs} は実際のメッセージカタログを含む @file{LOCALE/CDIR/}
ディレクトリのサーチパスです。これは常にシステムのデフォルト(たとえば、
@file{"/usr/share/locale"})に追加されます。そして、コロンで区切られた
@code{GETTEXT_PATH} 環境変数を継承します。

@var{cdir} はカテゴリーディレクトリで、既定値を @code{LC_CATEGORY}
環境変数または、適当なシステム既定値(たとえば @code{LC_MESSAGES})に
設定します。一般にはこれを指定する必要はありません。

@var{cached?} は個別のメッセージをキャッシュするかを意味し、デフォルトは
@code{#t} です。

@var{lookup-cached?}
は、これらのパラメータで生成されるディスパッチをキャッシュするかどうか
を意味し、デフォルトは @code{#t} です。

@code{textdomain} はこれらのパラメータを内部の @code{make-gettext} に
渡し、その結果を、@code{gettext} で使われるグローバルなディスパッチに
束縛します。これらのクロージャを複数の別々のドメインやロケールを一度に
扱うのに便利なように、手で構築することができます。(これらは
サーバ環境で便利です。) 後述の @code{make-gettext} を参照してください。

@code{textdomain} はそのドメインの情報をもつ @emph{アクセサ手続き}を
返します。詳細については、後述の @code{make-gettext} を参照してください。
@c COMMON
@end defun

@defun gettext msg-id
@c MOD text.gettext
@c EN
Returns a translated message of @var{msg-id}.  If there's no
translated message, @var{msg-id} itself is returned.
@c JP
@var{msg-id} の翻訳されたメッセージを返します。もし、翻訳された
メッセージがなければ、@var{msg-id} それ自身を返します。
@c COMMON
@end defun

@defun ngettext msg-id :optional msg-id2 num
@c MOD text.gettext
@c EN
Similar to @var{gettext}, but it can be used to handle
plural forms.
Pass a singular form to @var{msg-id}, and plural form to
@code{msg-id2}.  The @var{num} argument is used to determine
the plural form.  If no message catalog is found, @var{msg-id}
is returned when @var{num} is 1, and @var{msg-id2} otherwise.
@c JP
@var{gettext}と似ていますが、複数形を処理するのに使うことが
できます。単数形のメッセージを @var{msg-id} へ、複数形のメッセージを
@code{msg-id2} に渡します。@var{num} 引数は、複数形を決定
するのに使われます。もし、メッセージカタログが見つからなければ、
@var{num} が 1 のときは、@var{msg-id} が返り、そうでなければ、
@var{msg-id2} が返ります。
@c COMMON
@end defun

@defun bindtextdomain domain dirs
@c MOD text.gettext
@c EN
Sets the search path of domain @var{domain} to @var{dirs}, which
may be just a single directory name or a list of directory names.
@c JP
ドメイン @var{domain} のサーチパスを @var{dirs} に設定します。
単一のディレクトリ名であったり、ディレクトリのリストであったりします。
@c COMMON
@end defun

@defun dgettext domain msg-id
@defunx dcgettext domain msg-id locale
@c MOD text.gettext
@c EN
Returns a translated message of @var{msg-id} in @var{domain}.
@code{Dcgettext} takes @var{locale} as well.
@c JP
@var{domain} 中の @var{msg-id} の翻訳されたメッセージを返します。
@code{dcgettext} は @var{locale} も引数としてとります。
@c COMMON
@end defun

@c EN
@subheading Low-level flexible API
@c JP
@subheading 低水準の柔軟な API
@c COMMON

@c EN
The following procedure is more flexible interface, on top of which
the gettext-compatible APIs are written.
@c JP
以下の手続きはより柔軟性のあるインタフェースで、この上で、gettext-互換の
API が書かれています。
@c COMMON

@defun make-gettext :optional domain locale dirs gettext-cached? lookup-cached?
@c MOD text.gettext
@c EN
Creates and returns an @emph{accessor procedure}, which encapsulates
methods to retrieve localized messages.

The meaning of arguments are the same as @code{textdomain} above.
Indeed, @code{textdomain} just calls @code{make-gettext}, and later
it binds the result to the global parameter.   If you wish to have
multiple independent domains within a single program, you can
call @code{make-gettext} directly and manage the created
accessor procedure by yourself.
@c JP
@emph{アクセサ手続き} を生成して返します。返された手続きは、
地域化されたメッセージを検索するメソッドをカプセル化しています。

引数の意味は上述の @code{textdomain} と同じです。
実際は、@code{textdomain} は @code{make-gettext} を呼び、その後、
それは、結果をこのグローバルパラメータに束縛します。@code{make-gettext}
を直接呼んで、自分自身で、アクセサ手続きを管理することもできます。
@c COMMON

@example
(define my-gettext (make-gettext "myapp"))
(define _ (my-gettext 'getter))
(_ "Hello, World!")
@end example
@end defun

@c ----------------------------------------------------------------------
@node Simple HTML document construction, Display with pager, Localized messages, Library modules - Utilities
@section @code{text.html-lite} - Simple HTML document construction
@c NODE シンプルなHTMLドキュメントの構築, @code{text.html-lite} - シンプルなHTMLドキュメントの構築

@deftp {Module} text.html-lite
@mdindex text.html-lite
@c EN
Provides procedures to construct an HTML document easily.
For example, you can construct an HTML table by the following code:
@c JP
HTML ドキュメントを簡単に構築するための手続きを提供します。
例えば、以下のコードは HTML のテーブルを構築します。
@c COMMON
@example
(html:table
  (html:tr (html:th "Item No") (html:th "Quantity"))
  (html:tr (html:td 1) (html:td 120))
  (html:tr (html:td 2) (html:td 30))
  (html:tr (html:td 3) (html:td 215)))
@end example
@c EN
See the description of @code{html:@var{element}} below for details.

This module does little check for the constructed html documents,
such as whether the attributes are valid, and whether the content
of the element matches DTD.  It does not provide a feature to parse
the html document neither.  Hence the name `lite'.
@c JP
詳細については、以下の @code{html:@var{element}} の説明を見てください。

このモジュールでは生成されたHTMLドキュメントに関して、
例えばアトリビュートに有効な値が入っているか、要素の内容はDTDを満たしているか、
等のチェックをほとんど行いません。また、HTMLをパーズする関数も提供されません。
それが「lite」の名の由来です。
@c COMMON
@end deftp

@defun html-escape
@defunx html-escape-string string
@c MOD text.html-lite
@c EN
Escapes the ``unsafe'' characters in HTML.  @code{html-escape}
reads input string from the current input port and writes the result
to the current output port.   @code{html-escape-string} takes the
input from @var{string} and returns the result in a string.
@c JP
HTML に含まれる"安全でない"文字をエスケープします。
@code{html-escape} は、現在の入力ポートから文字列を読み込み、
結果を現在の出力ポートへ書き出します。@code{html-escape-string} は
@var{string} を入力とし、文字列を返します。
@c COMMON
@end defun

@defun html-doctype :key type
@c MOD text.html-lite
@c EN
Returns a doctype declaration for an HTML document.
@var{type} can be either one of the followings (default is
@code{:html-4.01-strict}).
@c JP
HTML ドキュメントの文書型宣言を返します。
@var{type} は、以下のいずれかを指定します (デフォルトは@code{:html-4.01-strict}
です)。
@c COMMON
@table @code
@item :html-4.01-strict, :html-4.01, :strict
HTML 4.01 Strict DTD
@item :html-4.01-transitional, :transitional
HTML 4.01 Transitional DTD
@item :html-4.01-frameset, :frameset
HTML 4.01 Frameset DTD
@item :xhtml-1.0-strict, :xhtml-1.0
XHTML 1.0 Strict DTD
@item :xhtml-1.0-transitional
XHTML 1.0 Transitional DTD
@item :xhtml-1.0-frameset
XHTML 1.0 Frameset DTD
@item :xhtml-1.1
XHTML 1.1 DTD
@end table
@end defun

@deftp {Function} html:@var{element} @var{args} @dots{}
@findex html:a
@findex html:abbr
@findex html:acronym
@findex html:address
@findex html:area
@findex html:b
@findex html:base
@findex html:bdo
@findex html:big
@findex html:blockquote
@findex html:body
@findex html:br
@findex html:button
@findex html:caption
@findex html:cite
@findex html:code
@findex html:col
@findex html:colgroup
@findex html:dd
@findex html:del
@findex html:dfn
@findex html:div
@findex html:dl
@findex html:dt
@findex html:em
@findex html:fieldset
@findex html:form
@findex html:frame
@findex html:frameset
@findex html:h1
@findex html:h2
@findex html:h3
@findex html:h4
@findex html:h5
@findex html:h6
@findex html:head
@findex html:hr
@findex html:html
@findex html:i
@findex html:iframe
@findex html:img
@findex html:input
@findex html:ins
@findex html:kbd
@findex html:label
@findex html:legend
@findex html:li
@findex html:link
@findex html:map
@findex html:meta
@findex html:noframes
@findex html:noscript
@findex html:object
@findex html:ol
@findex html:optgroup
@findex html:option
@findex html:p
@findex html:param
@findex html:pre
@findex html:q
@findex html:samp
@findex html:script
@findex html:select
@findex html:small
@findex html:span
@findex html:strong
@findex html:style
@findex html:sub
@findex html:sup
@findex html:table
@findex html:tbody
@findex html:td
@findex html:textarea
@findex html:tfoot
@findex html:th
@findex html:thead
@findex html:title
@findex html:tr
@findex html:tt
@findex html:ul
@findex html:var
@c MOD text.html-lite
@c EN
Construct an HTML element @var{element}.  Right now,
the following elements are provided.
(The elements defined in HTML 4.01 DTD,
@uref{http://www.w3.org/TR/html4/sgml/dtd.html}).
@c JP
@var{element} の HTML 要素を構築します。現時点では以下の要素が
サポートされています。
(HTML 4.01 DTD @uref{http://www.w3.org/TR/html4/sgml/dtd.html}
に定義されている要素です)。
@c COMMON
@example
a        abbr       acronym    address     area      b
base     bdo        big        blockquote  body      br
button   caption    cite       code        col       colgroup
dd       del        dfn        div         dl        dt
em       fieldset   form       frame       frameset
h1       h2         h3         h4          h5        h6
head     hr         html       i           iframe    img
input    ins        kbd        label       legend    li
link     map        meta       noframes    noscript  object
ol       optgroup   option     p           param     pre
q        samp       script     select      small     span
strong   style      sub        sup         table     tbody
td       textarea   tfoot      th          thead     title
tr       tt         ul         var
@end example

@c EN
The result of these functions is a tree of text segments,
which can be written out to a port by @code{write-tree} or
can be converted to a string by @code{tree->string}
(@pxref{Lazy text construction}).

You can specify attributes of the element by using a keyword-value
notation before the actual content.
@c JP
これらの手続きは、テキスト・セグメントのツリーを返すので、
@code{write-tree} でポートに書き出したり、@code{tree->string} で
文字列に変換したりできます
(@ref{Lazy text construction}参照)。

要素のアトリビュートは要素の内容に先立つキーワード-値の表記で指定することができます。
@c COMMON
@example
(tree->string (html:a :href "http://foo/bar" "foobar"))
  @result{}
  "<a href=\"http://foo/bar\">foobar</a\n>"

(tree->string
  (html:table :width "100%" :cellpadding 0 "content here"))
  @result{}
  "<table width=\"100%\" cellpadding=\"0\">content here</table\n>"
@end example

@c EN
The boolean value given to the attribute has a special meaning.
If @code{#t} is given, the attribute is rendered without a value.
If @code{#f} is given, the attribute is not rendered.
@c JP
属性に与える真偽値は特別な意味を持ちます。
@code{#t} が与えられると、属性は値なしでレンダリングされます。
@code{#f} が与えられると、属性それ自体がレンダリングされません。
@c COMMON
@example
(tree->string (html:table :border #t))
  @result{} "<table border></table\n>"

(tree->string (html:table :border #f))
  @result{} "<table></table\n>"
@end example

@c EN
Special characters in attribute values are escaped by the function,
but the ones in the content are not.  It is caller's responsibility
to escape them.

The functions signal an error if a content is given to the
HTML element that doesn't take a content.   They do not
check if the given attribute is valid, neither
if the given content is valid for the element.
@c JP
属性の値における特別な文字は、手続きによってエスケープされますが、
要素の内容にある特別な文字はエスケープされません。それをエスケープ
するのは呼び出し側の責任です。

内容を持たない HTML 要素に内容を与えると手続きはエラーを通知します。
手続きは、与えられた属性が妥当であるか、与えられた内容がその要素に
とって妥当であるかのチェックはしません。
@c COMMON

@c EN
@emph{Note:}
You might have noticed that these procedures insert a newline
before @code{>} of the closing tag.  That is, the rendered
HTML would look like this:
@c JP
@emph{注意:}
これらの手続は改行を終了タグの@code{>}の前に挿入することに注意してくだ
さい。つまり、HTMLをレンダリングすると以下のようになります。
@c COMMON

@example
<table><tr><td>foo</td
><td>bar</td
></tr
></table
>
@end example

@c EN
We intentionally avoid inserting newlines after the closing
tag, since @emph{it depends on the surrounding context whether
the newline is significant or not}.  We may be able to insert newlines
after the elements directly below a @code{<head>} element,
for example, but we cannot in a @code{<p>} element, without
affecting the content.
@c JP
終了ダグの後に改行をいれないのは意図的なものです。@emph{改行が意味をも
つかどうかは外側の文脈に依存するからです}。たとえば、@code{<head>}要素
の直下にある要素の後に改行を入れてもテキストの内容には影響を与えませんが、
@code{<p>}要素中で改行を入れるとそれは内容の一部となってしまいます。
@c COMMON

@c EN
There are three possible solutions: (1) not to insert newlines
at all, (2) to insert newlines within tags, and (3) to insert
newlines only at the safe position.  The first one creates one
long line of HTML, and although it is still valid HTML, it is
inconvenient to handle it with line-oriented tools.
The third one requires the
rendering routine to be aware of DTD.  So we took the second
approach.
@c JP
3つ可能性があって、(1) 改行は全く入れない、(2) タグの中だけで改行を入
れる。(3) 安全な場所にのみ改行をいれる。最初の場合はHTMLは一行になり、
正当なHTMLではあるものの、行指向のツールで処理するには不便です。3番目
の場合はレンダリングするのにDTDをちゃんと見るツールが必要になります。
というわけで、ここでは2番目のアプローチを取っています。
@c COMMON
@end deftp

@c ----------------------------------------------------------------------
@node Display with pager, Parsing input stream, Simple HTML document construction, Library modules - Utilities
@section @code{text.pager} - Display with pager
@c NODE ページャーを用いた出力, @code{text.pager} - ページャーを用いた出力

@deftp {Module} text.pager
@mdindex text.pager
A convenience module to present long text nicely to the user.
@end deftp

@deffn {Parameter} pager-program
@c MOD text.pager
A parameter containing a list of pager program and its arguments
(e.g. @code{("/usr/bin/less" "-M")}).

The program must take input from the standard input.

The default value is taken from the environment variable @code{PAGER}
if set, or either @code{less} or @code{more} if those programs are
available on the system.
@end deffn

@defun display/pager string
@c MOD text.pager
Display @var{string} by a pager subprocess specified by the parameter
@code{pager-program}.  The procedure returns when the subprocess exits.

If the terminal is not suitable for control
(e.g. @code{TERM} is @code{dumb} or @code{emacs}), @var{string} is
simply @code{display}ed without a pager.

If you're running MinGW version of @code{gosh} on mintty,
calling subprocess pager doesn't work well, so the procedure
emulate the pager behavior (@code{pager-program} is ignored).
@end defun

@defun with-output-to-pager thunk
@c MOD text.pager
Call @var{thunk} with its current output port to a string buffer,
then show the buffered output using @code{display/pager}.

Note that the output begins after @var{thunk} returns.
@end defun


@c ----------------------------------------------------------------------
@node Parsing input stream, Showing progress on text terminals, Display with pager, Library modules - Utilities
@section @code{text.parse} - Parsing input stream
@c NODE 入力ストリームのパージング, @code{text.parse} - 入力ストリームのパージング

@deftp {Module} text.parse
@mdindex text.parse
@c EN
A collection of utilities that does simple parsing from
the input port.   The API is inspired, and compatible with
Oleg Kiselyov's input parsing library (@uref{http://okmij.org/ftp/Scheme/parsing.html}).
His library is used in lots of other libraries, notably,
a full-Scheme XML parser/generator SSAX (@uref{http://okmij.org/ftp/Scheme/xml.html}).

You can use this module in place of his
@code{input-parse.scm} and @code{look-for-str.scm}.

I reimplemented the functions to be efficient on Gauche.
Especially, usage of @code{string-set!} is totally avoided.
I extended the interface a bit so that they can deal with character sets
and predicates, as well as a list of characters.

These functions work sequentially on the given input port,
that is, they read from the port as much as they need, without
buffering extra characters.
@c JP
入力ポートに対して単純な解析を行うユーティリティのコレクションです。
API は Oleg Kiselyov 氏の入力解析ライブラリ (@uref{http://okmij.org/ftp/Scheme/parsing.html}) に
触発され、互換性を持つものです。氏のライブラリは、他のたくさんの
ライブラリで使われています。特に、Scheme のみで書かれたパーサ/ジェネレータ
である SSAX (@uref{http://okmij.org/ftp/Scheme/xml.html}) が挙げられます。

このモジュールは、氏の @code{input-parse.scm} や @code{look-for-str.scm}
の代わりに使うことができます。

Gauche で効果的になるように手続きを再実装しました。特に、@code{string-set!}
の使用は完全に取り除きました。インターフェースを少し拡張したので、
文字集合や述語、文字のリストにも使うことができます。

これらの手続きは、与えられた入力ポートに対してシーケンシャルに動作します。
それは、ポートから必要なだけ読み、余分な文字をバッファリングしないということです。
@c COMMON
@end deftp

@defun find-string-from-port? str in-port :optional max-no-chars
@c MOD text.parse
@c EN
Looks for a string @var{str} from the input port @var{in-port}.
The optional argument @var{max-no-chars} limits the maximum number of
characters to be read from the port; if omitted, the search span is
until EOF.

If @var{str} is found, this function returns the number of characters
it has read.   The next read from @var{in-port} returns the next char
of @var{str}.  If @var{str} is not found, it returns @code{#f}.

Note: Although this procedure has `@code{?}' in its name,
it may return non-boolean value, contrary to the Scheme convention.
@c JP
入力ポート @var{in-port} から、文字列 @var{str} を探します。
オプショナル引数 @var{max-no-chars} は、ポートから読み込まれる最大文字数を
制限します。省略されると、検索する範囲は EOF までとなります。

@var{str} が見つかると、手続きはすでに読み込んだ文字の数を返します。
@var{in-port} の次回の読み込みは、@var{str} の次の文字を返します。
@var{str} が見つからない場合、@code{#f} が返ります。

注意: この手続きはその名前に「@code{?}」がつきますが、Scheme の慣習に反し、
真偽値ではない値を返すことがあります。
@c COMMON
@end defun

@defun peek-next-char :optional port
@c MOD text.parse
@c EN
Discards the current character and peeks the next character from @var{port}.
Useful to look ahead one character.
If @var{port} is omitted, the current input port is used.
@c JP
現在の文字を破棄し、@var{port} から次の文字を読みます。一文字先読みするのに
便利です。@var{port} が省略されると、現在の入力ポートが使われます。
@c COMMON
@end defun

@c EN
In the following functions, @var{char-list} refers to one of the
followings:
@itemize @bullet
@item
A character set.
@item
A list of characters, character sets and/or symbol @code{*eof*}.
@end itemize
That denotes a set of characters.  If a symbol @code{*eof*} is
included, the EOF condition is also included.  Without @code{*eof*},
the EOF condition is regarded as an error.
@c JP
以下の手続きでは、@var{char-list} は次のどれかを意味します。
@itemize @bullet
@item
文字集合。
@item
文字、文字集合、シンボル @code{*eof*} の任意の組み合わせのリスト。
@end itemize
これらにより文字の集合が表現されます。シンボル @code{*eof*} が含まれる場合、
EOF の条件もまた含まれます。@code{*eof*} が含まれない場合、EOF の条件は
エラーとして扱われます。
@c COMMON

@defun assert-curr-char char-list string :optional port
@c MOD text.parse
@c EN
Reads a character from @var{port}.  If it is included in @var{char-list},
returns the character.  Otherwise, signals an error with a message
containing @var{string}.
If @var{port} is omitted, the current input port is used.
@c JP
@var{port} から文字を読みます。その文字が @var{char-list} に含まれている場合は
その文字を返します。そうでなければ、@var{string} を含むメッセージとともに
エラーを通知します。
@c COMMON
@end defun

@defun skip-until char-list/number :optional port
@c MOD text.parse
@c EN
@var{char-list/number} is either a char-list or a number.
If it is a number; it reads that many characters and returns @code{#f}.
If the input is not long enough, an error is signaled.
If @var{char-list/number} is a char-list, it reads from @var{port}
until it sees a character that belongs to the char-list.
Then the character is returned.
If @var{port} is omitted, the current input port is used.
@c JP
@var{char-list/number} は、文字のリストか数です。
数の場合、たくさんの文字を読んで、@code{#f} を返します。
入力が十分に長くない場合は、エラーが通知されます。
@var{char-list/number} が文字のリストの場合、その文字リストに属する文字に
出会うまで @var{port} を読み込み、その文字を返します。
@var{port} が省略された場合、現在の入力ポートが使われます。
@c COMMON
@end defun

@defun skip-while char-list :optional port
@c MOD text.parse
@c EN
Reads from @var{port} until it sees a character that does not
belong to @var{char-list}.  The character remains in the stream.
If it reaches EOF, an EOF is returned.
If @var{port} is omitted, the current input port is used.

This example skips whitespaces from input.  Next read from
port returns the first non-whitespace character.
@c JP
@var{char-list} に属しない文字に出会うまで、@var{port} を読み込みます。
文字はストリームに残されます。EOF に達したら EOF が返されます。
@var{port} が省略された場合、現在の入力ポートが使われます。

この例では、入力から空白スペースをスキップしています。ポートからの次の
読み込みは、最初の空白スペースでない文字を返します。
@c COMMON
@example
(skip-while #[\s] port)
@end example
@end defun

@defun next-token prefix-char-list break-char-list :optional comment port
@c MOD text.parse
@c EN
Skips any number of characters in @var{prefix-char-list},
then collects the characters until it sees @var{break-char-list}.
The collected characters are returned as a string.
The break character remains in the @var{port}.

If the function encounters EOF and @code{*eof*} is not included in
@var{break-char-list}, an error is signaled with @var{comment} is
included in the message.
@c JP
@var{prefix-char-list} に含まれる文字はいくつでもスキップします。
そして、@var{break-char-list} に含まれる文字に出会うまで、文字を
蓄積します。蓄積された文字群は文字列として返されます。
中断文字は @var{port} に残されます。

手続きが EOF に達し、@code{*eof*} が @var{break-char-list} に含まれていない
場合、@var{comment} が含まれたメッセージとともにエラーが通知されます。
@c COMMON
@end defun

@defun next-token-of char-list/pred :optional port
@c MOD text.parse
@c EN
Reads and collects the characters as far as
it belongs to @var{char-list/pred}, then returns them as a string.
The first character that doesn't belong to @var{char-list/pred} remains
on the port.

@var{char-list/pred} may be a char-list or a predicate that takes
a character.   If it is a predicate, each character is passed to it,
and the character is regarded to ``belong to'' @var{char-list/pred}
when it returns a true value.
@c JP
読み込んだ文字が @var{char-list/pred} にある限り蓄積し、文字列として
返します。@var{char-list/pred} に含まれない最初の文字はポートに残されます。

@var{char-list/pred} は文字のリストか文字を取る述語です。述語の場合、
それぞれの文字がその述語に渡され、真の値が返る場合はその文字は
@var{char-list/pred} に属するとみなされます。
@c COMMON
@end defun

@defun read-string n :optional port
@c MOD text.parse
@c EN
This is like built-in @code{read-string} (@pxref{Reading data}),
except that this returns @code{""} when the input already reached EOF.

Provided for the compatibility for the code that depends Oleg's library.
@c JP
組み込みの@code{read-string} (@ref{Reading data}参照) とほぼ同じですが、
入力が既にEOFに達していた場合は@code{""}を返します。

Olegのライブラリに依存しているコードの互換性のために用意されています。
@c COMMON
@end defun

@c ----------------------------------------------------------------------
@node Showing progress on text terminals, SQL parsing and construction, Parsing input stream, Library modules - Utilities
@section @code{text.progress} - Showing progress on text terminals
@c NODE テキスト端末上で進捗を表示する, @code{text.progress} - テキスト端末上で進捗を表示する

@deftp {Module} text.progress
@mdindex text.progress
@c EN
This module provides a utility to report a progress of processing
on a text terminal, using characters to display bar chart.
@c JP
このモジュールはバーチャートを文字を用いて表示し、テキスト端末上に処理
の進行状況を出すためのユーティリティです。
@c COMMON

@c EN
The generic format of a progress bar consists of a single line
of text, which is splitted into several parts; a header, which
displays the title; followed by a bar, a numeric part, and a time part,
as shown in the following example (only the line beginning with ``foo''
is actually displayed).
@c JP
進捗を示すプログレスバーの汎用的なフォーマットは1行のテキストで構成されます。
この1行はいくつかの部分に分解できます。タイトルを表示するヘッダ部、その後に
プログレスバーがあって、数値部、時間部と続きます。以下がその例です(foo
からはじまる1行だけが実際に表示されます。
@c COMMON
@example
<-header-> <-------bar---------> <-num-><-time->      <---info---->
foo       |#############        |123/211   01:21 ETA  compiling...
          ^
          separator
@end example

@c EN
Various things like the character used in the bar chart or
the format of the numeric progress can be configured.
@c JP
バーチャートに使う文字などのいろいろなバリエーションや、数値で表わす
進捗のフォーマットなども設定可能です。
@c COMMON

@c EN
Internally a progress bar maintains two numbers, the maximum (goal)
value and the current value.  The bar shows the proportion of
the current value relative to the maximum value.  The numeric progress
shows the current value over the maximum value by default, but you
can configure it to show only the current value or percentage, for example.
@c JP
内部的にはプログレスバーは2つの数値、最大値(ゴール)と現在の値を保持し
ています。バーは最大値に対する現在の値の比を示すものです。数値で表わす
進捗はデフォルトでは最大値の上に現在の値を表示します。しかし、たとえば、
現在の値だけを表示するとか、100分率で表示するなどの設定が可能です。
@c COMMON

@c EN
A progress bar also has two states, ``in progress'' and ``finished''.
When it is in progress, every time the text is displayed it is
followed by @code{#\return}, so that the next display overwrites
the bar, and the time part shows ETA (estimated time of arrival).
Once it becomes finished, the last line of text is displayed
with @code{#\newline}, and the time part shows the actual time
it took to finish.
@c JP
プログレスバーは2つの状態「進捗中」および「終了」のどちらかの状態を保
持しています。「進捗中」なら、どの時点でも表示されるテキストには
@code{#\return}が続きます。これにより次の表示が前の表示を上書きするこ
とになります。時間部はETA(残り時間)を表示します。終了してしまえば、最
後の行の後に@code{#\newline}が続きます。時間部には終了までにかかった時
間が表示されます。
@c COMMON
@end deftp

@c EN
This module provides only one procedure, @code{make-text-progress-bar},
which packages the progress bar feature in a closure and returns it.
@c JP
このモジュールは@code{make-text-progress-bar}という手続きを1つだけ提供
します。この手続きはプログレスバーの機能をクロージャに包んでそれを返し
ます。
@c COMMON

@defun make-text-progress-bar :key header header-width bar-char bar-width num-width num-format time-width info info-width separator-char max-value port
@c MOD text.progress
@c EN
Returns a procedure that packages operations on the progress bar.
The procedure can be called with a symbol indicating an operation,
and an optional numeric argument.
@c JP
プログレスバー上の操作を包んだ手続きを返します。返された手続きに操作を
示すシンボルとオプションで数値を引数として渡して使います。
@c COMMON

@table @code
@item @var{proc} 'show
@c EN
Redisplays the progress bar.  All other operations implies redisplay,
so you don't need to use this unless you have a specific reason to
redisplay the current state.
@c JP
プログレスバーを再表示する。他のどの操作も状態の再表示を行います。
したがって、現在のステータスを再表示しなければない特別な理由がないかぎ
りこれを使う必要はありません。
@c COMMON

@item @var{proc} 'set @var{value}
@c EN
Sets the current value to @var{value}, then redisplays the progress bar.
If @var{value} exceeds the max value, it is clipped by the max value.
@c JP
現在の値を@var{value}にセットし、プログレスバーを再表示します。
@var{value}が最大値を超えていたら、超過分を切り捨て最大値にします。
@c COMMON

@item @var{proc} 'inc @var{value}
@c EN
Increments the current value by @var{value}, then redisplays the progress bar.
If the current value exceeds the max value, it is clipped by the max value.
@c JP
@var{value}分だけ現在の値を増し、プログレスバーを再表示します。現在の
値が最大値を超えたら、超過分を切り捨て最大値にします。
@c COMMON

@item @var{proc} 'finish
@c EN
Puts the progress bar to the ``finished'' state, then redisplays it.
The time part shows the total elapsed time, and the line is terminated
by @code{#\newline} so that it won't be clobbered.   Once a progress
bar becomes ``finished'', there's no way to put it back ``in progress''.
@c JP
プログレスバーを「終了」状態にし、再表示します。時間部はトータルの経過
時間を表示します。また、表示行末は@code{#\newline}とし、上書きされない
ようにします。プログレスバーはいったん「終了」状態になれば、「進捗中」
状態に戻す方法はありません。
@c COMMON

@item @var{proc} 'set-info @var{text}
@c EN
Changes the text displayed in the ``info'' part.  To use the info part,
you have to give a positive value to @var{info-width} keyword argument
of @code{make-text-progress-bar}.
@c JP
``info''部に表示されるテキストを変更します。
info部を使うには、@code{make-text-progress-bar}の@var{info-width}キーワード
引数に正の値が指定されている必要があります。
@c COMMON


@item @var{proc} 'set-header @var{text}
@c EN
Changes the text displayed in the ``header' area.
@c JP
``header''部に表示されるテキストを変更します。
@c COMMON
@end table

@c EN
The keyword arguments are used to customize the display:
@c JP
キーワード引数を使って表示をカスタマイズできます。
@c COMMON
@table @var
@item header
@c EN
The text to be displayed in the header part.
This can be changed later, by sending @code{set-header} message
to the created progress bar.
@c JP
ヘッダ部に表示するテキスト。このテキストは、作られたプログレスバーに
@code{set-header}メッセージを送ることで後で変更可能です。
@c COMMON

@item header-width
@c EN
The width of the header part, in number of characters.
The header text is displayed left-aligned in the part.
If the header text is longer than the width, the excess characters
are omitted.  The default is 14.
@c JP
ヘッダ部の幅、文字数で指定します。ヘッダ部のテキストは左詰めです。ヘッ
ダ部に置くテキストが幅よりも長い場合には超過分の文字は切り捨てられます。
デフォルトは14文字です。
@c COMMON

@item bar-char
@c EN
A character used to draw a bar chart.  The default is @code{#\#}.
@c JP
バーチャートを描くのに使う文字。デフォルトは@code{#\#}です。
@c COMMON

@item bar-width
@c EN
The width of the bar chart part, in number of characters.
The default is 40.
@c JP
バーチャート部の幅で、文字数で指定します。デフォルトでは40文字です。
@c COMMON

@item num-width
@c EN
The width of the numeric part, in number of characters.
The default is 9.  Setting this to 0 hides the numeric part.
@c JP
数値部の幅で、文字数で指定します。デフォルトでは9で、これを0に設定する
と数値部を隠せます。
@c COMMON

@item num-format
@c EN
A procedure to format the numeric part.  Two arguments are
passed; the current value and the maximum value.  It must return
a string.  The default is the following procedure.
@c JP
数値部を整形する手続き。引数が2つ渡されます。ひとつは現在の値、もうひ
とつは最大値です。この手続きは文字列を返さなければなりません。デフォル
トでは以下の手続きです。
@c COMMON
@example
(lambda (cur max)
  (format "~d/~d" cur max))
@end example

@item time-width
@c EN
The width of the time part, in number of characters.
The default is 7.  Settings this to 0 hides the time part.
@c JP
時間部の幅で、文字数で指定します。デフォルトでは7文字で、これを0に設定
すると時間部を隠せます。
@c COMMON

@item info
@c EN
The text to be displayed in the info part.  This text can be
changed later by sending @code{set-info} message to the created
progress bar.  Note that you have to give a positive number
to @var{info-width} keyword argument to enable the info part.
@c JP
info部に表示されるテキストです。このテキストは、作られたプログレスバーに
@code{set-info}メッセージを送ることで後から変更できます。
info部を表示するには、@var{info-width}キーワード引数に正の値を
与えておく必要があります。
@c COMMON

@item info-width
@c EN
The width of the info part.  The default value is zero,
which means the info part is not displayed.
@c JP
info部の表示幅です。デフォルトは0で、info部は表示されません。
@c COMMON

@item separator-char
@c EN
A character put around the bar part.  Default is @code{#\|}.
You can pass @code{#f} not to display the separators.
@c JP
バー部分の前後に置く文字です。デフォルトでは@code{#\|}です。
セパレータを表示したくなければ、@code{#f}を渡します。
@c COMMON

@item max-value
@c EN
The maximum value of the progress bar.  Must be a positive real number.
Default is 100.
@c JP
プログレスバーの最大値です。正の実数でなければなりません。デフォルトでは100です。
@c COMMON

@item port
@c EN
An output port to which the progress bar is displayed.  The default value
is the current output port when @code{make-text-progress-bar} is called.
@c JP
プログレスバーを表示する出力ポートです。デフォルト値は
@code{make-text-progress-bar}が呼ばれた時点での現在の出力ポートです。
@c COMMON
@end table
@end defun

@c EN
Here's a simple example, using customized numeric part:
@c JP
以下は簡単なカスタマイズをした例です。
@c COMMON

@example
(use text.progress)

(define (main args)
  (define (num-format cur max)
    (format "~d/~d(~3d%)" cur max
            (round->exact (/. (* cur 100) max))))

  (let ((p (make-text-progress-bar :header "Example"
                                   :header-width 10
                                   :bar-char #\o
                                   :num-format num-format
                                   :num-width 13
                                   :max-value 256)))
    (do ((i 0 (+ i 1)))
        ((= i 256) (p 'finish))
      (p 'inc 1)
      (sys-select #f #f #f 50000))))
@end example

@c ----------------------------------------------------------------------
@node SQL parsing and construction, Simple template expander, Showing progress on text terminals, Library modules - Utilities
@section @code{text.sql} - SQL parsing and construction
@c NODE SQLのパーズと構築, @code{text.sql} - SQLのパーズと構築

@deftp {Module} text.sql
@mdindex text.sql
@c EN
This module provides a utility to parse and construct SQL statement.
@c JP
このモジュールはSQL文のパーズと構築のためのユーティリティを提供します。
@c COMMON

@c EN
It is currently under development, and we only have a tokenization routine.
The plan is to define S-expression syntax of SQL and provides a routine
to translate one form to the other.
@c JP
このモジュールは現在まだ開発途上にあります。まだトークン列を生成するルー
チンしかありません。SQLのS式構文を定義して、SQLとその構文との間の変換
ルーチンを提供する計画です。
@c COMMON

@c EN
Note: If you're looking for a routine to escape strings to be
safe in SQL, see @code{dbi-escape-sql} in @ref{DBI user API}.
@c JP
註: SQLに安全に渡せるように文字列をエスケープするルーチンをお探しなら、
@ref{DBI user API}の@code{dbi-escape-sql}を見てください。
@c COMMON
@end deftp

@defun sql-tokenize sql-string
@c MOD text.sql
@c EN
Tokenize a SQL statement @var{sql-string}.  The return value is
a list of tokens, where each token is
represented by one of the following forms.
@c JP
SQL文@var{sql-string}をトークン列に分解します。返り値はトークンのリス
トで、各トークンは以下の形式のひとつで表現されます。
@c COMMON

@c EN
@example
<symbol>              Special delimiter.  One of the followings:
                      + - * / < = > <> <= >= ||
<character>           Special delimiter.  One of the followings:
                      #\, #\. #\( #\) #\;
<string>              Regular identifier
(delimited <string>)  Delimited identifier
(parameter <num>)     Positional parameter (?)
(parameter <string>)  Named parameter (:foo)
(string    <string>)  Character string literal
(number    <string>)  Numeric literal
(bitstring <string>)  Binary string.  <string> is like "01101"
(hexstring <string>)  Binary string.  <string> is like "3AD20"
@end example
@c JP
@example
<symbol>              特殊区切り子、以下のどれか
                      + - * / < = > <> <= >= ||
<character>           特殊区切り子、以下のどれか
                      #\, #\. #\( #\) #\;
<string>              通常の識別子
(delimited <string>)  区切られた識別子
(parameter <num>)     位置パラメータ (?)
(parameter <string>)  名前つきパラメータ (:foo)
(string    <string>)  文字列リテラル
(number    <string>)  数値リテラル
(bitstring <string>)  バイナリ文字列  <string> は "01101" な感じ
(hexstring <string>)  Binary string.  <string> は "3AD20" な感じ
@end example
@c COMMON

@c EN
If it encounters an untokenizable string, it raises an
@code{<sql-parse-error>} condition.
@c JP
トークンに分解できない文字列がくると@code{<sql-parse-error>}コンディショ
ンがあがります。
@c COMMON
@end defun

@deftp {Condition Type} <sql-parse-error>
@c MOD text.sql
@c EN
A condition to indicate an SQL parse error.  Inherits @code{<error>}.
@c JP
SQLパーズエラーを示すコンディション。@code{<error>}を継承。
@c COMMON
@defivar <sql-parse-error> sql-string
@c EN
Holds the source SQL string.
@c JP
元のSQL文字列を保持。
@c COMMON
@end defivar
@end deftp

@c ----------------------------------------------------------------------
@node Simple template expander, Transliterate characters, SQL parsing and construction, Library modules - Utilities
@section @code{text.template} - Simple template expander
@c NODE 簡単なテンプレート拡張, @code{text.template} - 簡単なテンプレート拡張

@deftp {Module} text.template
@mdindex text.template
@c EN
This module lifts Gauche's built-in string interpolation feature
to be more general template engine.
@c JP
このモジュールは、Gauche組み込みの文字列補間機能をより一般的なテンプレートエンジンとして
使えるようにするものです。
@c COMMON

@c EN
Gauche's string interpolation syntax is expanded at read time and then
handled by macro expanders, and 
becomes a simple Scheme code fragment.  
For example, if you have this:
@c JP
Gaucheの文字列補間構文はソース読み込み時にマクロ呼び出しへと展開され、
さらにマクロ展開器により展開されて単純なSchemeコード片となります。
例えば、次のソースコードがある場合:
@c COMMON
@example
(let ([x 10])
  #"The square of x is ~(* x x).")
@end example

@c EN
It is eventually converted to this after macro expansion:
@c JP
マクロ展開後の最終形は次のコードになります:
@c COMMON
@example
(let ([x 10])
  (string-append '"The square of x is " (x->string (* x.0 x.0)) '"."))
@end example

@c EN
It is a kind of template expansion, but you have to have the template string
as a literal, so it's restricted.  With this module, you can feed template
string and the bindings of the value at the runtime:
@c JP
これも一種のテンプレート展開と言えるのですが、文字列補間ではテンプレート文字列が
文字列リテラルとしてソースコード上に現れていなければならないという制限があります。
このモジュールでは、文字列と束縛を実行時に与えることができます:
@c COMMON

@example
(define *template* "The square of x is ~(* x x).")

(expand-template-string *template*
  (make-template-environment :bindings '(x 10)))
  @result{} "The square of x is 100."
@end example

@c EN
The syntax of template strings is the same as string interpolation
(@pxref{String interpolation}); that is, tokens following @code{~}
is read as a Scheme expression.  In case if the token is a symbol
and you need to delimit it from subsequent characters, you can use
symbol escape by @code{|}.
@c JP
テンプレート文字列の構文は文字列補間のそれと同じです(@ref{String interpolation}参照)。
すなわち、@code{~}に続くトークンがScheme式として呼ばれます。もしトークンがシンボルで、
その後の続く文字から区切る必要がある場合は、@code{|}によるシンボルエスケープが使えます。
@c COMMON

@c EN
You also need to provide a @emph{template environment}, where the
expressions in the template is evaluated.  Note that, 
unlike string interpolation,
those expressions can't refer to the local bindings.
@c JP
また、テンプレート展開時には、テンプレート中の式を評価するための
@emph{テンプレート環境}を与える必要があります。
文字列補間と違って、テンプレート中の式がローカル束縛を参照することはできません。
@c COMMON
@end deftp

@defun expand-template-string template env
@c EN
Expands a template string @var{template} with a template environment
@var{env}, and returns the result string.
@c JP
テンプレート文字列@var{template}を、テンプレート環境@var{env}のもとで展開し、
結果の文字列を返します。
@c COMMON
@end defun

@defun expand-template-file filename env :optional paths
@c EN
Reads a template string from a file named by @var{filename}, expands
it with a template environment @var{env}, and returns the result string.

If @var{filename} is not an absolute path, it is looked in the directories
listed in @var{paths}.
@c JP
テンプレート文字列を@var{filename}で指定されるファイルから読み込み、
テンプレート環境@var{env}のもとでそれを展開し、結果の文字列を返します。

@var{filename}が絶対パスでない場合は、@var{paths}中のディレクトリからの相対パスで
探されます。
@c COMMON
@end defun

@defun make-template-environment :key extends imports bindings
@c EN
Creates and returns a template environment.   A template environment
is like a module (@pxref{Modules}): It maps symbols to values, and
it can import bindings from other modules, or extend other modules.
@c JP
テンプレート環境を作成して返します。テンプレート環境はモジュールのようなものです
(@ref{Modules}参照)。それはシンボルを値にマップし、
また他のモジュールから束縛をインポートしたり、他のモジュールをextendしたりできます。
@c COMMON

@c EN
The keyword arguments @var{extends} and @var{imports} must be a list
of symbols; they specify names of modules to inherit from or to import from.
@c JP
キーワード引数@var{extends}と@var{imports}はシンボルのリストを取り、
それぞれ継承元のモジュール、あるいはインポート元のモジュールを指定します。
@c COMMON

@c EN
The keyword arguments @var{bindings} must either be a dictionary
(anything that inherits @code{<dictionary>}), or a key-value list.
The mappings represented by it are incorporated to the environment.
@c JP
キーワード引数@var{bindings}はディクショナリ(@code{<dictionary>}のサブクラスの
インスタンス)か、key-valueリストでなければなりません。
それにより表される束縛が環境に取り込まれます。
@c COMMON
@end defun

@c ----------------------------------------------------------------------
@node Transliterate characters, Lazy text construction, Simple template expander, Library modules - Utilities
@section @code{text.tr} - Transliterate characters
@c NODE 文字変換, @code{text.tr} - 文字変換

@deftp {Module} text.tr
@mdindex text.tr
@c EN
This module implements a transliterate function,
that substitutes characters of the input string.
This functionality is realized in Unix @code{tr(1)} command,
and incorporated in various programs such as @code{sed(1)}
and @code{perl}.

Gauche's @code{tr} is aware of multibyte characters.
@c JP
このモジュールは、入力ストリームから指定の文字を置き換えて出力する、
文字変換(transliterate)機能を提供します。
Unixの@code{tr(1)}コマンドで実装され、@code{sed}や@code{perl}にも
採り入れられている機能です。

Gaucheの@code{tr}はマルチバイト文字／文字列を正しく扱います。
@c COMMON
@end deftp

@defun tr from-list to-list :key :complement :delete :squeeze :table-size :input :output
@c MOD text.tr
@c EN
Reads from @var{input} and writes to @var{output},
with transliterating characters in @var{from-list} to the
corresponding ones in @var{to-list}.  Characters that doesn't
appear in @var{from-list} are passed through.
@c JP
@var{input}から文字を読み込み、その文字が@var{from-list}内にあれば
対応する@var{to-list}内の文字に置き換えて、@var{output}へと書き出します。
@var{from-list}に無い文字はそのまま@var{output}へと渡されます。
@c COMMON

@c EN
The default values of @var{input} and @var{output} are
current input port and current output port, respectively.
@c JP
@var{input}と@var{output}の既定値はそれぞれ現在の入力ポートと
出力ポートです。
@c COMMON

@c EN
Both @var{from-list} and @var{to-list} must be strings.
They may contain the following special syntax.
Other characters that doesn't fits in the syntax are taken as they are.
@c JP
@var{from-list}と@var{to-list}は文字列でなければなりません。
その中には次のような表記を使うことができます。それ以外の文字はそのまま使われます。
@c COMMON

@table @code
@item @b{x-y}
@c EN
Expanded to the increasing sequence of characters from @code{x} to @code{y},
inclusive.  The order is determined by the internal character
encoding system; generally it is safer to limit use of this within
the range of the same character class.   The character @code{x}
must be before @code{y}.
@c JP
文字@code{x}から文字@code{y}までの文字の昇順の並びと解釈されます。
@code{x}と@code{y}は含まれます。文字の並びはGaucheの内部文字エンコーディングに
よって決定されるので、一般には@code{x}と@code{y}は同じキャラクタクラスの中に
止めておいた方が安全でしょう。@code{x}は@code{y}より小さくなければなりません。
@c COMMON

@item @b{x*n}
@c EN
Repeat @code{x} for @code{n} times.  @code{n} is a decimal number notation.
Meaningful only in
@var{to-list}; it is an error to use this form in @var{from-list}.
If @code{n} is omitted or zero, @code{x} is repeated until @var{to-list}
matches the length of @var{from-list} (any character after it is ignored).
@c JP
文字@code{x}の@code{n}個の並び。@code{n}は10進数で表記された数値です。
これは@var{to-list}でのみ有効で、@var{from-list}で使うとエラーになります。
@code{n}が省略されるか0の場合、@code{x}は@var{to-list}の長さが@var{from-list}
の長さに達するまで繰り返されます(その場合、@var{to-list}の残りは無視されます)。
@c COMMON

@item @b{@code{\}x}
@c EN
Represents @code{x} itself.  Use this escape to avoid a special
character to be interpreted as itself.   Note that if you place
a backslash in a string, you must write @code{\\}, for the Scheme
reader also interprets backslash as a special character.

There's no special sequence to represent non-graphical characters,
for you can put such characters by the string syntax.
@c JP
文字@code{x}それ自身。特殊文字そのものを埋め込みたい場合に使います。
文字列のリーダも@code{\}を解釈するので、@code{\\}と書かねばならないことに注意
して下さい。

グラフィカルでない文字のための構文はありません。文字列リーダの構文を使って
そのような文字を文字列に含めることができます。
@c COMMON
@end table

@c EN
Here's some basic examples.
@example
;; @r{swaps case of input}
(tr "A-Za-z" "a-zA-Z")

;; @r{replaces 7-bit non-graphical characters to `?'}
(tr "\x00-\x19\x7f" "?*")
@end example
@c JP
いくつか例を挙げます。
@example
;; @r{大文字と小文字を交換します}
(tr "A-Za-z" "a-zA-Z")

;; @r{ひらがなとかたかなを交換します}
(tr "ぁ-んァ-ン" "ァ-ンぁ-ん")

;; @r{7ビットのノングラフィカルな文字を`?'に変換します}
(tr "\x00-\x19\x7f" "?*")
@end example
@c COMMON

@c EN
If @var{to-list} is shorter than @var{from-list}, the behavior
depends on the keyword argument @var{delete}.  If a true value is
given,  characters that appear in @var{from-list} but not
in @var{to-list} are deleted.   Otherwise,
the extra characters in @var{from-list} are just passed through.
@c JP
@var{to-list}が@var{from-list}より短い場合、動作はキーワード引数@var{delete}に
依存します。もし真の値が@var{delete}に与えられれば、@var{from-list}に現われて
@var{to-list}に対応するものがない文字は入力から取り除かれます。そうでなければ
そのような文字はそのまま出力されます。
@c COMMON

@c EN
When a true value is specified to @var{complement},
the character set in @var{from-list} is complemented.
Note that it implies @emph{huge} set of characters,
so it is not very useful unless either output character
set is a single character (using `*') or used with
@code{delete} keyword.
@c JP
真の値が@var{complement}に与えられた場合、@var{from-list}の文字の
補集合が@var{from-list}として使われます。この文字集合は極めて大きくなる
可能性があることに注意してください。従って、一般にこのオプションは
@var{to-list}に`*'を使ってそれらの文字を一文字にマッピングするか、
@code{delete}オプションと併用するかしないとあまり意味がありません。
@c COMMON

@c EN
When a true value is specified to @var{squeeze},
the sequence of the same replaced characters is squeezed to one.
If @var{to-list} is empty, the sequence of the same characters
in @var{from-list} is squeezed.
@c JP
真の値が@var{squeeze}に与えられた場合、同じ文字への置換が2つ以上並ぶ場合に
2つめ以降の文字が削除されます。@var{to-list}が空の場合は、@var{from-list}
に含まれる文字で同一文字が並んだ場合に2つめ以降の文字が削除されます。
@c COMMON

@c EN
Internally, @code{tr} builds a table to map the characters for
efficiency.  Since Gauche can deal with potentially huge set
of characters, it limits the use of the table for only smaller
characters (<256 by default).  If you want to transliterate
multibyte characters on the large text, however, you might want
to use larger table, trading off the memory usage.  You can specify
the internal table size by @var{table-size} keyword argument.
For example, if you transliterate lots of EUC-JP hiragana text
to katakana, you may want to set table size greater than 42483
(the character code of the last katakana).
@c JP
内部的に、@code{tr}はキャラクタのマッピングのためにテーブルを使用します。
但し、Gaucheでは極めて大きな文字集合を扱うため、テーブルはキャラクタコードの
小さい文字のみに対して使われます(デフォルトではコード255以下の文字)。
もし、より大きな文字を頻繁に変換することが分かっていて、メモリを余分に使っても
速度を上げたい場合は、このテーブルの大きさを@var{table-size}キーワード引数で
指定することができます。例えばEUC-JPコードで大量の平仮名と片仮名を変換する場合は、
@var{table-size}を42483以上にすると、全ての変換がテーブルルックアップで
行われます。
@c COMMON

@c EN
Note that the pre-calculation to build the transliterate table
needs some overhead.  If you want to call @code{tr} many times
inside loop, consider to use @code{build-transliterator} described below.
@c JP
@code{tr}が変換テーブルを計算するのにいくらかオーバーヘッドがあることに
注意して下さい。内側のループで@code{tr}を繰り返し呼ぶような場合は
下に示す@code{build-transliterator}を使った方が良いでしょう。
@c COMMON
@end defun

@defun string-tr string from-list to-list :key :complement :delete :squeeze :table-size
@c MOD text.tr
@c EN
Works like @code{tr}, except that input is taken from a string @var{string}.
@c JP
入力を@var{string}から取って変換結果を文字列で返す以外は@code{tr}と同じです。
@c COMMON
@end defun

@defun build-transliterator from-list to-list :key :complement :delete :squeeze :table-size :input :output
@c MOD text.tr
@c EN
Returns a procedure that does the actual transliteration.  This effectively
``pre-compiles'' the internal data structure.   If you want to run
@code{tr} with the same sets repeatedly, you may build the procedure
once and apply it repeatedly, saving the overhead of initialization.
@c JP
実際の変換動作をする手続きを作成して返します。内部データのセットアップを済ませるため、
同じ文字変換セットに対して@code{tr}を繰り返し呼ぶような場合は、この手続きを用いることで
初期化のオーバヘッドを軽減することができます。
@c COMMON

@c EN
A note for an edge case:
When @var{input} and/or @var{output} keyword arguments are omitted,
the created transliterator is set up to use current-input-port and/or
current-output-port at the time transliterator is called.
@c JP
註記：@var{input}や@var{output}キーワード引数が省略された場合、
作成される変換手続きは、それが使用された時点でのカレント入出力ポート
を参照します。
@c COMMON

@example
(with-input-from-file "huge-file.txt"
  (lambda ()
    (let loop ((line (read-line)))
      (unless (eof-object? line) (tr "A-Za-z" "a-zA-Z")))))

@c EN
;; @r{runs more efficiently...}
@c JP
;; @r{以下の方が効率良く動作します...}
@c COMMON

(with-input-from-file "huge-file.txt"
  (lambda ()
    (let ((ptr (build-transliterator "A-Za-z" "a-zA-Z")))
      (let loop ((line (read-line)))
        (unless (eof-object? line) (ptr))))))
@end example

@end defun

@c ----------------------------------------------------------------------
@node Lazy text construction, Combination library, Transliterate characters, Library modules - Utilities
@section @code{text.tree} - Lazy text construction
@c NODE 怠惰なテキスト構築, @code{text.tree} - 怠惰なテキスト構築

@deftp {Module} text.tree
@mdindex text.tree
@c EN
Defines simple but commonly used functions for a text construction.

When you generate a text by a program,
It is a very common operation to concatenate text segments.
However, using string-append repeatedly causes unnecessary
copying of intermediate strings, and sometimes such intermediate
strings are discarded due to the error situation (for example,
think about constructing an HTML document in the CGI script).

The efficient technique is to delay concatenation of those
text segments until it is needed.  In Scheme it is done very
easily by just consing the text segments together, thus forming
a tree of text, and then traverse the tree to construct a text.
You can even directly writes out the text during traversal,
avoiding intermediate string buffer.
(Hans Boehm's ``cord'' library, which comes with his garbage
collector library, uses this technique and proves it is very
efficient for editor-type application).

Although the traversal of the tree can be written in a
few lines of Scheme, I provide this module in the spirits
of OnceAndOnlyOnce.   Also it's easier if we have a common interface.
@c JP
テキストを生成する場合によく使われるシンプルな手続きを定義します。

プログラムでテキストを生成する場合、テキストの断片をつなぎ合わせて行く操作が
非常に多く現われます。しかし単純に@code{string-append}を繰り返し
呼んでしまうと、中間結果の文字列を保持するためだけにメモリアロケーションが多発しますし、
途中でエラーが発生した場合にその中間結果は結局捨てられてしまうかもしれません
(例えば、CGIスクリプト中でHTMLドキュメントを構築してゆくような場合を考えてみて下さい)。

よく知られた効率の良い方法は、テキストの断片をつなぎ合わせるのを本当に必要に
なるまで遅らせることです。Schemeではそれは非常に簡単です。単に断片をコンス
していって木構造を作り、最後にそれをトラバースしてテキストを作成するのです。
場合によっては、トラバースしながらテキストを出力すれば事足りてしまうので、
中間結果のバッファを持つ必要さえありません。
(Hans Boehmのガベージコレクションライブラリに附属している ``cord'' ライブラリ
はこのテクニックを実装したもので、エディタ等のアプリケーションで非常に効率良く
動作することが知られています)。

木構造をトラバースする手続きなどほんの2〜3行で書けてしまいますが、
「一度、そして一度だけ」の精神の下に、このモジュールを提供します。
インタフェースが統一されてたほうが便利ですしね。
@c COMMON
@end deftp

@deffn {Generic Function} write-tree tree :optional out
@c MOD text.tree
@c EN
Writes out an @var{tree} as a tree of text, to the output port @var{out}.
If @var{out} is omitted, the current output port is used.

Two methods are defined for this generic function, as shown below.
If you have more complex behavior, you can define more methods
to customize the behavior.
@c JP
@var{tree}をテキストの木構造とみなして、出力ポート@var{out}に出力します。
@var{out}が省略された場合は現在の出力ポートが使われます。

下に示す2つのメソッドが定義されています。より複雑な動作をさせたい場合は、
単純なリストの替わりにノードとなるクラスを定義して、それにメソッドを定義するようにすれば
動作をカスタマイズできます。
@c COMMON
@end deffn

@deffn {Method} write-tree ((tree <list>) out)
@deffnx {Method} write-tree ((tree <top>) out)
@c MOD text.tree
@c EN
Default methods.  For a list, @code{write-tree} is recursively
called for each element.  Any objects other than list is written out
using @code{display}.
@c JP
@code{write-tree}の既定の動作です。@var{tree}がリストなら、その要素それぞれに
ついて@code{write-tree}を呼び出します。それ以外のオブジェクトに関しては
@code{display}を呼んで出力します。
@c COMMON
@end deffn

@defun tree->string tree
@c MOD text.tree
@c EN
Just calls the @code{write-tree} method for @var{tree} using
an output string port, and returns the result string.
@c JP
出力文字列ポートを作成して@code{write-tree}を呼び、生成された文字列を返します。
@c COMMON
@end defun


@c ----------------------------------------------------------------------
@node Combination library, Message digester framework, Lazy text construction, Library modules - Utilities
@section @code{util.combinations} - Combination library
@c NODE 組み合わせ, @code{util.combinations} - 組み合わせ

@deftp {Module} util.combinations
@mdindex util.combinations
@c EN
This module implements several useful procedures of
combinations, permutations and related operations.

Most procedures in the module have two variants: a procedure without
star (e.g. @code{permutations}) treats all elements in the given
set distinct, while a procedure with star (e.g. @code{permutations*})
considers duplication.  The procedures with star take optional @var{eq}
argument that is used to test equality, which defaults to @code{eqv?}.
@c JP
このモジュールは、いくつかの便利なコンビネーションや順列とそれに関連する
操作の手続きを実装しています。

このモジュールのほとんどの手続きは2つのバージョンを持っています。
1つはアスタリスクの付かない手続き(例えば、@code{permutations})で、
与えられたセットにある全ての要素を区別して扱います。もう1つは、
アスタリスクの付く手続き(例えば、@code{permutations*})で、重複を
考慮します。アスタリスクの付く手続きは、オプショナルな@var{eq}引数を取り
ます。それは等値性のテストに使われ、デフォルトは@code{eqv?}です。
@c COMMON
@end deftp

@defun permutations set
@defunx permutations* set :optional eq
@c MOD util.combinations
@c EN
Returns a list of all permutations of a list @var{set}.
@c JP
リスト@var{set}の全ての順列のリストを返します。
@c COMMON

@example
(permutations '(a b c))
  @result{} ((a b c) (a c b) (b a c) (b c a) (c a b) (c b a))

(permutations '(a a b))
  @result{} ((a a b) (a b a) (a a b) (a b a) (b a a) (b a a))

(permutations* '(a a b))
  @result{} ((a a b) (a b a) (b a a))
@end example

@c EN
The number of possible permutations explodes if @var{set} has
more than several elements.  Use with care.  If you want to process
each permutation at a time, consider @code{permutations-for-each} below.
@c JP
@var{set}がある程度の要素を持っている場合、可能性のある順列の数は
爆発的に大きくなります。注意して使って下さい。
一度にそれぞれの順列を処理したい場合は、下記の@code{permutations-for-each}の
使用を考慮して下さい。
@c COMMON
@end defun

@defun permutations-for-each proc set
@defunx permutations*-for-each proc set :optional eq
@c MOD util.combinations
@c EN
For each permutation of a list @var{set}, calls @var{proc}.
Returns an undefined value.
@c JP
リスト@var{set}のそれぞれの順列に対して、@var{proc}を呼び出します。
戻り値は未定義値です。
@c COMMON
@end defun

@defun combinations set n
@defunx combinations* set n :optional eq
@c MOD util.combinations
@c EN
Returns a list of all possible combinations of @var{n} elements out
of a list @var{set}.
@c JP
リスト@var{set}の@var{n}個の要素の可能性のある全ての順列のリストを
返します。
@c COMMON

@example
(combinations '(a b c) 2)
  @result{} ((a b) (a c) (b c))

(combinations '(a a b) 2)
  @result{} ((a a) (a b) (a b))

(combinations* '(a a b) 2)
  @result{} ((a a) (a b))
@end example

@c EN
Watch out the explosion of combinations when @var{set} is large.
@c JP
@var{set}が大きいときは、組み合わせの爆発について注意して下さい。
@c COMMON
@end defun

@defun combinations-for-each proc set n
@defunx combinations*-for-each proc set n :optional eq
@c MOD util.combinations
@c EN
Calls @var{proc} for each combination of @var{n} elements out of @var{set}.
Returns an undefined value.
@c JP
@var{set}の@var{n}個の要素のそれぞれの組み合わせについて@var{proc}を
呼び出します。戻り値は未定義値です。
@c COMMON
@end defun

@defun power-set set
@defunx power-set* set :optional eq
@c MOD util.combinations
@c EN
Returns power set (all subsets) of a list @var{set}.
@c JP
リスト@var{set}の累乗集合(全てのサブセット)を返します。
@c COMMON

@example
(power-set '(a b c))
  @result{} (() (a) (b) (c) (a b) (a c) (b c) (a b c))

(power-set* '(a a b)
  @result{} (() (a) (b) (a a) (a b) (a a b))
@end example
@end defun

@defun power-set-for-each proc set
@defunx power-set*-for-each proc set :optional eq
@c MOD util.combinations
@c EN
Calls @var{proc} for each subset of @var{set}.
@c JP
@var{set}のそれぞれのサブセットについて@var{proc}を呼び出す。
@c COMMON
@end defun

@defun power-set-binary set
@c MOD util.combinations
@c EN
Returns power set of @var{set}, like @code{power-set}, but in different order.
@code{Power-set-binary} traverses subset space in depth-first order,
while @code{power-set} in breadth-first order.
@c JP
@code{power-set}のように、@var{set}の累乗集合を返しますが、順番が異なります。
@code{power-set-binary}はサブセットの空間を深さ優先でトラバースしますが、
@code{power-set}は横型探索を行います。
@c COMMON

@example
(power-set-binary '(a b c))
  @result{} (() (c) (b) (b c) (a) (a c) (a b) (a b c))
@end example
@end defun

@defun cartesian-product list-of-sets
@defunx cartesian-product-right list-of-sets
@c MOD util.combinations
@c EN
Returns a cartesian product of sets in @var{list-of-sets}.
@code{Cartesian-product} construct the result in left fixed order
(the rightmost element varies first), while
@code{cartesian-product-right} in right fixed order
(the leftmost element varies first).
@c JP
@var{list-of-sets}にあるセットのデカルト積を返します。
@code{cartesian-product}は左固定順で結果を構築しますが
(一番右の要素がまず異なる)、
@code{cartesian-product-right}は右固定順で行います
(一番左の要素がまず異なる)。
@c COMMON

@example
(cartesian-product '((a b c) (0 1)))
  @result{} ((a 0) (a 1) (b 0) (b 1) (c 0) (c 1))

(cartesian-product-right '((a b c) (0 1)))
  @result{} ((a 0) (b 0) (c 0) (a 1) (b 1) (c 1))
@end example
@end defun

@c ----------------------------------------------------------------------
@node Message digester framework, Calculate dominator tree, Combination library, Library modules - Utilities
@section @code{util.digest} - Message digester framework
@c NODE メッセージダイジェストフレームワーク, @code{util.digest} - メッセージダイジェストフレームワーク

@deftp {Module} util.digest
@mdindex util.digest
@c EN
This module provides a base class and common interface for
message digest algorithms, such as MD5 (@pxref{MD5 message digest})
and SHA (@pxref{SHA message digest}).
@c JP
このモジュールは、MD5 (@ref{MD5 message digest}参照)や
SHA (@ref{SHA message digest}参照)などの、メッセージ
ダイジェストアルゴリズムのためのベースクラスと一般的なインターフェースを
提供します。
@c COMMON
@end deftp

@deftp {Class} <message-digest-algorithm-meta>
@clindex message-digest-algorithm-meta
@c MOD util.digest
@c EN
A metaclass of message digest algorithm implementation.
@c JP
メッセージダイジェストアルゴリズムの実装のメタクラスです。
@c COMMON

@defivar {<message-digest-algorithm-meta>} hmac-block-size
@c EN
Specifies the block size (in bytes), which is specific to each algorithm.
(This is a slot for each @emph{class} object that implements the algorithm,
not for instance of such classes.  Only the author of such digest classes
needs to care.  See @file{ext/digest/sha.scm} in the source tree
for more details.)
@c JP
各アルゴリズムに固有のブロックサイズをバイト数で指定します。
(これはアルゴリズムを実装する各クラスオブジェクトのスロットで、
それらのクラスのインスタンスのスロットではありません。通常、新たなダイジェストアルゴリズム
クラスを実装する人のみが気にすれば良いスロットです。具体例は
ソースツリーの@file{ext/digest/sha.scm}を見てください。)
@c COMMON
@end defivar
@end deftp

@deftp {Class} <message-digest-algorithm>
@clindex message-digest-algorithm
@c MOD util.digest
@c EN
A base class of message digest algorithm implementation.
@c JP
メッセージダイジェストアルゴリズムの実装のベースクラスです。
@c COMMON
@end deftp

@c EN
The concrete subclass of message digest algorithm has to
implement the following methods.
@c JP
メッセージダイジェストアルゴリズムの具体サブクラスは、以下のメソッドを
実装しなければなりません。
@c COMMON

@deffn {Generic function} digest-update! algorithm data
@c MOD util.digest
@c EN
Takes the instance of massage-digest algorithm, and updates it
with the data @var{data}, which can be either a u8vector
or a (possibly incomplete) string.
@c JP
メッセージダイジェストアルゴリズムのインスタンスを取り、
それをu8vectorか(不完全な可能性のある)文字列のデータ@var{data}で
更新します。
@c COMMON
@end deffn

@deffn {Generic function} digest-final! algorithm
@c MOD util.digest
@c EN
Finalizes the instance of message-digest algorithm, and
returns the digest result in an incomplete string.
@c JP
メッセージダイジェストアルゴリズムのインスタンスを終了させ、
そのダイジェストの結果を不完全文字列で返します。
@c COMMON
@end deffn

@deffn {Generic function} digest class
@c MOD util.digest
@c EN
A wrapper of digest routines.  Given message-digest algorithm @var{class},
this function reads the input data from current input port until EOF,
and returns the digest result in an incomplete string.
@c JP
ダイジェストルーチンのラッパです。メッセージダイジェストアルゴリズム
@var{class}を与え、現在の入力ポートから入力データをEOFまで読み込み、
そのダイジェストの結果を不完全文字列で返します。
@c COMMON
@end deffn

@deffn {Generic function} digest-string class string
@c MOD util.digest
@c EN
A wrapper of digest routines.  Given message-digest algorithm @var{class},
this function reads the input data from @var{string},
and returns the digest result in an incomplete string.
@c JP
ダイジェストルーチンのラッパです。メッセージダイジェストアルゴリズム
@var{class}を与え、入力データを@var{string}から読み込み、
そのダイジェストの結果を不完全文字列で返します。
@c COMMON
@end deffn

@defun digest-hexify digest-result
@c MOD util.digest
@c EN
An utility procedure.  Given the result of digest, @var{digest-result},
which can be an u8vector or a (possibly incomplete) string,
converts it to a hexified string.
@c JP
ユーティリティ手続きです。ダイジェストの結果、@var{digest-result}
(u8vectorか(不完全かもしれない)文字列)
与えると、それを16進文字列に変換します。
@c COMMON
@end defun

@c ----------------------------------------------------------------------
@node Calculate dominator tree, Determine isomorphism, Message digester framework, Library modules - Utilities
@section @code{util.dominator} - Calculate dominator tree
@c NODE 支配木, @code{util.dominator} - 支配木

@deftp {Module} util.dominator
@mdindex util.dominator
@c EN
Dominator tree is an auxiliary structure for control flow graphs.
It is frequently used in the flow analysis of compilers, but
also useful for handling general directed graphs.
@c JP
支配木(dominator tree)は制御フローグラフで補助的に使われる構造です。
コンパイラのフロー解析によく使われることが多いですが、一般の有向グラフでも有用です。
@c COMMON
@end deftp

@defun calculate-dominators start upstreams downstreams node-comparator
@c MOD util.dominator
@c EN
The four arguments represent a directed, possibly cyclic, graph.
Here, we use @code{Node} to denote an abstract type of a node 
of the graph.  It can be anything---the algorithm is oblivious on
the actual type of nodes.
@c JP
4つの引数で有向グラフが表現されます。循環があっても構いません。
以下ではグラフのノードが@code{Node}という型を持つとして説明します。
実際にはノードの型は何であっても構いません。
アルゴリズムはノードの実際の型とは無関係に動作します。
@c COMMON

@table @asis
@item @var{start} @code{:: Node}
@c EN
The start node, or the enter node, of the graph.
@c JP
フローの起点となるノード。startノードとかenterノードとも呼ばれます。
@c COMMON
@item @var{upstreams} @code{:: Node -> (Node @dots{})}
@c EN
A procedure that takes a node, and returns its upstream
(immediate ancestor) nodes.
@c JP
ノードを取り、その直接の上流ノードのリストを返す関数。
@c COMMON
@item @var{downstreams} @code{:: Node -> (Node @dots{})}
@c EN
A procedure that takes a node, and returns its downstream
(immediate descendant) nodes.
@c JP
ノードを取り、その直接の下流ノードのリストを返す関数。
@c COMMON
@item @var{node-comparator}
@c EN
A comparator that is used to determine if two nodes are equal to each other.
It doesn't need to have comparison procedure (we don't need to see
which is smaller than the other), but it has to have hash function,
for we use hashtables internally.  (@xref{Basic comparators}, for the details
of comparators.)
@c JP
二つのノードが等しいかどうかを決定する比較器。大小比較関数を持っている必要はありませんが、
アルゴリズム内部でハッシュテーブルを使うので、ハッシュ関数は持っている必要があります。
比較器について詳しくは@ref{Basic comparators}を参照してください。
@c COMMON
@end table

@c EN
The procedure returns a list of @code{(node1 node2)}, where
@code{node2} is the immediate dominator of @code{node1}.
@c JP
返り値は@code{(node1 node2)}を要素に持つリストです。ここで、
@code{node2}は@code{node1}の直接支配ノード(immediate dominator)です。
@c COMMON

@c EN
If there are node in the given graph that are unreachable
from @var{start}, such nodes are ignored and not included
in the result.
@c JP
与えられたグラフの中に@var{start}から到達不可能なノードがあった場合、
それは単に無視され、結果に含まれません。
@c COMMON

@c EN
(A bit of explanation: Suppose you want to go to node X from @var{start}.
There may be multiple routes, but if you have to pass node Y no matter
which route you take, then Y is a dominator of X.  There may be
many dominators of X.  Among them, there's
always one dominator such that all other X's dominators are also
its dominators---in other words, the closest dominator of X---which
is called the immediate dominator of X.)
@c JP
(ちょっとした説明: @var{start}からノードXに行きたいとします。
複数の経路がありえますが、どの経路を取っても必ずノードYを通らないと
Xに行けない場合、YをXの支配ノード(dominator)と呼びます。
支配ノードは複数ありえますが、その中で一つだけ、他のXの支配ノード全てが
そのノードの支配ノードでもあるようなノードがあります(言い換えれば、
Xに一番「近い」支配ノードです)。それをXの直接支配ノードと呼びます。)
@c COMMON

@c EN
Let's see an example.  You have this directed graph:
@c JP
例を見てみましょう。こんな有向グラフがあるとします。
@c COMMON

@example
          A (start)
          |
          v
          B <-------+
          |         |
    ------+-----    |
    |          |    |
    v          v    |
    C -------> D ---+
    |          |
    v          v
    E <------- F
@end example

@c EN
Let's represent the graph by a list of @code{(x y z ...)} where @code{x}
can directly go to either @code{y z ...}.
@c JP
このグラフをリストのリストで表現してみましょう。
ここで、内側のリスト@code{(x y z ...)}は、@code{x}からは@code{y}や@code{z}に
直接行ける、ということを表します。
@c COMMON

@example
(define *graph* '((A B)
                  (B C D)
                  (C D E)
                  (D F B)
                  (F E)))
@end example

@c EN
Then you can calculate the immediate dominator of each node as follows:
@c JP
すると、各ノードの直接支配ノードが次の通り計算できます。
@c COMMON

@example
(calculate-dominators 'A
  (^n (filter-map (^g (and (memq n (cdr g)) (car g))) *graph*))
  (^n (assoc-ref *graph* n '()))
  eq-comparator)
  @result{} ((E B) (F D) (D B) (C B) (B A))
@end example

@c EN
That is, @code{E}'s immediate dominator is @code{B},
@code{F}'s is @code{D}, and so on.
@c JP
つまり、@code{E}の直接支配ノードは@code{B}であり、
@code{F}のは@code{D}である、という具合です。
@c COMMON

@c EN
The result itself can be viewed as a tree.  It is called a dominator tree.
@c JP
この結果自体を木と解釈することができます。これを支配木(dominator tree)と呼びます。
@c COMMON

@example
              F
              |
              v
        E     D     C
        |     |     |
        |     v     |
        +---> B <---+
              |
              v
              A
@end example
@end defun


@c ----------------------------------------------------------------------
@node Determine isomorphism, The longest common subsequence, Calculate dominator tree, Library modules - Utilities
@section @code{util.isomorph} - Determine isomorphism
@c NODE 同型判定, @code{util.isomorph} - 同型判定

@deftp {Module} util.isomorph
@mdindex util.isomorph
@c EN
Provides a procedure that determines whether two structures are
isomorphic.
@c JP
二つの構造が同型かどうかを判定する手続きを提供するモジュールです。
@c COMMON
@end deftp

@defun isomorphic? obj1 obj2 :optional context
@c MOD util.isomorph
@c EN
Returns @code{#t} if @var{obj1} and @var{obj2} are isomorphic.

@var{context} is used if you want to call @code{isomorphic?}
recursively inside @code{object-isomorphic?} described below.
@c JP
@var{obj1}と@var{obj2}が同型であれば@code{#t}を返します。

省略可能な引数@var{context}は、下で説明する@code{object-isomorphic?}
の中から@code{isomorphic?}を再帰的に呼び出す場合に使います。
@c COMMON

@example
(isomorphic? '(a b) '(a b)) @result{} #t

(define x (cons 0 0))
(define y (cons 0 0))
(isomorphic? (cons x x)
             (cons x y))
 @result{} #f
(isomorphic? (cons x x)
             (cons y y))
 @result{} #t
@end example
@end defun

@deffn {Generic Function} object-isomorphic? obj1 obj2 context
@c MOD util.isomorph
@c EN
With this method, you can customize how to determine isomorphism of
two objects.  Basically, you will call @code{isomorphic?} recursively
for each slots of object you want to traverse; the method should return
@code{#t} if all of the test succeeds, or return @code{#f} otherwise.
@var{context} is an opaque structure
that keeps the traversal context, and you should pass it to
@code{isomorphic?} as is.

The default method returns @code{#t} if @var{obj1} and @var{obj2} are
equal (in the sense of @code{equal?}).
@c JP
このメソッドで、二つのオブジェクトの同型判定処理をカスタマイズできます。
基本的には、オブジェクトのトラバースしたいスロットに対して@code{isomorphic?}を順に適用し、
全てが成功すれば@code{#t}を、一つでも失敗すれば@code{#f}を返すようにします。
@var{context}はトラバースのコンテクストを保持しているオブジェクトです。そのまま
@code{isomorphic?}に渡して下さい。

デフォルトメソッドは、@var{obj1}と@var{obj2}が@code{equal?}の意味で等しければ
@code{#t}を返します。
@c COMMON
@end deffn

@c ----------------------------------------------------------------------
@node The longest common subsequence, Levenshtein edit distance, Determine isomorphism, Library modules - Utilities
@section @code{util.lcs} - The longest common subsequence
@c NODE 最長共通サブシーケンス, @code{util.lcs} - 最長共通サブシーケンス

@deftp {Module} util.lcs
@mdindex util.lcs
@c EN
This module implements the algorithm to find the longest common subsequence
of two given sequences.  The implemented algorithm is based on
Eugene Myers' O(ND) algorithm 
(Eugene Myers, An O(ND) Difference Algorithm and Its Variations,
@i{Algorithmica} Vol. 1 No. 2, pp. 251-266, 1986.).

One of the applications of this algorithm is to calculate
the difference of two text streams;
see @ref{Calculate difference of text streams}.
@c JP
このモジュールは、与えられた2つのシーケンスの最長共通サブシーケンスを見つける
アルゴリズムを実装しています。アルゴリズムは、Eugene Myersの
O(ND)アルゴリズムに基づいています
(Eugene Myers, An O(ND) Difference Algorithm and Its Variations,
@i{Algorithmica} Vol. 1 No. 2, pp. 251-266, 1986.)。

このアルゴリズムを使うアプリケーションの1つは、2つのテキストストリームの
相違点を計算する@ref{Calculate difference of text streams}です。
@c COMMON
@end deftp

@defun lcs seq-a seq-b :optional eq-fn
@c MOD util.lcs
@c EN
Calculates and returns the longest common sequence of
two lists, @var{seq-a} and @var{seq-b}.
Optional @var{eq-fn} specifies
the comparison predicate; if omitted, @code{equal?} is used.
@c JP
2つのリスト、@var{seq-a}と@var{seq-b}の最長共通シーケンスを計算して
返します。オプションの@var{eq-fn}では、比較を行う述語を指定します。
省略されると、@code{equal?}が使われます。
@c COMMON

@example
(lcs '(x a b y) '(p a q b))
 @result{} (a b)
@end example
@end defun

@defun lcs-with-positions seq-a seq-b :optional eq-fn
@c MOD util.lcs
@c EN
This is the detailed version of @code{lcs}.
The arguments are the same.

Returns a list of the following structure:
@c JP
@code{lcs}の詳細バージョンです。引数は同じです。

以下の構造のリストを返します。
@c COMMON

@example
(@var{length} ((@var{elt} @var{a-pos} @var{b-pos}) @dots{}))
@end example

@c EN
@var{Length} is an integer showing the length of the found LCS.
What follows is a list of elements of LCS; each sublist
consists of the element, the integer position of the element
in @var{seq-a}, then the integer position of the element in @var{seq-b}.
@c JP
@var{length}は、見つかったLCS(最長共通サブシーケンス)の長さを表す整数です。
それに続くのは、LCSの要素のリストで、その要素を構成するそれぞれのサブリスト、
@var{seq-a}の中での要素の位置(整数)、@var{seq-b}の中での要素の位置(整数)
となります。
@c COMMON

@example
(lcs-with-positions '(a) '(a))
 @result{} (1 ((a 0 0)))

(lcs-with-positions '(x a b y) '(p q a b))
 @result{} (2 ((a 1 2) (b 2 3)))

(lcs-with-positions '(x a b y) '(p a q b))
 @result{} (2 ((a 1 1) (b 2 3)))

(lcs-with-positions '(x y) '(p q))
 @result{} (0 ())
@end example
@end defun

@defun lcs-fold a-proc b-proc both-proc seed a b :optional eq-fn
@c MOD util.lcs
@c EN
A fundamental iterator over the "edit list" derived from
two lists @var{a} and @var{b}.

@var{A-proc}, @var{b-proc}, @var{both-proc} are all procedures
that take two arguments.   The second argument is a intermediate
state value of the calculation.  The first value is an element
only in @var{a} for @var{a-proc}, or an element only in @var{b}
for @var{b-proc}, or an element in both @var{a} and @var{b}
for @var{both-proc}.  The return value of each procedure is used
as the state value of the next call of either one of the procedures.
@var{Seed} is used as the initial value of the state value.
The last state value is returned from @code{lcs-fold}.

The three procedures are called in the following order: Suppose the sequence
@var{a} consists of @var{a'}@var{c}@var{a''}, and @var{b} consists of
@var{b'}@var{c}@var{b''}, where @var{a'}, @var{b'}, @var{a''}, and @var{b''}
are subsequences, and @var{c} is the head of the
LCS of @var{a} and @var{b}.   Then @var{a-proc} is called first on
each element in @var{a'}, @var{b-proc} is called second on
each element in @var{b'}, then @var{both-proc} is called on @var{c}.
Afterwards, the process is repeated using @var{a''} and @var{b''}.
@c JP
2つのリスト@var{a}と@var{b}から引き出された``編集リスト''に対する
基本的なイテレータです。

@var{a-proc}、@var{b-proc}、@var{both-proc}は全て2引数を取る手続きです。
2番目の引数は、計算の中間の値です。最初の値は、@var{a-proc}では@var{a}にしかない要素、
@var{b-proc}では@var{b}にしかない要素、@var{both-proc}では@var{a}と@var{b}の両方に
ある要素となります。それぞれの手続きが返す値は、次に呼び出される手続きのうちの1つの
状態を表す値として使われます。@var{seed}は、状態を表す値の初期値として使われます。
@code{lcs-fold}が返す値は、最後の状態を表す値です。

これらの3つの手続きは、以下の順番で呼ばれます。ここでは、シーケンス@var{a}は
@var{a'}@var{c}@var{a''}、@var{b}は@var{b'}@var{c}@var{b''}となっているとすると、
ここでは@var{a'}、@var{b'}、@var{a''}、@var{b''}はサブシーケンスで、
@var{c}は@var{a}と@var{b}のLCSの先頭になります。そして、@var{a-proc}はまず
@var{a'}のそれぞれの要素に対して呼ばれ、@var{b-proc}が@var{b'}のそれぞれの
要素に対して呼ばれ、@var{both-proc}が@var{c}に対して呼ばれます。
その後、このプロセスは@var{a''}と@var{b''}を使って繰り返されます。
@c COMMON
@end defun

@defun lcs-edit-list a b :optional eq-fn
@c MOD util.lcs
@c EN
Calculates 'edit-list' from two lists @var{a} and @var{b}, which is
the smallest set of commands (additions and deletions) that changes
@var{a} into @var{b}.
This procedure is built on top of @code{lcs-fold} above.

Returns a list of @emph{hunk}s, which is a contiguous section of
additions and deletions.  Each hunk consists of a list of
directives, which is a form of:
@c JP
2つのリスト@var{a}と@var{b}から``編集リスト''を計算します。それは、
@var{a}を@var{b}に変更するためのコマンド(追加と削除)の最小セットです。
この手続きは、上の@code{lcs-fold}の上に構築されています。
@c COMMON
@example
(@var{+}|@var{-} @var{position} @var{element})
@end example

@c EN
Here's an example.  Suppose @var{a} and @var{b} are the following
lists, respectively.
@c JP
例を挙げます。@var{a}と@var{b}がそれぞれ以下のようなリストだとします。
@c COMMON

@example
@var{a} @equiv{} ("A" "B" "C" "E" "H" "J" "L" "M" "N" "P")
@var{b} @equiv{} ("B" "C" "D" "E" "F" "J" "K" "L" "M" "R" "S" "T")
@end example

@c EN
Then, @code{(lcs-edit-list a b equal?)} returns the following list.
@c JP
すると、@code{(lcs-edit-list a b equal?)}は以下のリストを返します。
@c COMMON
@example
(((- 0 "A"))
 ((+ 2 "D"))
 ((- 4 "H") (+ 4 "F"))
 ((+ 6 "K"))
 ((- 8 "N") (- 9 "P") (+ 9 "R") (+ 10 "S") (+ 11 "T"))
)
@end example
@c EN
The result consists of five hunks.  The first hunk consists of
one directive, @code{(- 0 "A")}, which means the element @code{"A"}
at the position 0 of list @var{a} has to be deleted.
The second hunk also consists of one directive, @code{(+ 2 "D")},
meaning the element @code{"D"} at the position 2 of list @var{b}
has to be added.  The third hunk means @code{"H"} at the position
4 of list @var{a} should be removed and @code{"F"} at the position
4 of list @var{b} should be added, and so on.

If you are familiar with Perl's Algorithm::Diff module, you may
notice that this is the same structure that its @code{diff} procedure
returns.
@c JP
結果は5つの片からなります。最初のものは1つのディレクティブ、@code{(- 0 ``A'')}から
なり、これはリスト@var{a}の位置0にある要素@code{``A''}が削除されることを意味します。
2番目のものはまた1つのディレクティブ、@code{(+ 2 ``D'')}からなり、これは
リスト@var{b}の位置2にある要素@code{``D''}が追加されることを意味します。
3番目のものは、リスト@var{a}の位置4にある@code{``H''}は削除され、リスト@var{b}の
位置4にある@code{``F''}が追加される、などとなります。

もしあなたがPerlのAlgorithm::Diffモジュールを良く知っていれば、
その@code{diff}手続きが返すものと同じ構造だということが分かるでしょう。
@c COMMON
@end defun

@c ----------------------------------------------------------------------
@node Levenshtein edit distance, Pattern matching, The longest common subsequence, Library modules - Utilities
@section @code{util.levenshtein} - Levenshtein edit distance
@c NODE Levenshtein編集距離, @code{util.levenshtein} - Levenshtein編集距離

@deftp {Module} util.levenshtein
@mdindex util.levenshtein
@c EN
This module provides procedures to calculate edit distance between
two sequences.  Edit distance is the minimum number of edit operations
required to match one sequence to another.
Three algorithms are implemented:
@c JP
このモジュールは二つのシーケンスの間の編集距離を計算する手続きを提供します。
編集距離とは、ひとつのシーケンスからもうひとつのシーケンスへと変更する
編集操作の数です。3つのアルゴリズムが実装されています。
@c COMMON

@table @asis
@item Levenshtein distance
@c EN
Count deletion of one element, insertion of one element,
and substitution of one element.
@c JP
1要素の削除、1要素の追加、1要素の置き換えそれぞれを1操作と数えます。
@c COMMON
@item Damerau-Levenshtein distance
@c EN
Besides deletion, insertion and substitution, we allow transposition
of adjacent elements.
@c JP
削除、追加、置き換えに加え、隣合った要素の入れ替えも1操作と数えます。
@c COMMON
@item Restricted edit distance
@c EN
Also called optimal string alignment distance.  Like Damerau-Levenshtein,
but once transposition is applied, no further editing on those elements
are allowed.
@c JP
Optimal string alignmentとも呼ばれます。Damerau-Levenshteinと似ていますが、
隣合った要素の入れ替えを行った場合、それらの要素は以降の編集を受けません。
@c COMMON
@end table

@c EN
These algorithms are often used to compare strings, but the procedures
in this module can handle any type of sequence (@pxref{Sequence framework}).
@c JP
これらのアルゴリズムは文字列に対して使われることが多いですが、
このモジュールの手続きはシーケンスになら何でも使えます
(@ref{Sequence framework}参照)。
@c COMMON
@end deftp

@defun l-distance seq-A seq-B :key elt= cutoff
@defunx l-distances seq-A seq-Bs :key elt= cutoff
@defunx re-distance seq-A seq-B :key elt= cutoff
@defunx re-distances seq-A seq-Bs :key elt= cutoff
@defunx dl-distance seq-A seq-B :key elt= cutoff
@defunx dl-distances seq-A seq-Bs :key elt= cutoff
@c MOD util.levenshtein
@c EN
Calculates Levenshtein distance (@code{l-*}), restricted edit
distance (@code{re-*}) and Damerau-Levenshtein distance (@code{dl-*})
between sequences, respectively.  Each algorithm comes in two 
flavors: The singular form @code{*-distance} takes two sequences,
@var{seq-A} and @var{seq-B}, and calculates distance between them.
The plural form @code{*-distances} takes a sequence @var{seq-A}
and a list of sequences @var{seq-Bs}, and calculates distances
between @var{seq-A} and each in @var{seq-Bs}.
@c JP
それぞれ、与えられたシーケンス間のLevenshtein距離(@code{l-*})、
Restricted edit距離(@code{re-*})およびDamerau-Levenshtein距離(@code{dl-*})を
計算します。アルゴリズム毎にふたつのAPIが提供されます。
単数形の@code{*-distance}は、二つのシーケンス@var{seq-A}と@var{seq-B}を取り、
両者の間の距離を計算します。
複数形の@code{*-distances}は、一つのシーケンス@var{seq-A}と
シーケンスのリスト@var{seq-Bs}をとり、@var{seq-Bs}の各シーケンスと
@var{seq-A}との距離を計算します。
@c COMMON

@c EN
If you need to calculate distances from a single sequence to many
sequences, using the plural version is much faster than repeatedly
calling the singular version, for the plural version can reuse internal
data structures and save allocation and setup time.
@c JP
あるシーケンスと、多数のシーケンスとの間の距離を計算したいなら、
単数形のAPIを繰り返し呼ぶより複数形のAPIを使う方が効率的です。
複数形のAPIでは内部で使うデータ構造を再利用するので、
重複するアロケーションと初期化の時間を節約できます。
@c COMMON

@c EN
Sequences can be any object that satisfy the @code{<sequence>} protocol
(@pxref{Sequence framework}).
@c JP
シーケンスは、@code{<sequence>}プロトコルを満足するオブジェクトであれば
何でも構いません (@ref{Sequence framework}参照)。
@c COMMON

@c EN
The keyword argument @var{elt=} is used to compare elements in
the sequences.  Its default is @code{eqv?}.
@c JP
キーワード引数@var{elt=}はシーケンスの要素同士を比較するのに使われます。
デフォルトは@code{eqv?}です。
@c COMMON

@c EN
The keyword argument @var{cutoff} must be, if given, a nonnegative
exact integer.  Once the possible minimum distance between two sequences
becomes greater than this number, the algorithm stops and gives @code{#f}
as the result, and moves on to the next calculation.
This is useful when you run the algorithm on large set of sequences
and you only need to look for the pairs closer than the certain limit.
@c JP
キーワード引数@var{cutoff}は非負の正確な整数でなければなりません。与えられた場合、
二つのシーケンスの距離を比較していて、それが@var{cutoff}以上になることがわかったら、
それ以上の計算を打ち切り@code{#f}を結果とします。
これは、特にたくさんのシーケンスから、ごく限られた限度以下の距離を持つものを探す
場合に便利です。
@c COMMON

@c EN
In our implementation, Levenshtein is the fastest, Damerau-Levenshtein
is the slowest and Restricted edit is somewhere inbetween.  If you don't
need to take into account of transpositions, use Levenshtein; it counts
2 for @code{cat} -> @code{act}, while other algorithms yield 1 for it.
If you need to consider transpositions, choose either
@code{re-} or @code{dl-}.  The catch in @code{re-} is that it does not
satisfy triangular inequality, i.e. for given three sequences X, Y and Z,
(Damerau-)Levenshtein distance L always satisfy
L(X;Z) <= L(X;Y) + L(Y;Z), but restricted edit distance doesn't
guarantee that.
@c JP
現在の実装ではだいたい、Levenshteinが最も速く、Damerau-Levenshteinが最も遅く、
Restricted editがその中間です。置換を1操作と考える必要がなければ、
Levenshteinを使うのが良いでしょう。@code{cat}から@code{act}は
Levenshtein距離では2ですが他の距離では1です。
置換を1操作とする必要があれば、@code{re-}か@code{dl-}を
使うことになります。@code{re-}の落とし穴は、それが三角不等式を満たさないことです。
つまり、3つのシーケンスX, Y, Zがある時、
(Damerau-)Levenshtein距離Lは常に
L(X;Z) <= L(X;Y) + L(Y;Z) を満たしますが、Restricted edit距離には
その保証がありません。
@c COMMON

@example
(l-distance "cat" "act")  @result{} 2
(l-distances "cat" '("Cathy" "scathe" "stack")
  :elt= char-ci=?)
  @result{} (2 3 4)

(re-distance "cat" "act") @result{} 1

(re-distances "pepper"
  '("peter" "piper" "picked" "peck" "pickled" "peppers")
  :cutoff 4)
  @result{} (2 2 4 4 #f 1)

(dl-distance '(a b c d e) '(c d a b e)) @result{} 4
@end example

@c EN
Note: If you pass a list of sequences to the second argument
of the singular version by accident, you might not get an error immediately
because a list is also a sequence.
@c JP
註: 単数形のAPIの第2引数にうっかりシーケンスのリストを渡してしまった場合でも、
直ちにエラーになるとは限らないことに注意。リスト自体もシーケンスだからです。
@c COMMON
@end defun

@c ----------------------------------------------------------------------
@node Pattern matching, SLIB-compatible record type, Levenshtein edit distance, Library modules - Utilities
@section @code{util.match} - Pattern matching
@c NODE パターンマッチング, @code{util.match} - パターンマッチング

@deftp {Module} util.match
@mdindex util.match
@c EN
This module is a port of Andrew Wright's pattern matching macro library.
It is widely used in the Scheme world, and ported to various Scheme
implementations, including Chez Scheme, PLT Scheme, Scheme48, Chicken,
and SLIB.
It is similar to, but more powerful than
Common Lisp's @code{destructuring-bind}.
@c JP
このモジュールは Andrew Wright のパターンマッチングマクロライブラリを
ポートしたものです。このライブラリは Scheme 界では広くつかわれており、
Chez Scheme、PLT Scheme、Scheme48、Chicken および SLIB を含む、様々な
Scheme の実装にポートされています。この機能は Common Lisp の
@code{destructuring-bind} に似ていますがより強力です。
@c COMMON

@c EN
This version retains compatibility of the original Wright's macro,
except (1) @var{box} is not supported since Gauche doesn't have one,
and (2) structure matching is integrated to Gauche's object system.
@c JP
この版では、オリジナルの Wright's macro のマクロとの互換性が保たれて
います。ただし、例外がふたつあって、それは、(1) @var{box} はサポートされて
いません。Gauche にそれがないからです。(2) 構造のマッチングは Gauche の
オブジェクトシステムに統合されています。
@c COMMON
@end deftp

@c EN
We show a list of APIs first, then the table of complete syntax of
patterns, followed by examples.
@c JP
まず API のリストを示し、それからパターンの完全な構文のテーブルを示し、
そして例を示します。
@c COMMON

@c EN
@subheading Pattern matching API
@c JP
@subheading パターンマッチング API
@c COMMON

@defmac match expr clause @dots{}
@c MOD util.match
@c EN
Each @var{clause} is either one of the followings:
@c JP
それぞれの @var{clause} は以下のうちどちらかです。
@c COMMON
@example
(@var{pat} @var{body} @dots{})
(@var{pat} (=> @var{identifier}) @var{body} @dots{})
@end example

@c EN
First, the @var{expr} is matched against @var{pat} of each clauses.
The detailed syntax of the pattern is explained below.
@c JP
まず、@var{expr} を各節の @var{pat} に照合します。パターンの詳しい
構文については後述します。
@c COMMON

@c EN
If a matching @var{pat} is found, the @emph{pattern variables} in
@var{pat} are bound to the corresponding elements in @var{expr}, then
@var{body} @dots{} are evaluated.  Then @code{match} returns the value(s)
of the last expression of @var{body} @dots{}.
@c JP
@var{pat} にマッチする部分が見つかれば、@var{pat} 中の @emph{パターン変数}
は、@var{expr} 中の対応する要素に束縛され、その後、@var{body} @dots{}
が評価されます。@code{match}は@var{body} @dots{}の最後の式の値を返します。
@c COMMON

@c EN
If the clause is the second form, @var{identifier} is also bound
to the failure continuation of the @var{clause}.  It is a
procedure with no arguments, and when called, it jumps back to
the matcher as if the matching of @var{pat} is failed, and
@code{match} continues to try the rest of clauses.
So you can perform extra tests
within @var{body} @dots{} and if you're not satisfied you can reject
the match by calling @code{(@var{identifier})}.  See the examples
below for more details.
@c JP
節が 2つ目の形式である場合、@var{identifier} は @var{clause} の失敗継続
に束縛されます。これは引数をもたない手続きで、呼ばれると、あたかも、
@var{pat} の照合に失敗したかの如くマッチャーに戻り、@code{match} が
残りの節について試行を続けます。それゆえ、@var{body} @dots{} 内部で
追加のテストを実行することが可能で、もし、満足いくものでなければ、
@code{(@var{identifier})} を呼ぶことで、照合結果を拒絶することができます。
より詳しくは、後述の例を見てください。
@c COMMON

@c EN
If no @var{pat} matches, @code{match} reports an error.
@c JP
どの @var{pat} もマッチしなければ、@code{match} はエラーを報告します。
@c COMMON
@end defmac

@defmac match-lambda clause @dots{}
@c MOD util.match
@c EN
Creates a function that takes one argument and performs @code{match} on it,
using @var{clause} @dots{}.  It's functionally equivalent to the following
expression:
@c JP
ひとつの引数をとり、それに対して @var{clause} @dots{} を用いて、
@code{match} を実行する関数を生成します。機能としては以下の式と同等です。
@c COMMON
@example
(lambda (expr) (match expr @var{clause} @dots{}))
@end example

@c EN
Example:
@c JP
例:
@c COMMON

@example
(map (match-lambda
       ((item price-per-lb (quantity 'lbs))
        (cons item (* price-per-lb quantity)))
       ((item price-per-lb (quantity 'kg))
        (cons item (* price-per-lb quantity 2.204))))
     '((apple      1.23 (1.1 lbs))
       (orange     0.68 (1.4 lbs))
       (cantaloupe 0.53 (2.1 kg))))
 @result{} ((apple . 1.353) (orange . 0.952)
            (cantaloupe . 2.4530520000000005))
@end example
@end defmac

@defmac match-lambda* clause @dots{}
@c MOD util.match
@c EN
Like @code{match-lambda}, but performs @code{match} on the list of
whole arguments.
It's functionally equivalent to the following expression:
@c JP
@code{match-lambda} と同じですが、@code{match} をすべての引数のリスト
に対して実行します。機能としては以下の式と同等です。
@c COMMON
@example
(lambda expr (match expr @var{clause} @dots{}))
@end example
@end defmac

@defmac match-let ((pat expr) @dots{}) body-expr @dots{}
@defmacx match-let name ((pat expr) @dots{}) body-expr @dots{}
@defmacx match-let* ((pat expr) @dots{}) body-expr @dots{}
@defmacx match-letrec ((pat expr) @dots{}) body-expr @dots{}
@c MOD util.match
@c EN
Generalize @code{let}, @code{let*}, and @code{letrec} to allow
patterns in the binding position rather than just variables.
Each @var{expr} is evaluated, and then matched to @var{pat},
and the bound pattern variables are visible in
@var{body-expr} @dots{}.
@c JP
束縛部分が単なる変数ではなく、パターンを許す、一般化された @code{let}、
@code{let*} および @code{letrec} です。
各 @var{expr} が評価され、その後、@var{pat} と照合され、束縛された
パターン変数が @var{body-expr} @dots{} から見えるようになります。
@c COMMON

@example
(match-let (
             (((ca . cd) ...)   '((a . 0) (b . 1) (c . 2)))
           )
  (list ca cd))
 @result{} ((a b c) (0 1 2))
@end example

@c EN
If you're sick of parenthesis, try @code{match-let1} below.
@c JP
括弧はうんざりという向きには、以下の @code{match-let1} をおためしあれ。
@c COMMON
@end defmac

@defmac match-let1 pat expr body-expr @dots{}
@c MOD util.match
@c EN
This is a Gauche extension and isn't found in the original Wright's code.
This one is equivalent to the following code:
@c JP
これは Gauche での拡張で、オリジナルの Wright のコードにはありません。
これは以下のコードと同等です。
@c COMMON
@example
(match-let ((@var{pat} @var{expr})) @var{body-expr} @dots{})
@end example

@c EN
Syntactically, @code{match-let1} is very close to the Common Lisp's
@code{destructuring-bind}.
@c JP
構文としては @code{match-let1} は Common Lisp の @code{destructuring-bind}
に非常によく似ています。
@c COMMON

@example
(match-let1 ('let ((var val) ...) body ...)
            '(let ((a b) (c d)) foo bar baz)
  (list var val body))
 @result{} ((a c) (b d) (foo bar baz))
@end example
@end defmac

@defmac match-define pat expr
@c MOD util.match
@c EN
Like toplevel @code{define}, but allows a pattern instead of variables.
@c JP
トップレベルの @code{define} と同様ですが、変数の代りにパターンが許されます。
@c COMMON

@example
(match-define (x . xs) (list 1 2 3))

x  @result{} 1
xs @result{} (2 3)
@end example

@end defmac

@c EN
@subheading Pattern syntax
@c JP
@subheading パターンの構文
@c COMMON

@c EN
Here's a summary of pattern syntax. The asterisk @code{(*)}
after explanation means Gauche's extension which does not present
in the original Wright's code.
@c JP
ここにあるのはパターンの構文の要約です。説明の後にあるアスタリスク
@code{(*)} はオリジナルの Wright のコードにはない、Gauche の拡張で
あることを意味します。
@c COMMON

@c EN
@example
pat : @var{patvar}                       ;; anything, and binds pattern var
    | @b{_}                            ;; anything
    | ()                           ;; the empty list
    | #t                           ;; #t
    | #f                           ;; #f
    | @var{string}                       ;; a string
    | @var{number}                       ;; a number
    | @var{character}                    ;; a character
    | '@var{sexp}                        ;; an s-expression
    | '@var{symbol}                      ;; a symbol (special case of s-expr)
    | (@var{pat1} ... @var{patN})              ;; list of n elements
    | (@var{pat1} ... @var{patN} . @var{patN+1})     ;; list of n or more
    | (@var{pat1} ... @var{patN} @var{patN+1} ooo)   ;; list of n or more, each element
                                   ;;   of remainder must match @var{patN+1}
    | #(@var{pat1} ... @var{patN})             ;; vector of n elements
    | #(@var{pat1} ... @var{patN} @var{patN+1} ooo)  ;; vector of n or more, each element
                                   ;;   of remainder must match @var{patN+1}
    | (@b{$} @var{class} @var{pat1} ... @var{patN})      ;; an object (@var{patK} matches in slot order)
    | (@b{struct} @var{class} @var{pat1} ... @var{patN}) ;; ditto (*)
    | (@b{@@} @var{class} (@var{slot1} @var{pat1}) ...)   ;; an object (using slot names) (*)
    | (@b{object} @var{class} (@var{slot1} @var{pat1}) ...) ;; ditto (*)
    | (@b{=} @var{proc} @var{pat})                 ;; apply proc, match the result to pat
    | (@b{and} @var{pat} ...)                ;; if all of pats match
    | (@b{or} @var{pat} ...)                 ;; if any of pats match
    | (@b{not} @var{pat} ...)                ;; if all pats don't match at all
    | (@b{?} @var{predicate} @var{pat} ...)        ;; if predicate true and all pats match
    | (@b{set!} @var{patvar})                ;; anything, and binds setter
    | (@b{get!} @var{patvar})                ;; anything, and binds getter
    | `qp                          ;; a quasi-pattern

patvar : a symbol except @b{_}, @b{quote}, @b{$}, @b{struct}, @b{@@}, @b{object}, @b{=}, @b{and}, @b{or},
         @b{not}, @b{?}, @b{set!}, @b{get!}, @b{quasiquote}, @b{...}, @b{___}, @b{..@i{k}}, @b{__@i{k}}.

@c @b doesn't work well in pdf version, so we conditionalize...
@ifnottex
ooo : @b{...}                          ;; zero or more
    | @b{___}                          ;; zero or more
    | @b{..@i{k}}                          ;; @i{k} or more, where @i{k} is an integer.
                                   ;;   Example: @b{..1}, @b{..2} ...
    | @b{__@i{k}}                          ;; @i{k} or more, where @i{k} is an integer.
                                   ;;   Example: @b{__1}, @b{__2} ...
@end ifnottex
@iftex
ooo : ...                          ;; zero or more
    | ___                          ;; zero or more
    | ..@slanted{k}                          ;; @i{k} or more, where @i{k} is an integer.
                                   ;;   Example: ..1, ..2 ...
    | __@slanted{k}                          ;; @i{k} or more, where @i{k} is an integer.
                                   ;;   Example: __1, __2 ...
@end iftex

@end example
@c JP
@example
pat : @var{patvar}                       ;; 任意のオブジェクトにマッチし、patvarを束縛
    | @b{_}                            ;; 任意のオブジェクト
    | ()                           ;; 空リスト
    | #t                           ;; #t
    | #f                           ;; #f
    | @var{string}                       ;; 文字列
    | @var{number}                       ;; 数
    | @var{character}                    ;; 文字
    | @var{keyword}                      ;; キーワード (*)
    | '@var{sexp}                        ;; Ｓ式
    | '@var{symbol}                      ;; シンボル(Ｓ式の特殊ケース)
    | (@var{pat1} ... @var{patN})              ;; n 要素のリスト
    | (@var{pat1} ... @var{patN} . @var{patN+1})     ;; n 以上の要素を含むリスト
    | (@var{pat1} ... @var{patN} @var{patN+1} ooo)   ;; n 以上の要素を含むリスト、残りの各要素は
                                   ;; @var{patN+1} にマッチしなければならない
    | #(@var{pat1} ... @var{patN})             ;; n 要素のベクタ
    | #(@var{pat1} ... @var{patN} @var{patN+1} ooo)  ;; n 以上の要素を含むベクタ、残りの各要素は
                                   ;; @var{patN+1} にマッチしなければならない
    | (@b{$} @var{class} @var{pat1} ... @var{patN})      ;; オブジェクト (@var{patK} はスロット順でマッチ)
    | (@b{struct} @var{class} @var{pat1} ... @var{patN}) ;; 同上 (*)
    | (@b{@@} @var{class} (@var{slot1} @var{pat1}) ...)  ;; オブジェクト (スロット名を使う) (*)
    | (@b{object} @var{class} (@var{slot1} @var{pat1}) ...) ;; 同上 (*)
    | (@b{=} @var{proc} @var{pat})                 ;; procを適用し、結果を pat にマッチさせる
    | (@b{and} @var{pat} ...)                ;; すべての pat にマッチするか
    | (@b{or} @var{pat} ...)                 ;; マッチする pat があるか
    | (@b{not} @var{pat} ...)                ;; どの pat もマッチしないか
    | (@b{?} @var{predicate} @var{pat} ...)        ;; predicate が真、かつ、全 pat がマッチ
    | (@b{set!} @var{patvar})                ;; 任意のオブジェクトにマッチし、セッタを束縛
    | (@b{get!} @var{patvar})                ;; 任意のオブジェクトにマッチし、ゲッタを束縛
    | `qp                          ;; 擬似パターン

patvar : a symbol except @b{_}, @b{quote}, @b{$}, @b{struct}, @b{@@}, @b{object}, @b{=}, @b{and}, @b{or},
         @b{not}, @b{?}, @b{set!}, @b{get!}, @b{quasiquote}, @b{...}, @b{___}, @b{..k}, @b{__k}.

@c @b doesn't work well in pdf version, so we conditionalize...
@ifnottex
ooo : @b{...}                          ;; ゼロまたはそれ以上
    | @b{___}                          ;; ゼロまたはそれ以上
    | @b{..@i{k}}                          ;; @i{k} またはそれ以上。@i{k}は整数。
                                   ;;   例: @b{..1}, @b{..2} ...
    | @b{__@i{k}}                          ;; @i{k} またはそれ以上。@i{k}は整数。
                                   ;;   例: @b{__1}, @b{__2} ...
@end ifnottex
@iftex
ooo : ...                          ;; ゼロまたはそれ以上
    | ___                          ;; ゼロまたはそれ以上
    | ..@slanted{k}                          ;; @i{k} またはそれ以上。@i{k}は整数。
                                   ;;   例: ..1, ..2 ...
    | __@slanted{k}                          ;; @i{k} またはそれ以上。@i{k}は整数。
                                   ;;   例: __1, __2 ...
@end iftex

@end example
@c COMMON

@itemize @bullet
@item
@c EN
A bare symbol is a "pattern variable"; it matches anything, and
the matched part of the expression is bound to the symbol.
The following symbols have special meanings and cannot be used
as a pattern variable: @code{_}, @code{quote}, @code{$}, @code{struct},
@code{@@}, @code{object}, @code{=}, @code{and}, @code{or},
@code{not}, @code{?}, @code{set!}, @code{get!}, @code{quasiquote},
@code{...}, @code{___}, and @code{..k} and @code{__k} where @emph{k} is
an integer.
@c JP
素のシンボルは「パターン変数」で、あらゆるものとマッチし、
式のマッチした部分がそのシンボルに束縛されます。
以下のシンボルは特別な意味をもち、パターン変数としては使えません。
@code{_}、@code{quote}、@code{$}、@code{struct}、@code{@@}、@code{object}、
@code{=}、@code{and}、@code{or}、@code{not}、@code{?}、@code{set!}、
@code{get!}、@code{quasiquote}、@code{...}、@code{___} および
@code{..k} と @code{__k} (ここで、@emph{k} は整数)。
@c COMMON

@item
@c EN
A symbol @code{_} matches anything, without binding a pattern variable.
It can be used to show "don't care" placeholder.
@c JP
シンボル @code{_} はあらゆるものマッチし、パターン変数は束縛しません。
プレースホルダであることを示すのに用います。
@c COMMON

@item
@c EN
Literals such as emptylist, booleans, strings, numbers, characters and
keywords match the same object (in the sense of @code{equal?}).
@c JP
空リスト、真偽値、文字列、数、文字およびキーワードのリテラルは
(@code{equal?}という意味で)同じオブジェクトとマッチします。
@c COMMON

@item
@c EN
Quoted expression matches the same expression (in the sense of @code{equal?}).
You can use a quoted symbol to match the symbol itself.
@c JP
クウォートされた式は(@code{equal?} という意味で)同じ式とマッチします。
クウォートされたシンボルをそれ自身とマッチさせるのに使えます。
@c COMMON

@item
@c EN
A keyword, without a quote, used to match the same keyword object.
Since we're in the process of unifying keywords and symbols, the user is 
recommended to write keywords with a quote in a pattern in order to match
the keyword in the input.  @xref{Keyword and symbol integration}, for
the details.
@c JP
キーワードは、以前はクオート無しで同じキーワードにマッチしていました。
しかし現在は、キーワードとシンボルの統合に移行中なので、キーワードにマッチさせるために
パターンにキーワードを含める際には常にクオートしてください。
詳しくは@ref{Keyword and symbol integration}参照。
@c COMMON

@item
@c EN
A list and a vector in general match a list or a vector whose elements
matches the elements in the pattern recursively, unless the first element
of the list is one of the special symbols listed above, it has a special
meaning.
@c JP
通常リストおよびベクタは、それぞれ、パターン中の要素にマッチする要素を
もつリストまたはベクタとマッチします。ただし、最初の要素が上であげた
特別なシンボルではない限りです。そのような場合には特別な意味を持ちます。
@c COMMON

@c EN
As a special case, the last element of a vector or a list can be
followed by a symbol @code{...}.  In that case, the pattern just before
the symbol @code{...} can be applied repeatedly until it consumes all the
elements in the given expression.  A symbol @code{___} can be used
in place of @code{...}; it is useful when you want to produce a pattern
by syntax-rules macro.
@c JP
特別な場合として、ベクタあるいはリストの最後の要素のあとにシンボル
@code{...} を付加することができます。この場合には、@code{...} シンボル
直前のパターンが与えられた式のすべての要素を尽すまで繰り返し適用されます。
シンボル @code{___} は @code{...} の場所で使えます。構文規則マクロによって
パターンを生成したいときに便利です。
@c COMMON

@c EN
For a list pattern, you can also use a symbol @code{..1}, @code{..2},
@dots{}, which specifies the minimum number of repetition.
@c JP
リストのパターンに対しては、シンボル @code{..1}、@code{..2}、@dots{} が
使えます。これは繰り返しの最小値を指定するものです。
@c COMMON

@item
@c EN
@code{($ class pat1 @dots{})} matches an instance of a class @code{class}.
Each pattern @code{pat1} @dots{} matches each value of slots,
in order of @code{(class-slots class)} by default.
(Records are exception; they match the same order as their
default constructor since 0.9.6.)
@c JP
@code{($ class pat1 @dots{})} は @code{class} クラスのインスタンスと
マッチします。各パターン @code{pat1} @dots{} はデフォルトではスロットの各値と
@code{(class-slots class)} の順にマッチします。
(レコードは例外で、0.9.6からデフォルトコンストラクタの順序と同じ順序になりました。)
@c COMMON

@c EN
@code{(struct class pat1 @dots{})} has the same meaning.  Although
the original Wright's code doesn't have @code{struct}, PLT Scheme has
it in its extended match feature, and it is more descriptive.
@c JP
@code{(struct class pat1 @dots{})} は同じ意味です。オリジナルの
Wright のコードには、@code{struct} はありませんが、PLT Scheme の拡張
照合機能にはそなわっています。こちらの方がより説明的です。
@c COMMON

@c EN
This is an adaptation of the original feature that can match structures.
It is useful to match a simple instance that you know the order of
slots; for example, a simple record created by @code{define-record-type}
(@pxref{Record types}) would be easy to match by positioned values.
@c JP
これはオリジナルの機能を構造(structure)にもマッチするように調整した
ものです。スロットの順番が予め分るような単純なインスタンスをマッチする
のに便利です。たとえば、@code{define-record-type} (@ref{Record types}参照)で作成した
簡単なレコードは簡単に位置指定された値でマッチすることができます。
@c COMMON

@c EN
If the instance's class uses inheritances, it is a bit difficult to
match by positions.  You can use @code{@@} or @code{object} pattern
below to match using slot names.
@c JP
インスタンスのクラスが継承を使っている場合、位置によるマッチを
おこなうのは少々難しくなります。以下の @code{@@} あるいは @code{object}
パターンを使って、スロット名でマッチを行うことができます。
@c COMMON

@item
@c EN
@code{(object class (slot1 pat1) @dots{})} matches an instance
of a class @code{class} whose value of @var{slot1} @dots{} matches
@var{pat1} @dots{}.  This is Gauche's extension.  @code{@@} can be
used in place of @code{object}, but @code{object} is recommended
because of descriptiveness.
@c JP
@code{(object class (slot1 pat1) @dots{})} は
@var{slot1} @dots{} の値が @var{pat1} @dots{} にマッチするような
@code{class} クラスのインスタンスとマッチします。これは、
Gauche の拡張です。@code{@@} は @code{object} と同じ場所で使えます。
ただし、@code{object} の方が説明的でわかりやすいので、こちらを
推奨します。
@c COMMON

@item
@c EN
@code{(= proc pat)} first applies @var{proc} to the corresponding
expression, then match the result with @var{pat}.
@c JP
@code{(= proc pat)} は最初に @var{proc} を対応する式に適用し、
その結果と @var{pat} をマッチさせます。
@c COMMON

@item
@c EN
@code{(and pat @dots{})}, @code{(or pat @dots{})}, and
@code{(not pat @dots{})} are boolean operations of patterns.
@c JP
@code{(and pat @dots{})}、@code{(or pat @dots{})} および
@code{(not pat @dots{})} はパターンの真偽値演算子です。
@c COMMON

@item
@c EN
@code{(? predicate pat @dots{})} first applies a predicate to the
corresponding expression, and if it returns true, applies each
@code{pat} @dots{} to the expression.
@c JP
@code{(? predicate pat @dots{})} は最初、述語を対応する式に適用し、
真が返れば、各 @code{pat} @dots{} をその式に適用します。
@c COMMON

@item
@c EN
@code{(set! patvar)} matches anything, and binds an one-argument
procedure to a pattern variable @var{patvar}.  If the procedure is
called, it replaces the value of matched pattern for the given argument.
@c JP
@code{(set! patvar)} はあらゆるものにマッチし、一引数の手続きを
パターン変数 @var{patvar} に束縛します。その手続きが呼ばれると、
マッチしたパターンの値を与えられた引数で置き換えます。
@c COMMON

@item
@c EN
@code{(get! patvar)} matches anything, and binds a zero-argument
procedure to a pattern variable @var{patvar}.  If the procedure is
called, it returns the matched value.
@c JP
@code{(get! patvar)} はあらゆるものにマッチし、引数なしの手続きを
パターン変数 @var{patvar} に束縛します。その手続きが呼ばれると、
マッチしたパターンの値を返します。
@c COMMON

@item
@c EN
@code{`qp} is a quasipattern.  @var{qp} is quoted, in the sense
that it matches itself, @emph{except} the pattern that is unquoted.
(Don't confuse quasipattern to quasiquote, though the functions are
similar.  Quasiquote turns off evaluation except unquoted subtree.
Quasiquote turns off the special pattern syntax except unquoted subtree.
See the examples below).
@c JP
@code{`qp}はquasipatternです。@var{qp}は、クオートされたパターンと同様、
それそのものにマッチしますが、その中にアンクオートされているパターンがあると、
その部分だけは通常のパターンとして解釈されます。
(準クオート(quasiquote)とquasipatternを混同しないようにしてください。
機能的に両者は似ていますが、準クオートがアンクオートされた部分木以外の
部分の評価をoffにするのに対し、quasipatternはアンクオートされた部分木
以外の部分のパターン構文を無効にします。下の例も参照して下さい。)
@c COMMON
@end itemize

@c EN
@subheading Pattern examples
@c JP
@subheading パターン例
@c COMMON

@c EN
A simple structure decomposition:
@c JP
単純な構造の分解
@c COMMON
@example
(match '(0 (1 2) (3 4 5))
  [(a (b c) (d e f))
   (list a b c d e f)])
 @result{} (0 1 2 3 4 5)
@end example

@c EN
Using predicate patterns:
@c JP
述語パターンの使用
@c COMMON
@example
(match 123
  [(? string? x) (list 'string x)]
  [(? number? x) (list 'number x)])
 @result{} (number 123)
@end example

@c EN
Extracting variables and expressions from @code{let}.
Uses repetition and predicate patterns:
@c JP
@code{let} から変数と式を取り出す
反復および述語パターンの利用
@c COMMON
@example
(define let-analyzer
  (match-lambda
    [('let (? symbol?)
           ((var expr) ...)
       body ...)
     (format "named let, vars=~s exprs=~s" var expr)]
    [('let ((var expr) ...)
       body ...)
     (format "normal let, vars=~s exprs=~s" var expr)]
    [_
     (format "malformed let")]))

(let-analyzer '(let ((a b) (c d)) e f g))
 @result{} "normal let, vars=(a c) exprs=(b d)"

(let-analyzer '(let foo ((x (f a b)) (y (f c d))) e f g))
 @result{} "named let, vars=(x y) exprs=((f a b) (f c d))"

(let-analyzer '(let (a) b c d))
 @result{} "malformed let"
@end example

@c EN
Using @code{=} function application.  The pattern variable @var{m}
is matched to the result of application of the regular expression.
@c JP
@code{=} 関数適用。パターン変数 @var{m} は正規表現の適用結果にマッチする
@c COMMON
@example
(match "gauche-ref.texi"
  ((? string? (= #/(.*)\.([^.]+)$/ m))
   (format "base=~a suffix=~a" (m 1) (m 2))))
 @result{} "base=gauche-ref suffix=texi"
@end example

@c EN
An example of quasipattern.   In the first expression, the
pattern except @code{value} is quoted, so the symbols @code{the},
@code{answer}, and @code{is} are not pattern variables but literal
symbols.   The second expression shows that; input symbol @code{was}
does not match the literal symbol @code{is} in the pattern.
If we don't use quasiquote, all symbols in the pattern are pattern
variables, so any four-element list matches as the third expression shows.
@c JP
quasipatternの例です。最初の式では、パターンのうち@code{value}以外の
部分がクオートされたことになり、従ってシンボル@code{the}, @code{answer},
@code{is}はパターン変数ではなくリテラルシンボルとなります。
2番目の式がそのことを示しています。入力にあるシンボル@code{was}は
パターンの@code{is}とマッチしません。もしクオートを行わないと、
全てのシンボルはパターン変数となるので、3番目の例に示すように
任意の4つの要素を持つリストとマッチしてしまいます。
@c COMMON
@example
(match '(the answer is 42)
  [`(the answer is ,value) value]
  [else #f])
 @result{} 42

(match '(the answer was 42)
  [`(the answer is ,value) value]
  [else #f])
 @result{} #f

(match '(a b c d)
  [(the answer is value) value]
  [else #f])
 @result{} d
@end example

@c EN
An example of matching records.
The following code implements ``rotation''
operation to balance a red-black tree.
@c JP
レコードのマッチングの例です。
次のコードは赤黒木をバランスさせる「ローテーション」操作を実装しています。
@c COMMON

@example
(define-record-type T #t #t
  color left value right)

(define (rbtree-rotate t)
  (match t
    [(or ($ T 'B ($ T 'R ($ T 'R a x b) y c) z d)
         ($ T 'B ($ T 'R a x ($ T 'R b y c)) z d)
         ($ T 'B a x ($ T 'R ($ T 'R b y c) z d))
         ($ T 'B a x ($ T 'R b y ($ T 'R c z d))))
     (make-T 'R (make-T 'B a x b) y (make-T 'B c z d))]
    [else t]))
@end example

@c ----------------------------------------------------------------------
@node SLIB-compatible record type, Relation framework, Pattern matching, Library modules - Utilities
@section @code{util.record} - SLIB-compatible record type
@c NODE SLIB-互換のレコード型, @code{util.record} - SLIB-互換のレコード型

@deftp {Module} util.record
@mdindex util.record
@c EN
This module provides a Guile and SLIB compatible record type API.
It is built on top of Gauche's object system.

See also @ref{Record types}, which provides a convenience macro
@code{define-record-type}.
@c JP
このモジュールは、Guile と SLIB とに互換性のあるレコード型 API を提供します。
これは、Gauche のオブジェクトシステム上に構築されています。

便利なマクロ @code{define-record-type} を提供する @ref{Record types} も
参照してください。
@c COMMON
@end deftp

@defun make-record-type type-name field-names
@c MOD util.record
@c EN
Returns a new class which represents a new record type.
(It is what is called @emph{record-type descriptor} in SLIB).
In Gauche, the new class is a subclass of @code{<record>}
(see @ref{Record types}).

@var{type-name} is a string that is used for debugging purposes.
It is converted to a symbol and set as the name of the new class.
@var{field-names} is a list of symbols of the names of fields.
Each field is implemented as a slot of the new class.
@c JP
あらしいレコード型を表わす新しいクラスを返します。
(これは SLIB では @emph{レコード型記述子}とよばれているものです。)
Gauche では、この新しいクラスは @code{<record>} のサブクラスです
(@ref{Record types} 参照)。

@var{type-name} はデバッグの目的で使われる文字列です。
これは、シンボルに変換され、この新しいクラスの名前として設定されます。
@var{field-names} はフィールド名のシンボルのリストです。
各々のフィールドはこの新しいクラスのスロットとして実装されます。
@c COMMON
@end defun

@c EN
In the following procedures, @var{rtd} is the record class
created by @code{make-record-type}.
@c JP
以下の手続きでは、@var{rtd} は @code{make-record-type} によって
生成されたクラスです。
@c COMMON

@defun record-constructor rtd :optional field-names
@c MOD util.record
@c EN
Returns a procedure that constructs an instance
of the record type of given @var{rtd}.  The returned
procedure takes exactly as many arguments as @var{field-names},
which defaults to @code{'()}.  Each argument sets the initial
value of the corresponding field in @var{field-names}.
@c JP
与えられた @var{rtd} レコード型のインスタンスを構築する手続きを
返します。返された手続きは @var{field-names} とちょうど同じ数の
引数をとります。@var{field-names} のデフォルトは @code{'()} です。
それぞれの引数は @var{field-names} の対応するフィールドの初期値を
設定します。
@c COMMON
@end defun

@defun record-predicate rtd
@c MOD util.record
@c EN
Returns a procedure that takes one argument, which returns @code{#t}
iff the given argument is of type of @var{rtd}.
@c JP
一つの引数をとり、与えられた引数が @var{rtd} と同じ型であり、その場合に
限り @code{#t} を返す手続きを返します。
@c COMMON
@end defun

@defun record-accessor rtd field-name
@c MOD util.record
@c EN
Returns an accessor procedure for the field named by @var{field-name}
of type @var{rtd}.  The accessor procedure takes an instance of
@var{rtd}, and returns the value of the field.
@c JP
@var{rtd} 型の @var{field-name} によって名付けられたフィールドへの
アクセサ手続きを返します。このアクセサ手続きは、@var{rtd} のインスタンスを
一つとり、そのフィールドの値を返します。
@c COMMON
@end defun

@defun record-modifier rtd field-name
@c MOD util.record
@c EN
Returns a modifier procedure for the field named by @var{field-name}
of type @var{rtd}.  The modifier procedure takes two arguments,
an instance of @var{rtd} and a value, and sets the value to
the specified field.
@c JP
@var{rtd} 型の @var{field-name} によって名付けられたフィールドへの
モディファイア手続きを返します。このモディファイア手続きは、
@var{rtd} のインスタンスと値のふたつの引数をとり、その引数を
指定されたフィールドに設定します。
@c COMMON
@end defun

@example
(define rtd (make-record-type "my-record" '(a b c)))

rtd @result{} #<class my-record>

(define make-my-record (record-constructor rtd '(a b c)))

(define obj (make-my-record 1 2 3))

obj @result{} #<my-record 0x819d9b0>

((record-predicate? rtd) obj)  @result{} #t

((record-accessor rtd 'a) obj) @result{} 1
((record-accessor rtd 'b) obj) @result{} 2
((record-accessor rtd 'c) obj) @result{} 3

((record-modifier rtd 'a) obj -1)

((record-accessor rtd 'a) obj) @result{} -1
@end example

@c ----------------------------------------------------------------------
@node Relation framework, Stream library, SLIB-compatible record type, Library modules - Utilities
@section @code{util.relation} - Relation framework
@c NODE リレーションフレームワーク, @code{util.relation} - リレーションフレームワーク

@deftp {Module} util.relation
@mdindex util.relation
@c EN
Provides a set of common operations for relations.
@c JP
リレーションに対する共通の操作を提供します。
@c COMMON

@c EN
Given set of values S1, S2, ..., Sn, a relation R is a set of tuples
such that the first element of a tuple is from S1, the second from
S2, ..., and the n-th from Sn.  In another word, R is a subset of
Cartesian product of S1, ..., Sn.
(The definition, as well as the term @emph{relation}, is taken
from the Codd's 1970 paper,
"A Relational Model of Data for Large Shared Data Banks", in
CACM 13(6) pp.377--387.)
@c JP
値の集合を S1, S2, ..., Sn とするとリレーション R はタプルの集合で、
タプルの最初の要素は S1 からの値で、2番目は S2 から、で n 番目は
Sn からとなっている。いいかえれば、R は S1, ..., Sn の直積です。
(この定義と@emph{リレーション}という用語は 1970年のCoddのペーパー
"A Relational Model of Data for Large Shared Data Banks", in
CACM 13(6) pp.377--387.によるものです。)
@c COMMON

@c EN
This definition can be applied to various datasets: A set of Gauche
object system instances is a relation, if you view each instance as
a tuple and each slot value as the actual values.  A list of lists can be a
relation.  A stream that reads from CSV table produces a relation.
Thus it would be useful to provide a module that implements generic
operations on relations, no matter how the actual representation is.
@c JP
この定義はいろいろなデータベースセットにあてはまります。各インスタンス
をタプルとみなし、各スロット値を実際の値と見ると、Gaucheのオブジェクト
システムの集合はリレーションです。リストのリストもリレーションです。
CSVテーブルからの読み出しストリームはリレーションを生成します。このよ
うことから、表現に依存しないリレーション上のジェネリックな操作を実装す
るモジュールを用意することは有意義です。
@c COMMON

@c EN
From the operational point of view, we can treat any datastructure
that provides the following four methods; @code{relation-rows},
which retrieves a collection of tuples (rows);
@code{relation-column-names}, @code{relation-accessor}, and
@code{relation-modifier}, which provide the means to access
meta-information.
All the rest of relational operations are built on top of
those primitive methods.
@c JP
操作という観点からいえば、以下の4つのメソッドがあれば、どのようなデー
タ構造もあつかえます。タプルのコレクション(行)を取り出す
@code{relation-rows}、それから、@code{relation-column-names}、
@code{relation-accessor}、@code{relation-modifier}、これらはメタ情報に
アクセスする方法を提供しています。これ以外のすべてのリレーション操作は
上のプリミティブメソッドを使って組まれています。
@c COMMON

@c EN
A concrete implementation of relation can use duck typing,
i.e. it doesn't need to inherit a particular base class to
use the relation methods.  However, for the convenience,
a base class @code{<relation>} is provided in this module.
It works as a mixin class---a concrete class typically wants
to inherit @code{<relation>} and @code{<collection>} or
@code{<sequence>}.  Check out the sample implementations
in the @file{lib/util/relation.scm} in the source tree, if
you're curious.
@c JP
リレーションの具体的な実装にはダックタイピングが適用できます。
すなわち、リレーションメソッドを使うのに特定のベースクラスを継承する必
要はありません。しかし、利便のためにこのモジュールには、ベースクラス
@code{<relation>}が用意されています。これは、ミックスインクラスのよう
な働きをします。具象クラスは典型的には@code{<relation>}および
@code{<collection>}または@code{<sequence>}を継承することになるでしょう。
興味があれば、ソースツリーにある@file{lib/util/relation.scm}に含まれる
サンプル実装をチェックするとよいでしょう。
@c COMMON

@c EN
This module is still under development.
The plan is to build useful relational operations on top of the
common methods.
@c JP
このモジュールは現時点では開発途上にあります。計画では共通メソッド上に
有用なリレーション操作関数群を構築することになっています。
@c COMMON
@end deftp

@c EN
@subheading Basic class and methods
@c JP
@subheading 基本となるクラスとメソッド
@c COMMON

@deftp {Class} <relation>
@clindex relation
@c MOD util.relation
@c EN
An abstract base class of relations.
@c JP
リレーションの抽象ベースクラス
@c COMMON
@end deftp

@deffn {Method} relation-column-names (r <relation>)
@c MOD util.relation
@c EN
A subclass must implement this method.
It should return a sequence of names of the columns.
The type of column names is up to the relation; we don't
place any restriction on it, as far as they are different
each other in terms of @code{equal?}.
@end deffn
@c JP
サブクラスではこのメソッドを必ず実装しなければなりません。
カラムの名前のシーケンスを返す必要があります。カラム名の型はリレーショ
ンによります。@code{equal?}の意味で相互に異っているかぎり、カラム名に
ついて特に制限はありません。
@end deffn
@c COMMON

@deffn {Method} relation-accessor (r <relation>)
@c MOD util.relation
@c EN
A subclass must implement this method.
It should return a procedure that takes two arguments, a row from
the relation @var{r} and a column name, and returns the value
of the specified column.
@c JP
サブクラスではこのメソッドは必ず実装しなければなりまん。2つの引数をと
り、リレーション@var{r}の行とカラム名をとり、指定したカラムの値を返す
手続を返さなければなりません。
@c COMMON
@end deffn

@deffn {Method} relation-modifier (r <relation>)
@c MOD util.relation
@c EN
A subclass must implement this method. It should returns a procedure
that takes three arguments, a row from the relation @var{r}, a column
name, and a value to set.
@c JP
サブクラスではこのメソッドは必ず実装しなければなりまん。
3つの引数、リレーション@var{r}の行、カラム名、値をとり、その値をセット
する手続を返さなければなりません。
@c COMMON

@c EN
If the relation is read-only, this method returns @code{#f}.
@c JP
リレーションが読み込み専用の場合はこのメソッドは@code{#f}を返します。
@c COMMON
@end deffn

@deffn {Method} relation-rows (r <relation>)
@c MOD util.relation
@c EN
A subclass must implement this method.
It should return the underlying instance of @code{<collection>} or
its subclass (e.g.  @code{<sequence>})
@c JP
サブクラスではこのメソッドは必ず実装しなければなりまん。
基盤となっている@code{<collection>}クラスまたはそのサブクラス(たとえば
@code{<sequence>})のインスタンスを返さなければなりません。
@c COMMON
@end deffn

@c EN
The rest of method are built on top of the above four methods.
A subclass of @code{<relation>} may overload some of the
methods below for better performance, though.
@c JP
のこりのメソッドは上の4つのメソッドを使って組まれています。とはいえ、
@code{<relation>} のサブクラスでは以下のメソッドを性能を得るためにオー
バーロードすることもできます。
@c COMMON

@deffn {Method} relation-column-name? (r <relation>) column
@c MOD util.relation
@c EN
Returns true iff @var{column} is a valid column name for the relation
@var{r}.
@c JP
@var{column}がリレーション@var{r}において有効なカラム名である場合にの
み真を返します。
@c COMMON
@end deffn

@deffn {Method} relation-column-getter (r <relation>) column
@deffnx {Method} relation-column-setter (r <relation>) column
@c MOD util.relation
@c EN
Returns a procedure to access the specified column of a row
from the relation @var{r}.  @code{Relation-column-getter}
should return a procedure that takes one argument, a row.
@code{Relation-column-setter} should return a procedure that
takes two arguments, a row and a new value to set.
@c JP
リレーション@var{r}の行の指定したカラムにアクセスする手続を返します。
@code{Relation-column-getter}は、1つの引数、行をとる手続きを返さなけれ
ばなりません。@code{Relation-column-setter}は2つの引数、行と新しくセッ
トする値を取る手続きを返さなければなりません。
@c COMMON

@c EN
If the relation is read-only, @code{relation-column-setter}
returns @code{#f}.
@c JP
リレーションが読み込み専用の場合は@code{relation-column-setter}
は@code{#f}を返します。
@c COMMON
@end deffn

@deffn {Method} relation-ref (r <relation>) row column :optional default
@c MOD util.relation
@c EN
@var{Row} is a row from the relation @var{r}.  Returns value of
the @var{column} in @var{row}.  If @var{column} is not a valid
column name, @var{default} is returned if it is given, otherwise
an error is signaled.
@c JP
@var{row}はリレーション@var{r}の行です。@var{row}の@var{column}の値を
返します。@var{column}が不正なカラム名である場合、@var{default}が与え
られていればそれを返し、そうでなければ、エラーを示すシグナルがあがりま
す。
@c COMMON
@end deffn

@deffn {Method} relation-set! (r <relation>) row column value
@c MOD util.relation
@c EN
@var{Row} is a row from the relation @var{r}.  Sets @var{value}
as the value of @var{column} in @var{row}.  This may signal
an error if the relation is read-only.
@c JP
@var{row}はリレーション@var{r}の行です。@var{value}を@var{row}の
@var{column}に設定します。リレーションが読み込み専用の場合には
エラーを示すシグナルがあがります。
@c COMMON
@end deffn

@deffn {Method} relation-column-getters (r <relation>)
@deffnx {Method} relation-column-setters (r <relation>)
@c MOD util.relation
@c EN
Returns full list of getters and setters.  Usually the default
method is sufficient, but the implementation may want to cache
the list of getters, for example.
@c JP
ゲッタとセッタの完全なリストを返します。通常はデフォルトのメソッドで十
分ですが、たとえばゲッタのリストをキャッシュしたいときもあるでしょう。
@c COMMON
@end deffn

@deffn {Method} relation-coercer (r <relation>)
@c MOD util.relation
@c EN
Returns a procedure that coerces a row into a sequence.
If the relation already uses a sequence to represent a row,
it can return row as is.
@c JP
行をシーケンスに変換する手続きを返します。行がすでにシーケンスで表現さ
れているリレーションであれば、行をそのまま返す手続きです。
@c COMMON
@end deffn

@deffn {Method} relation-insertable? (r <relation>)
@c MOD util.relation
@c EN
Returns true iff new rows can be inserted to the relation @var{r}.
@c JP
リレーション@var{r}に新しい行を挿入可能な場合にのみ真を返します。
@c COMMON
@end deffn

@deffn {Method} relation-insert! (r <relation>) row
@c MOD util.relation
@c EN
Insert a row @var{row} to the relation @var{r}.
@c JP
リレーション@var{r}に行@var{row}を挿入します。
@c COMMON
@end deffn

@deffn {Method} relation-deletable? (r <relation>)
@c MOD util.relation
@c EN
Returns true iff rows can be deleted from the relation @var{r}.
@c JP
リレーション@var{r}から行を削除可能である場合にのみ真を返します。
@c COMMON
@end deffn

@deffn {Method} relation-delete! (r <relation>) row
@c MOD util.relation
@c EN
Deletes a row @var{row} from the relation @var{r}.
@c JP
リレーション@var{r}から行@var{row}を削除します。
@c COMMON
@end deffn

@deffn {Method} relation-fold (r <relation>) proc seed column @dots{}
@c MOD util.relation
@c EN
Applies @var{proc} to the values of @var{column} @dots{} of each row,
passing @var{seed} as the state value.  That is, for each row in
@var{r}, @var{proc} is called as follows:
@c JP
@var{proc}を各行のカラム@var{column} @dots{} の値に適用します。
@var{seed}は状態の値として渡されます。すなわち、リレーション@var{r}の
各行ごとに以下のように@var{proc}を呼びます。
@c COMMON
@example

(@var{proc} @var{v_0} @var{v_1} @dots{} @var{v_i} @var{seed})

 where @var{v_k} = (relation-ref @var{r} @var{row} @var{column_k})

@end example

@c EN
The result of the call becomes a new seed value, and the final result
is returned from @var{relation-fold}.
@c JP
呼び出しの結果があたらしいシードの値となり、最終の結果が
@var{relation-fold}から返ります。
@c COMMON

@c EN
For example, if a relation has a column named @code{amount},
and you want to sum up all of them in a relation @var{r},
you can write like this:
@c JP
たとえば、リレーションが @code{amount} という名前のカラムをもつものと
し、リレーション @var{r} 内にあるそのカラムをすべて足しあわせたいとす
ると以下のように書けます。
@c COMMON
@example
(relation-fold r + 0 'amount)
@end example
@end deffn

@c EN
@subheading Concrete classes
@c JP
@subheading 具象クラス
@c COMMON

@deftp {Class} <simple-relation>
@clindex simple-relation
@c MOD util.relation
@end deftp

@deftp {Class} <object-set-relation>
@clindex object-set-relation
@c MOD util.relation
@end deftp

@c ----------------------------------------------------------------------
@node Stream library, Topological sort, Relation framework, Library modules - Utilities
@section @code{util.stream} - Stream library
@c NODE ストリームライブラリ, @code{util.stream} - ストリームライブラリ

@deftp {Module} util.stream
@mdindex util.stream
@c EN
This module provides a library of lazy streams, including the
functions and syntaxes defined in srfi-40 and srfi-41,
the latter of which became a part of R7RS large (as @code{(scheme stream)},

Gauche has a built-in lazy sequences (@pxref{Lazy sequences}), which is
a lazy stream integrated to a list so that you can use all list procedures
on it.  Lazy streams provided in this module are somewhat heavier than
lazy sequences and you need to use special procedures,
but it is strictly lazy (while a lazy sequence evaluates one element ahead)
and portable.
@c JP
このモジュールは遅延ストリームのライブラリを提供します。このモジュール
にはsrfi-40とsrfi-41で定義されている関数および構文が含まれています。
後者は@code{(scheme stream)}としてR7RS largeの一部になっています。

Gaucheには遅延ストリームとリストを統合したような、組み込みの遅延シーケンスがあります
(@ref{Lazy sequences})参照。そちらは通常のリスト手続きを使って扱うことができます。
このモジュールで提供される遅延ストームは、遅延シーケンスより重く、
扱うために専用の手続きが必要です。ただ、要素の評価は必要になるぎりぎりまで遅延され
(遅延シーケンスでは必要な要素のひとつ先まで評価されます)、またポータブルです。
@c COMMON
@end deftp

@menu
* Stream primitives::
* Stream constructors::
* Stream binding::
* Stream consumers::
* Stream operations::
@end menu

@node Stream primitives, Stream constructors, Stream library, Stream library
@subsection Stream primitives

@defun stream? obj
[R7RS stream]
@c MOD util.stream
@c EN
Returns @code{#t} iff @var{obj} is a stream created by a procedure
of @code{util.stream}.
@c JP
@var{obj}が@code{util.stream}の手続きによって作成されたストリームであ
る場合にかぎり@code{#t}を返します。
@c COMMON
@end defun

@defvar stream-null
[R7RS stream]
@c MOD util.stream
@c EN
The singleton instance of NULL stream.
@c JP
NULLストリームのシングルトンインスタンス。
@c COMMON
@end defvar

@defmac stream-cons object stream
[R7RS stream]
@c MOD util.stream
@c EN
A fundamental constructor of a stream.  Adds @var{object} to the
head of a @var{stream}, and returns a new stream.
@c JP
ストリームの基本構成子。@var{object}を@var{stream}の先頭に追加し、新し
いストリームを返します。
@c COMMON
@end defmac

@defun stream-null? obj
[R7RS stream]
@c MOD util.stream
@c EN
Returns @code{#t} iff @var{obj} is the null stream.
@c JP
@var{obj}がNULLストリームの場合にのみ@code{#t}を返します。
@c COMMON
@end defun

@defun stream-pair? obj
[R7RS stream]
@c MOD util.stream
@c EN
Returns @code{#t} iff @var{obj} is a non-null stream.
@c JP
@var{obj}がNULLストリームではないストリームのときにのみ@code{#t}を返します。
@c COMMON
@end defun

@defun stream-car s
[R7RS stream]
@c MOD util.stream
@c EN
Returns the first element of the stream @var{s}.
@c JP
ストリーム@var{s}の最初の要素を返します。
@c COMMON
@end defun

@defun stream-cdr s
[R7RS stream]
@c MOD util.stream
@c EN
Returns the remaining elements of the stream @var{s}, as a stream.
@c JP
ストリーム@var{s}の最初の要素を除いた残りの要素をストリームとして
返します。
@c COMMON
@end defun

@defmac stream-delay expr
[SRFI-40]
@c MOD util.stream
@c EN
Returns a stream which is a delayed form of @var{expr}.
@c JP
@var{expr}の遅延形式であるストリームを返します。
@c COMMON

@c EN
As a rule of thumb, any stream-producing functions should
wrap the resulting expression by @code{stream-delay}.
(Or you can use @code{stream-lambda}, @code{stream-let} or @code{stream-define},
described below.)
@c JP
原則として、ストリームを生成する関数はすべからく結果を
@code{stream-delay}でラップすべきです。
(以下に述べる@code{stream-lambda}, @code{stream-let}, @code{stream-define}を
使う手もあります)。
@c COMMON
@end defmac

@defmac stream-lambda formals body body2 @dots{}
[R7RS stream]
@c MOD util.stream
@c EN
A convenience macro to create a function that returns a stream.
Effectively, @code{(stream-lambda formals body body2 @dots{})} is the same
as @code{(lambda formals (stream-delay body body2 @dots{}))}.
@c JP
ストリームを返す関数を作る簡易マクロです。
@code{(stream-lambda formals body body2 @dots{})}は
@code{(lambda formals (stream-delay body body2 @dots{}))}と同じです。
@c COMMON
@end defmac

@node Stream constructors, Stream binding, Stream primitives, Stream library
@subsection Stream constructors

@defun stream obj @dots{}
[SRFI-40]
@c MOD util.stream
@c EN
Returns a new stream whose elements are @var{obj} @dots{}.
@c JP
要素が@var{obj} @dots{}であるような新しいストリームを返します。
@c COMMON

@c EN
Note: This differs from srfi-41's (@code{scheme.stream}'s) @code{stream},
which is a macro so that arguments are lazily evaluated.  Srfi-41's
@code{stream} is provided as @code{stream+} in this module.
@c JP
註：これはsrfi-41 (@code{scheme.stream})の@code{stream}とは異なります。
srfi-41の方はマクロで、引数の評価が遅延されます。srfi-41版はこのモジュールでは
@code{stream+}と言う名前で提供されます。
@c COMMON

@example
(stream 1 2 3))     @result{} @r{a stream that contains} (1 2 3)
(stream 1 (/ 1 0))) @result{} @r{error}
@end example
@end defun

@defmac stream+ expr @dots{}
@c MOD util.stream
@c EN
Returns a new stream whose elements are the result of @var{expr} @dots{}.

This is the same as srfi-41(@code{scheme.stream})'s @code{stream}.
Each @var{expr} isn't evaluated until it is accessed.
@c JP
要素が@var{expr} @dots{}の結果であるような新たなストリームを作って返します。

これはsrfi-41(@code{scheme.stream})の@code{stream}と同じです。
各@var{expr}はアクセスされるまで評価されません。
@c COMMON

@example
(define s (stream+ 1 (/ 1 0)))  ;; doesn't yield an error

(stream-car s)  @result{} 1

(stream-cadr s) @result{} @r{error}
@end example
@end defmac

@defun stream-unfold f p g seed
[R7RS stream]
@c MOD util.stream
@c EN
Creates a new stream whose element is determined as follows:

@itemize
@item
A ``go'' predicate @var{p} is called on the current seed value.
If it yields @code{#f}, the stream terminates.
@item
Otherwise, @code{(f s)} is the element of the stream,
and @code{(g s)} becomes the next seed value, where
@code{s} is the current seed value.  The initial seed value
is given by @var{seed}.
@end itemize

Note: Unfortunately, the order of arguments differs from
other @code{*-unfold} procedures, which takes @code{p f g}
(predicate, value-generator and seed-generator).  Furthermore,
the predicate is stop-predicate (returning true stops iteration).
@c JP
次の手順で生成される要素をもつ新たなストリームを作成して返します。

@itemize
@item
「続行」述語@var{p}が現在のシード値を引数として呼ばれます。
もし@code{#f}が返されたら、ストリームはそこで終了です。
@item
そうでなければ、@code{s}を現在のシード値として、@code{(f s)}をストリームの
現在の要素とし、@code{(g s)}を次のシード値とします。
@var{seed}はシード値の初期値を与えます。
@end itemize

註：残念なことに、この手続きは他の @code{*-unfold} 系手続きと異なる順序で
引数を取ります。他の手続きは@code{p f g} (述語、値生成、シード生成) の順です。
さらに、他の手続きでは述語は停止する時に真を返します。
@c COMMON

@example
(stream->list
 (stream-unfold integer->char (cut < <> 58) (cut + 1 <>) 48))
 @result{} (#\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9)
@end example
@end defun

@defun stream-unfoldn f seed n
[SRFI-40]
@c MOD util.stream
@c EN
Creates @var{n} streams related each other, whose contents are
generated by @var{f} and @var{seed}.
@c JP
互いに関連する @var{n} 本のストリームを生成します。それぞれの内容は
@var{f}および@var{seed}を使って生成します。
@c COMMON

@c EN
The @var{f} is called with the current seed value,
and returns @code{@var{n}+1} values:
@c JP
@var{f}は現在のシード値とともに呼ばれ、@code{@var{n}+1}個の値
を返します。
@c COMMON
@example
(@var{f} @var{seed})
  => seed result_0 result_1 @dots{} result_n-1
@end example

@c EN
The first value is to be the next seed value.
@var{Result_k} must be one of the following forms:
@table @code
@item (val)
@var{val} will be the next car of @var{k}-th stream.
@item #f
No new information for @var{k}-th stream.
@item ()
The end of @var{k}-th stream has been reached.
@end table
@c JP
最初の値は次のシード値になります。@var{Result_k}は以下の形式のどれかで
なければなりません。
@table @code
@item (val)
@var{val}は@var{k}-番目のストリームの次のcar部になります。
@item #f
@var{k}-番目のストリームの新しい情報はありません。
@item ()
@var{k}-番目のストリームの最後に到達しました。
@end table
@c COMMON

@c EN
The following example creates two streams, the first one produces
an infinite series of odd numbers and the second produces evens.
@c JP
以下の例では2つのストリームが作られます。最初のものは奇数の無限ストリー
ムで、2つめのものは偶数の無限ストリームです。
@c COMMON

@example
gosh> (define-values (s0 s1)
        (stream-unfoldn (lambda (i)
                          (values (+ i 2)          ;; next seed
                                  (list i)         ;; for the first stream
                                  (list (+ i 1)))) ;; for the second stream
                        0 2))
#<undef>
gosh> (stream->list (stream-take s0 10))
(0 2 4 6 8 10 12 14 16 18)
gosh> (stream->list (stream-take s1 10))
(1 3 5 7 9 11 13 15 17 19)
@end example
@end defun

@defun stream-unfolds f seed
[R7RS stream]
@c MOD util.stream
@c EN
Like @code{stream-unfoldn}, but the number of created streams is
determined by the number fo return values from @var{f}.  See
@code{stream-unfoldn} above for the details.
@c JP
@code{stream-unfoldn}と似ていますが、結果のストリームの数は
@var{f}の戻り値の数により決定されます。詳しくは
上の@code{stream-unfoldn}の説明を参照してください。
@c COMMON
@end defun

@defun stream-constant obj @dots{}
[R7RS stream]
@c MOD util.stream
@c EN
Returns an infinite stream that repeats @var{obj} @dots{}.
@c JP
@var{obj} @dots{}を繰り返す無限ストリームを返します。
@c COMMON

@example
(stream->list 10 (stream-constant 1 2))
  @result{} (1 2 1 2 1 2 1 2 1 2)
@end example
@end defun

@defun make-stream n :optional init
@c MOD util.stream
@c EN
Creates a new stream of @var{n} elements of @var{init}.
If @var{init} is omitted, @code{#f} is used.
Specifying a negative number to @var{n} creates an infinite stream.
@c JP
@var{n}個の@var{init}を要素とする新しいストリームを生成します。
@var{init}が省略された場合@code{#f}が使われます。@var{n}を負の値にする
と無限ストリームが生成されます。
@c COMMON
@end defun

@defun stream-tabulate n init-proc
@c MOD util.stream
@c EN
Creates a new stream of @var{n} elements.
The @var{k}-th element is obtained by applying @var{init-proc}
to @var{k}.  Specifying a negative number to @var{n} creates
an infinite stream.
@c JP
@var{n}個の要素をもつ新しいストリームを生成します。@var{k}-番目の要素
は @var{init-proc} を @var{k} に適用して得られます。@var{n}を負の値にする
と無限ストリームが生成されます。
@c COMMON
@end defun

@defun stream-iota :optional count start step
@c MOD util.stream
@c EN
Creates a new stream of numbers, starting from @var{start}
and incrementing @var{step}.  The length of stream is maximum
integer not greater than nonnegative real number @var{count}.
The default values of @code{count}, @var{start} and @var{step} are
@code{+inf.0}, 0 and 1, respectively.

If @var{start} and @var{step} are exact, and @var{count} is exact or
infinite, a sequence of exact numbers are created.  Otherwise,
a sequence of inexact numbers are created.
@c JP
@var{start}からはじまり、@var{step}ずつ要素が増加する数値のストリーム
を生成します。ストリームの長さは非負の実数@var{count}を越えない最大の整数値です。
@var{count}, @var{start}, @var{step}のデフォルト値はそれぞれ
@code{+inf.0}, 0 および 1です。

@var{start}と@var{step}が正確数で、@var{count}が正確数か無限大の場合、
正確数のストリームが作られます。そうでなければ非正確数のストリームになります。
@c COMMON
@end defun

@defun stream-range start :optional end step
[R7RS stream]
@c MOD util.stream
@c EN
Creates a new stream of real numbers, starting from @var{start}
and stops before @var{end}, stepping by @var{step}.
If @var{end} is omitted, positive infinity is assumed.
If @var{step} is omitted, @code{1} is assumed if @var{end} is greater
than @var{start}, and @code{-1} if @var{end} is less than @var{start}.

The generated numbers are exact if @var{start} and @var{step} are exact
and @var{end} is either exact or infinite.  Otherwise, inexact numbers
are generated.

In R7RS @code{scheme.stream}, @var{end} argument is required.
@c JP
@var{start}から始まり@var{step}おきに@var{end}の手前まで続く実数のストリームを
作って返します。@var{end}が省略された場合は正の無限大が使われます。
@var{step}が省略された場合、@var{start}が@var{end}より小さければ@code{1}が、
大きければ@var{-1}が使われます。

@var{start}と@var{step}が正確数で、@var{end}が正確数か無限大の場合は、
正確数のシーケンスが、そうでない場合は非正確数のシーケンスが生成されます。

R7RSの@code{scheme.stream}では、@var{end}引数は必須です。
@c COMMON

@example
(stream->list (stream-range 0 10))
 @result{} (0 1 2 3 4 5 6 7 8 9)
@end example
@end defun

@defun stream-from start :optional step
[R7RS stream]
@c MOD util.stream
@c EN
This is yet another number sequence generator.  Generates an infinite
sequence whose @var{i}-th element is @code{(+ @var{start} (* i @var{step}))}.
If @var{step} is omitted, 1 is assumed.  If both @var{start} and @var{step}
are exact, exact numbers are generated.  Otherwise, inexact numbers are
generated.
@c JP
もうひとつの数値シーケンス生成手続きです。@var{i}番目の項が
@code{(+ @var{start} (* i @var{step}))}であるような無限シーケンスを返します。
@var{step}が省略されたら1が使われます。
@var{start}と@var{step}が正確数なら、正確数のシーケンスが、
そうでなければ非正確数のシーケンスが返されます。
@c COMMON
@end defun

@defun stream-iterate f seed
[R7RS stream]
@c MOD util.stream
@c EN
Returns a stream starting from @var{seed}, and each successive element
is calculated by @code{(@var{f} @var{s})} where @var{s} is the previous
element.
@c JP
@var{seed}を初期値とし、ひとつ前の要素@var{s}から次の要素を@code{(@var{f} @var{s})}で
計算するような無限長のストリームを返します。
@c COMMON

@example
(stream->list 5 (stream-iterate (cut cons 'x <>) '()))
  @result{} (() (x) (x x) (x x x) (x x x x))
@end example

@c EN
See also @code{literate} in @code{gauche.lazy} (@pxref{Lazy sequence utilities}).
@c JP
@code{gauche.lazy}の@code{literate}も参照
(@ref{Lazy sequence utilities}).
@c COMMON
@end defun

@defun stream-xcons a b
@c MOD util.stream
@c EN
@code{(stream-cons b a)}.  Just for convenience.
@c JP
@code{(stream-cons b a)}のこと。利便性のためだけにある。
@c COMMON
@end defun

@defun stream-cons* elt @dots{} stream
@c MOD util.stream
@c EN
Creates a new stream which appends @var{elt} @dots{} before @var{stream}.
@c JP
@var{stream}の前に@var{elt} @dots{}を連結した新しいストリームを生成し
ます。
@c COMMON
@end defun

@defun list->stream list
[R7RS stream]
@c MOD util.stream
@c EN
Returns a new stream whose elements are the elements in @var{list}.
@c JP
@var{list}の要素を要素とする新たなストリームを作って返します。
@c COMMON
@end defun

@defun string->stream string :optional tail-stream
@c MOD util.stream
@c EN
Converts a string to a stream of characters.  If an optional
@var{tail-stream} is given, it becomes the tail of the resulting
stream.
@c JP
文字列を文字のストリームに変換します。@var{tail-stream}が与えられた場合は、
文字ストリームの後にそれが付け加えられます。
@c COMMON

@example
@end example
(stream->list (string->stream "abc" (list->stream '(1 2 3))))
 @result{} (#\a #\b #\c 1 2 3)
@end defun

@defun stream-format fmt arg @dots{}
@c MOD util.stream
@c EN
Returns a stream which is a result of applying @code{string->stream}
to @code{(format fmt arg @dots{})}.
@c JP
@code{string->stream}を@code{(format fmt arg @dots{})}に適用した結果の
ストリームを返します。
@c COMMON
@end defun

@defun port->stream :optional iport reader closer
[R7RS stream]
@c MOD util.stream
@c EN
Creates a stream, whose elements consist of the items
read from the input port @var{iport}.
The default @var{iport} is the current input port.
The default @var{reader} is @code{read-char}.

The result stream terminates at the point where @var{reader}
returns EOF (EOF itself is not included in the stream).
The port won't be closed by default when it reaches EOF.

If @var{closer} is given, it is called with @var{iport} as
an argument just after @var{reader} reads EOF.  You can close the port
with it.

The @var{reader} and @var{closer} arguments are Gauche's extension.
R7RS @code{scheme.stream} only takes one optional argument, @var{iport}.
@c JP
@var{iport}から@var{reader}を使って読み出されるデータを要素とする新たなストリームを
作って返します。@var{iport}のデフォルトは現在の入力ポート、
@var{reader}のデフォルトは@code{read-char}です。

@var{reader}がEOFを返したらストリームの終端となります (EOF自体は
ストリームには含まれません)。
EOFに達してもポートはクローズされません。

もし@var{closer}引数が与えられたら、それが@var{iport}を引数として
EOFが読まれた直後に呼ばれます。そこでポートをクローズするこはできます。

@var{reader}と@var{closer}引数はR7RSの@code{scheme.stream}では
定義されない、Gaucheの拡張です。
@c COMMON
@end defun

@defun generator->stream gen
@c MOD util.stream
@c EN
Creates a lazy stream of values generated by a generator @var{gen}.
A generator is a thunk that returns a value every time it is called,
with returning EOF to indicate the end of the input.
@xref{Generators}, for the details of generators.
@c JP
ジェネレータ@var{gen}が生成する値の列からなる遅延ストリームを作って返します。
ジェネレータは引数を取らない手続きで、呼ばれる度に値を返し、EOFを返すことで
終端を示すものです(EOFはストリームには含まれません)。
詳しくは@ref{Generators}を参照してください。
@c COMMON

@c EN
See also @code{generator->lseq}, which is another way to get
a lazy sequence from a generator (@pxref{Lazy sequences}, for the details).
@c JP
似た手続きに、ジェネレータから遅延シーケンスを得る@code{generator->lseq}も
あります(@ref{Lazy sequences}参照)。
@c COMMON
@end defun


@defun iterator->stream iter
@c MOD util.stream
@c EN
A generic procedure to turn an internal iterator @var{iter}
into a stream of iterated results.
@c JP
イテレータ@var{iter}から遅延シーケンスを作る手続きです。
@c COMMON

@c EN
The @var{iter} argument is a procedure that takes two arguments,
@var{next} and @var{end}, where @var{next} is a procedure that takes
one argument and @var{end} is a thunk.
@var{Iter} is supposed to iterate over some set and call @var{next}
for each argument, then call @var{end} to indicate the end of
the iteration.  Here's a contrived example:
@c JP
@var{iter}は二つの引数@var{next}と@var{end}を取る手続きです。
@var{next}は一つの引数を取る手続き、@var{end}は引数を取らない手続きです。
@var{iter}手続きは、その中で何らかの値の集合に対して順に@var{next}手続きを呼び、
最後に@var{end}手続きを呼びます。次はわざとらしい例です:
@c COMMON

@example
(stream->list
 (iterator->stream
  (lambda (next end) (for-each next '(1 2 3 4 5)) (end))))
 @result{} (1 2 3 4 5)
@end example

@c EN
Internally @code{iterator->stream} uses the ``inversion of iterator''
technique, so that @var{iter} only iterates to the element that
are needed by the stream.  Thus @var{iter} can iterate over
an infinite set.  In the following example, @var{iter} is
an infinite loop calling @var{next} with increasing integers,
but only the first 10 elements are calculated because of
@code{stream-take}:
@c JP
内部的に、@code{iterator->stream}はいわゆる「イテレータの反転」テクニックを
使っていて、@var{iter}は必要なだけしかイテレーションを行いません。なので
@var{iter}は無限の要素を扱うこともできます。
例えば次の例では、@var{iter}は増加する整数に対して@var{next}を無限に呼び出す
ようになっていますが、@code{stream-take}によって最初の10要素しか計算されません。
@c COMMON

@example
(stream->list
 (stream-take
  (iterator->stream
   (lambda (next end)
     (let loop ((n 0)) (next n) (loop (+ n 1)))))
  10))
 @result{} (0 1 2 3 4 5 6 7 8 9)
@end example
@end defun

@defmac stream-of elt-expr clause @dots{}
[R7RS stream]
@c MOD util.stream
@c EN
Stream comprehension.  Returns a stream in which each element
is computed by @var{elt-expr}.   
The @var{clause} creates scope of @var{elt-expr}
and controls iterations.  Each @var{clause} can be one of the following
forms:
@c JP
ストリーム内包表記。各要素が@var{elt-expr}で計算されるストリームを返します。
@var{clause}は@var{elt-expr}のスコープを作り、繰り返しを制御します。
各@var{clause}は以下の形のいずれかです：
@c COMMON
@table @code
@item (@var{x} in @var{stream-expr})
@c EN
Iterate over @var{stream-expr}, binding @var{x} to each element in
each iteration.  The variable @var{x} is visible in successive @var{clause}s
and @var{elt-expr}
@c JP
@var{stream-expr}が返すストリームの各要素を、@var{x}に束縛して繰り返します。
変数@var{x}のスコープは後続の@var{clause}および@var{elt-expr}です。
@c COMMON
@item (@var{x} is @var{expr})
@c EN
Bind a variable @var{x} with the value of @var{expr}.  The variable @var{x}
is visible in successive @var{clause}s
and @var{elt-expr}.
@c JP
変数@var{x}に値@var{expr}の結果を束縛します。@var{x}のスコープは
後続の@var{clause}および@var{elt-expr}です。
@c COMMON
@item expr
@c EN
If @var{expr} evaluates to @code{#f}, this iteration is skipped without
generating a new element.
@c JP
@var{expr}が@code{#f}に評価されたらこの回は値を生成せずに打ちきられ、
次の繰り返しに進みます。
@c COMMON
@end table

@c EN
The following comprehension generates infinite sequence of pythagorean
triples:
@c JP
次の内包表記はピタゴラス数の無限シーケンスを生成します：
@c COMMON

@example
(define pythagorean-triples
  (stream-of (list a b c)
    (c in (stream-from 3))
    (b in (stream-range 2 c))
    (a in (stream-range 1 b))
    (= (square c) (+ (square b) (square a)))))

(stream->list 5 pythagorean-triples)
  @result{} ((3 4 5) (6 8 10) (5 12 13) (9 12 15) (8 15 17))
@end example
@end defmac

@node Stream binding, Stream consumers, Stream constructors, Stream library
@subsection Stream binding

@defmac define-stream (name . formals)  body body2 @dots{}
[R7RS stream]
@c MOD util.stream
@c EN
A convenient macro to define a procedure that yields a stream.
Same as the following form:
@c JP
ストリームを作って返す関数を手軽に定義するマクロです。
次のフォームと同じです:
@c COMMON

@example
(define (name . formals)
  (stream-delay
    (let () body body2 @dots{})))
@end example
@end defmac

@defmac stream-let loop-var ((var init) @dots{}) body body2 @dots{}
[R7RS stream]
@c MOD util.stream
@c EN
A handy macro to write a lazy named-let loop.  It is the same as the
following:
@c JP
lazyなnamed-letによるループを書くときに便利なマクロです。次のフォームと同じです:
@c COMMON
@example
(let loop-var ((var init) @dots{})
  (stream-delay
    (let () body body2 @dots{})))
@end example
@end defmac

@defmac stream-match stream-expr clause @dots{}
[R7RS stream]
@c MOD util.stream
@c EN
This allows accessing streams via simple pattern matching.
The @var{stream-expr} argument is evaluated and must yield a stream.
Each @var{clause}
must be either a form of @code{(@var{pattern} @var{expr})} or
@code{(@var{pattern} @var{fender} @var{expr})}.

The content of the stream is matched to each @var{pattern},
which must have one of the following forms:
@c JP
このマクロは簡単なパターンマッチングを使ってストリームの要素にアクセスします。
@var{stream-expr}はストリームを返す式でなければなりません。
各@var{clause}は@code{(@var{pattern} @var{expr})}か
@code{(@var{pattern} @var{fender} @var{expr})}という形です。

入力ストリームは各@var{pattern}に順マッチするかどうかテストされます。
@var{pattern}には以下の形のいずれかです:
@c COMMON

@table @code
@item ()
@c EN
Matches a null stream.
@c JP
空のストリームとマッチします。
@c COMMON
@item (@var{p0} @var{p1} @dots{})
@c EN
Matches a stream that has exactly the same number of elements as
the number of pattern elements.
@c JP
パターン内の要素の数と入力ストリームの要素数が一致した時にマッチします。
@c COMMON
@item (@var{p0} @var{p1} @dots{} . @var{pRest})
@c EN
Matches a stream that has at least the same number of elements as
the number of pattern elements except @var{pRest}.  The rest of stream
matches with @var{pRest}.
@c JP
入力ストリームの要素数が、@var{pRest}を除いたパターン内の要素の数以上であれば
マッチします。@var{pRest}にはストリームの残りがマッチします。
@c COMMON
@item @var{pRest}
@c EN
Matches an entire stream.
@c JP
入力ストリーム全体とマッチします。
@c COMMON
@end table

@c EN
Each pattern element can be an identifier or a literal underscore.  If it is
an identifier, it is bound to the matched element while evaluating
the corresponding @var{fender} and @var{expr}.
@c JP
パターンの各要素は識別子かリテラルのアンダースコア@code{_}です。
アンダースコア以外の識別子の場合は、それらが対応する入力ストリームの要素に
束縛された環境で@var{fender}と@var{expr}が評価されます。
@c COMMON

@c EN
If @var{fender} is present in the @var{clause}, it is evaluated; if
it yields @code{#f}, the match of the clause fails and next clauses will be
tried.
@c JP
もし@var{fender}があれば、まずそれが評価され、@code{#f}であったらその@var{clause}の
マッチは失敗となり、次の@var{clause}が試されます。
@c COMMON

@c EN
Otherwise, @var{expr} is evaluated and the result(s) becomes the result(s)
of @code{stream-match}.
@c JP
そうでなければ@var{expr}が評価され、その結果が@code{stream-match}の結果となります。
@c COMMON

@c EN
Only the elements from the stream that is required to match are accessed.
@c JP
入力ストリームの要素はマッチに必要なだけ取り出されます。
@c COMMON

@c EN
The following example defines a procedure to count the number of true
values in the stream:
@c JP
次の例は、ストリーム中の真の値の数を数えています:
@c COMMON

@example
(define (num-trues strm)
  (stream-match strm
    (() 0)
    ((head . tail) head (+ 1 (num-trues tail)))
    ((_ . tail) (num-trues tail))))

(num-trues (stream #f #f #t #f #t #f #t #t))
  @result{} 4
@end example
@end defmac

@node Stream consumers, Stream operations, Stream binding, Stream library
@subsection Stream consumers

@c EN
These procedures takes stream(s) and consumes its/their elements
until one of the streams is exhausted.
@c JP
これらの手続きはストリームを取り、その要素を消費し尽します。
@c COMMON

@defun stream-for-each func . streams
[R7RS stream]
@c MOD util.stream
@c EN
Applies @var{func} for each element of @var{streams}.
Terminates if one of @var{streams} reaches the end.
@c JP
@var{func}を@var{streams}の各要素に適用します。
@var{streams}が終端に達したところで停止します。
@c COMMON
@end defun

@defun stream-fold f seed stream
[R7RS stream]
@c MOD util.stream
@c EN
Apply @var{f} on the current seed value and an element from
@var{stream} to obtain the next seed value, and repeat it until
@var{stream} is exhausted, then returns the last seed value.
The initial seed value is given by @var{seed}.

Note: The argument order of @var{f} differs from other @code{*-fold}
procedures, e.g. @code{fold} (@pxref{Walking over lists}) takes
the element first, then the seed value.
@c JP
@var{f}を現在のシード値と@var{stream}の要素に適用し、その結果を次のシード値として
@var{stream}が終端に達するまで繰り返します。最初のシード値は@var{seed}引数で与えられます。
最後のシード値が返されます。

註: @var{f}の引数順は、他の@code{*-fold}系関数のそれと異なることに注意してください。
例えば@code{fold} (@ref{Walking over lists}参照) では最初に要素、次にシード値が
渡されます。
@c COMMON

@example
(stream-fold - 0 (stream 1 2 3 4 5))
  @result{} -15
@end example
@end defun

@node Stream operations,  , Stream consumers, Stream library
@subsection Stream operations

@defun stream-append stream @dots{}
[R7RS stream]
@c MOD util.stream
@c EN
Returns a new stream which is concatenation of given @var{stream}s.
@c JP
与えられた@var{stream}を全部つないだ新たなストリームを返します。
@c COMMON
@end defun

@defun stream-concat streams
@defunx stream-concatenate streams
[R7RS stream]
@c MOD util.stream
@c EN
R7RS @code{scheme.stream} defines @code{stream-concat}.  Gauche had
@code{stream-concatenate}, and keeps it for the backward compatibility.
Both are the same.

The @var{streams} argument is a stream of streams.  Returns a new stream
that is concatenation of them.  Unlike @code{stream-append}, @var{streams}
can generate infinite streams.
@c JP
R7RS @code{scheme.stream}は@code{stream-concat}を定義しました。
Gaucheには@code{stream-concatenate}があったので互換性のためにそちらも残しています。
どちらも同じです。

@var{streams}はストリームのストリームです。各ストリームを連結したストリームを作って
返します。@code{stream-append}と違い、@var{streams}は無限個のストリームを生成
することができます。
@c COMMON
@end defun


@defun stream-map func stream stream2 @dots{}
[R7RS stream]
@c MOD util.stream
@c EN
Returns a new stream, whose elements are calculated by
applying @var{func} to each element of @var{stream} @dots{}.
@c JP
@var{streams}の各要素に@var{func}を適用した値を要素とする新しいストリー
ムを返します。
@c COMMON
@end defun

@defun stream-scan func seed stream
[R7RS stream]
@c MOD util.stream
@c EN
Returns a stream of @code{@var{seed}}, @code{(@var{func} @var{seed} @var{e0})},
@code{(@var{func} (@var{func} @var{seed} @var{e0}) @var{e1})}, @dots{}, where
@var{e0}, @var{e1} @dots{} are the elements from the input @var{stream}.
If @var{stream} is finite, the result stream has one more elements than
the number of elements in the original stream.
@c JP
@code{@var{seed}}、
@code{(@var{func} @var{seed} @var{e0})}、
@code{(@var{func} (@var{func} @var{seed} @var{e0}) @var{e1})} @dots{}
で構成されるストリームを返します。ここで
@var{e0}、@var{e1} @dots{}は入力ストリーム@var{stream}の要素です。
@var{stream}が有限なら、その要素よりひとつ多い要素が出力ストリームには含まれます。
@c COMMON

@example
(stream->list
  (stream-scan xcons '() (stream 1 2 3 4 5)))
 @result{} (() (1) (2 1) (3 2 1) (4 3 2 1) (5 4 3 2 1))
@end example
@end defun

@defun stream-zip stream @dots{}
[R7RS stream]
@c MOD util.stream
@c EN
Returns a new stream whose elements are lists of corresponding
elements from input @var{stream}s.  The output stream ends
when one of input streams is exhausted.
@c JP
入力ストリームの対応する要素のリストを要素とするストリームを作って返します。
入力ストリームのいずれかが終端に達した時に出力ストリームも終わります。
@c COMMON

@example
(stream->list
 (stream-zip (stream 1 2 3) (stream 'a 'b 'c 'd)))
 @result{} ((1 a) (2 b) (3 c))
@end example

@end defun

@defun stream-filter pred stream
[R7RS stream]
@c MOD util.stream
@c EN
Returns a new stream including only elements passing @var{pred}.
@c JP
@var{pred}をパスする要素のみからなる新しいストリームを返します。
@c COMMON
@end defun

@defun stream-remove pred stream
@c MOD util.stream
@c EN
Returns a new stream including only elements that doesn't satisfy @var{pred}.
@c JP
述語@var{pred}を満たさない要素のみからなる新しいストリームを返します。
@c COMMON
@end defun

@defun stream-partition pred stream
@c MOD util.stream
@c EN
Returns two streams, one consists of the elements in @var{stream}
that satisfy @var{pred}, the other consists of the ones that doesn't
satisfy @var{pred}.
@c JP
二つのストリームを返します。最初のストリームは@var{stream}の要素のうち
述語@var{pred}を満たすもの、次のストリームは@var{pred}を満たさないもので構成されます。
@c COMMON
@end defun

@defun stream->list stream
@defunx stream->list n stream
[R7RS stream]
@c MOD util.stream
@c EN
Converts a stream to a list.  In the first form, all elements from
@var{stream} are taken (thus it never returns if @var{stream} is infinite).
In the second form, at most @var{n} elements are taken, where
@var{n} must be a nonnegative exact integer.

Note: In usual Scheme conventions, the optional @var{n} comes after
the main argument (@var{stream}).
@c JP
ストリームをリストに変換します。最初の形式では、@var{stream}の全ての要素が
取り出されます (従って@var{stream}が無限ストリームであればこの関数は永遠に戻りません)。
二番めの形式では最大で@var{n}要素までがストリームから取り出されそのリストが返されます。
@var{n}は非負の正確な整数でなければなりません。

註:通常のSchemeの慣例では、省略可能な@var{n}は@var{stream}の後に来ますが、
この関数はそうでないことに注意。
@c COMMON
@end defun

@defun stream->string stream
@c MOD util.stream
@c EN
Converts a stream to a string.
All elements of @var{stream} must be characters, or an error is signaled.
@c JP
ストリームを文字列に変換します。
@var{stream}の全ての要素は文字でなければなりません。
そうでない場合はエラーが投げられます。
@c COMMON
@end defun


@defun stream-lines stream
@c MOD util.stream
@c EN
Splits @var{stream} where its element equals to @code{#\n}, and
returns a stream of splitted streams.  The character @code{#\n} won't
be included in the results.
@c JP
@var{stream}を、文字@code{#\n}が要素である箇所で分割し、
分割されたストリームのストリームを返します。@code{#\n}自体は結果に含まれません。
@c COMMON

@example
(stream->list
 (stream-map stream->string
             (stream-lines (string->stream "abc\ndef\nghi"))))
 @result{} ("abc" "def" "ghi")
@end example
@end defun

@defun stream= elt= stream @dots{}
@c MOD util.stream
@c EN
Returns true iff each corresponding element of @var{stream} @dots{}
are the same in terms of @var{elt=}, which takes two arguments.
This procedure won't terminate
if all of @var{stream}s is infinite.
@c JP
引数のストリームの全ての対応する要素がそれぞれ、2引数を取る@var{elt=}で比較して等しい場合に
@code{#t}を、そうでなければ@code{#f}を返します。
全ての@var{stream}が無限である場合、この手続きは終了しません。
@c COMMON
@end defun

@defun stream-prefix= stream prefix :optional elt=
@c MOD util.stream
@c EN
Compares initial elements of @var{stream} against
a list @var{prefix} by @var{elt=}.  Returns true iff they match.
Only as many elements of @var{stream}
as @var{prefix} has are checked.
@c JP
@var{stream}の最初の方の要素をリスト@var{prefix}と比較します。各要素は
@var{elt=}で比較されます。@var{prefix}と全てマッチしたら@code{#t}を、
そうでなければ@code{#f}を返します。最大でも@var{prefix}の要素分だけ@var{stream}から
要素が取り出されます。
@c COMMON
@end defun

@defun stream-caar s
@defunx stream-cadr s
@findex stream-cdar
@findex stream-cddr
@findex stream-caaar
@findex stream-caadr
@findex stream-cadar
@findex stream-caddr
@findex stream-cdaar
@findex stream-cdadr
@findex stream-cddar
@findex stream-cdddr
@findex stream-caaaar
@findex stream-caaadr
@findex stream-caadar
@findex stream-caaddr
@findex stream-cadaar
@findex stream-cadadr
@findex stream-caddar
@findex stream-cadddr
@findex stream-cdaaar
@findex stream-cdaadr
@findex stream-cdadar
@findex stream-cdaddr
@findex stream-cddaar
@findex stream-cddadr
@dots{}
@end defun
@defun stream-cdddar s
@defunx stream-cddddr s
@c MOD util.stream
@code{(stream-caar s)} = @code{(stream-car (stream-car s))} etc.
@end defun

@defun stream-ref stream pos
[R7RS stream]
@c MOD util.stream
@c EN
Returns the @var{pos}-th element in the stream.  @var{Pos}
must be a nonnegative exact integer.
@c JP
ストリームの@var{pos}番目の要素を返します。@var{pos}は非負の正確な整数でなければなりません。
@c COMMON
@end defun

@defun stream-first s
@defunx stream-second s
@defunx stream-third s
@defunx stream-fourth s
@defunx stream-fifth s
@defunx stream-sixth s
@defunx stream-seventh s
@defunx stream-eighth s
@defunx stream-ninth s
@defunx stream-tenth s
@c MOD util.stream
@code{(stream-first s)} = @code{(stream-ref s 0)} etc.
@end defun

@defun stream-take stream count
@defunx stream-take-safe stream count
@c MOD util.stream
Returns a new stream that consists of the first @var{count} elements
of the given stream.   If the given stream has less than
@var{count} elements, the stream returned by @code{stream-take}
would raise an error when the elements beyond the original stream
is accessed.  On the other hand, the stream returned by
@code{stream-take-safe} will return a shortened stream when
the given stream has less than @var{count} elements.

@example
(stream->list (stream-take (stream-iota -1) 10))
 @result{} (0 1 2 3 4 5 6 7 8 9)

(stream-take (stream 1 2) 5)
 @result{} @r{stream}

(stream->list (stream-take (stream 1 2) 5))
 @result{} @r{error}

(stream->list (stream-take-safe (stream 1 2) 5))
 @result{} (1 2)
@end example

Note: srfi-41 (@code{scheme.stream}) also defines @code{stream-take}, but
the argument order is reversed, and also it allows @var{stream} to have
less than @code{count} elements.
@end defun

@defun stream-drop stream count
@defunx stream-drop-safe stream count
@c MOD util.stream
Returns a new stream that consists of the elements in the given
stream except the first @var{count} elements.
If the given stream has less than @var{count} elements,
@code{stream-drop} returns a stream that raises an error
if its element is accessed, and @code{stream-drop-safe}
returns an empty stream.

Note: srfi-41 (@code{scheme.stream}) also defines @code{stream-drop}, but
the argument order is reversed, and also it allows @var{stream} to have
less than @code{count} elements.
@end defun

@defun stream-intersperse stream element
@c MOD util.stream
Returns a new stream in which @var{element} is
inserted between elements of @var{stream}.
@end defun

@defun stream-split stream pred
@c MOD util.stream
Split @var{stream} on elements that satisfy @var{pred},
and returns a stream of splitted streams.  The delimiting element
won't be included in the result.
@end defun

@defun stream-last stream
@c MOD util.stream
Returns the last element of @var{stream}.  If @var{stream} is infinite,
this procedure won't return.
@end defun

@defun stream-last-n stream count
@c MOD util.stream
Returns a stream that contains the last @var{count} elements
in @var{stream}.  The @var{count} argument must be a nonnegative exact
integer.  If the length of @var{stream} is smaller than @var{count},
the resulting stream is the same as @var{stream}.
If @var{stream} is infinite,
this procedure won't return.
@end defun

@defun stream-butlast stream
@c MOD util.stream
Returns a stream which is the same as @var{stream} but without the
last element.  If @var{stream} is empty, an empty stream is returned.
@end defun

@defun stream-butlast-n stream count
@c MOD util.stream
Returns a stream which is the same as @var{stream} but without the
last @var{count} elements.  The @var{count} argument must be a nonnegative exact
integer.  If @var{stream} is shorter than @var{count}, a null stream
is returned.
@end defun

@defun stream-length stream
[R7RS stream]
@c MOD util.stream
Returns the number of elements in @var{stream}.  It diverges if @var{stream}
is infinite.
@end defun

@defun stream-length>= stream n
@defunx stream-length= stream n
@c MOD util.stream
Returns true iff the length of @var{stream} is greater than or equal to,
and exactly equal to, @var{n}, respectively.
These procedures only realizes @var{stream} up to @var{n} elements.
@end defun

@defun stream-reverse stream :optional tail-stream
[R7RS stream]
@c MOD util.stream
@c EN
Returns a stream that returns the elements of @var{stream} in reverse order.
If @var{tail-stream} is given, it is added after the reversed stream.

The optional argument is Gauche's extension.  The description of @code{reverse}
(@pxref{Other list procedures}) for more details.
@c JP
@var{stream}の要素を逆順にしたストリームを返します。@var{tail-stream}が与えられた
場合、逆順にしたストリームの後にそれ付け加えられます。

省略可能な@var{tail-stream}はGaucheの拡張です。詳しくは
@code{reverse}の説明を参照してください (@ref{Other list procedures})。
@c COMMON
@end defun

@defun stream-count pred stream @dots{}
@c MOD util.stream
@end defun

@defun stream-find pred stream
@c MOD util.stream
@end defun

@defun stream-find-tail pred stream
@c MOD util.stream
@end defun

@defun stream-take-while pred stream
[R7RS stream]
@c MOD util.stream
@end defun

@defun stream-drop-while pred stream
[R7RS stream]
@c MOD util.stream
@end defun

@defun stream-span pred stream
@c MOD util.stream
@end defun

@defun stream-break pred stream
@c MOD util.stream
@end defun

@defun stream-any pred stream @dots{}
@c MOD util.stream
@end defun

@defun stream-every pred stream @dots{}
@c MOD util.stream
@end defun

@defun stream-index pred stream @dots{}
@c MOD util.stream
@end defun

@defun stream-member obj stream :optional elt=
@defunx stream-memq obj stream
@defunx stream-memv obj stream
@c MOD util.stream
@end defun

@defun stream-delete obj stream :optional elt=
@c MOD util.stream
@end defun

@defun stream-delete-duplicates stream :optional elt=
@c MOD util.stream
@end defun

@defun stream-grep re stream
@c MOD util.stream
@end defun

@defun write-stream stream :optional oport writer
@c MOD util.stream
@end defun

@c ----------------------------------------------------------------------
@node Topological sort, Unification, Stream library, Library modules - Utilities
@section @code{util.toposort} - Topological sort
@c NODE トポロジカルソート, @code{util.toposort} - トポロジカルソート

@deftp {Module} util.toposort
@mdindex util.toposort
@c EN
Implements topological sort algorithm.
@c JP
トポロジカルソートのアルゴリズムを実装します。
@c COMMON
@end deftp

@defun topological-sort graph :optional eqproc
@c MOD util.toposort
@c EN
@var{Graph} represents a directed acyclic graph (DAG) by a list
of connections, where each connection is the form
@example
(<node> <downstream> <downstream2> ...)
@end example
that means a node @code{<node>} is connected to other nodes
@code{<downstream>} etc.   @code{<node>} can be arbitrary
object, as far as it can be compared by the procedure @var{eqproc},
which is @var{eqv?} by default (@pxref{Equality}).
Returns a list of @code{<node>}s sorted topologically.

If the graph contains circular reference, an error is signaled.
@c JP
@var{Graph}は有向非循環グラフ(DAG)を表現するリストです。
リストの各要素は次の形をしています。
@example
(<node> <downstream> <downstream2> ...)
@end example
これで、ノード@code{<node>}から別のノード@code{<downstream>}等への接続が
あることを表現します。@code{<node>}はどんなオブジェクトであっても構いませんが、
同一性の判定が@var{eqproc}で行えなければなりません。@var{eqproc}の既定値は
@code{eqv?}です (@ref{Equality}参照)。
トポロジカルにソートされたノードのリストを返します。

グラフに循環が検出された場合はエラーとなります。
@c COMMON
@end defun

@c ----------------------------------------------------------------------
@node Unification, CGI utility, Topological sort, Library modules - Utilities
@section @code{util.unification} - Unification
@c NODE ユニフィケーション, @code{util.unification} - ユニフィケーション

@deftp {Module} util.unification
@mdindex util.unification
@c EN
Implements unification algorithm.
@c JP
ユニフィケーションのアルゴリズムを実装します。
@c COMMON

@c EN
The base API operates on abstract trees, while it is
agnostic to the actual representation of the tree.
The caller passes comparators and operators along the trees
to unify.
@c JP
基本APIは、抽象的な木に対して動作しますが、木が実際にどう実装されているかは
関知しません。
呼び出し側は、ユニファイする木といっしょに、比較器や操作手続きを渡します。
@c COMMON

@c EN
We assume the abstract tree has the following structure:
@c JP
抽象的な木は、次の構造を持っていると考えます。
@c COMMON

@example
Tree : Variable | Value | Tuple
Tuple : @{ Tree ... @}
@end example

@c EN
Here, @code{@{...@}} just represents a sequence of trees.
@c JP
ここで、@code{@{...@}}は単に木の並びを表します。
@c COMMON

@c EN
A variable can be bound to a tree.  A value can only match itself.
@c JP
変数(Variable)は木に束縛されます。値(Value)はそれ自身とのみマッチします。
@c COMMON

@c EN
To operate on this tree, we need the following comparators and procedures,
which the API takes as arguments:
@c JP
この木を扱うために、APIは以下の比較器と手続きを引数として取ります。
@c COMMON

@table @asis
@item Variable comparator: @code{var-cmpr}
@c EN
A comparator to see if an item is a variable, and also
check equality of two variables.  It must be hashable.
@xref{Basic comparators}, for the details of comparators.
@c JP
要素が変数であるかどうかを調べ、また二つの変数が同じかどうかを判定
するための比較器です。ハッシュ可能でなければなりません。
比較器については@ref{Basic comparators}を参照してください。
@c COMMON
@item Value comparator: @code{val-cmpr}
@c EN
A comparator to see if an item is a value, and also
check equality of two values.
Note that if a tree satisfies neither @var{var-cmpr} nor @var{val-compr},
it is regarded as a tuple.
@c JP
要素が値であるかどうかを調べ、また二つの値が等しいかどうかを
判定するための比較器です。@var{var-cmpr}も@var{val-cmpr}も
満たさない要素はタプルであるとみなされます。
@c COMMON
@item Tuple folder: @code{tuple-fold}
@c EN
A procedure @code{(tuple-folde proc seed tuple1 [tuple2])}. 
This procedure should work like @code{fold} (@pxref{Walking over lists})
over the elements in the tuple(s).  It is only called with
either one or two tuples.
@c JP
@code{(tuple-folde proc seed tuple1 [tuple2])}の形で呼び出される手続きです。
この手続きは、タプル中の要素について@code{fold}のように動作します
(@ref{Walking over lists}参照)。常にひとつかふたつのタプルを引数とします。
@c COMMON
@item Tuple constructor: @code{make-tuple}
@c EN
A procedure @code{(make-tuple proto elements)}, where
@var{proto} is a tuple and @var{elements} are a list of trees.  
It must return a new tuple with the given elements,
while all other properties are the same as @var{proto}.
This procedure isn't needed by @code{unify}.
@c JP
@code{(make-tuple proto elements)}の形式で呼び出される手続きです。
@var{proto}はタプルで、@var{elements}は木のリストです。
@var{proto}と同じ型のタプルで、要素だけを@var{elements}と置き換えた
新たなタプルを作成して返します。
@code{unify}はこの手続きを必要としません。
@c COMMON
@end table
@end deftp

@defun unify a b var-cmpr val-cmpr tuple-fold
@c MOD util.unification
@c EN
Unify two trees @var{a} and @var{b} and returns a substitution
dictionary, which is a dictionary that maps variables
to its bounded trees.
@c JP
二つの木、@var{a}と@var{b}を単一化し、置換辞書を返します。
置換辞書は、変数をその値にマップするものです。
@c COMMON

@c EN
See the entry of @code{util.unification} above for the description
of @var{var-cmpr}, @var{val-cmpr} and @var{tuple-fold}.
@c JP
引数@var{var-cmpr}、@var{val-cmpr}、@var{tuple-fold}に関しては
上の@code{util.unification}の説明を参照してください。
@c COMMON

@example
(dict->alist (unify '(a 3 (c b)) '(c b (2 e))
                    symbol-comparator
                    number-comparator
                    fold))
 @result{} ((e . 3) (a . c) (b . 3) (c . 2))
@end example

@c EN
As you can see in the example above, 
a variable may be mapped to another variable, or even to 
a tree that contains variables.  If you apply the substitution
to the original tree, you must do it recursively until all the
variables in the dictionary is eliminated.
@c JP
この例にも見られるように、一つの変数の値が別の変数であったり、
別の変数を含む木であったりする場合があります。
元の木に置換を適用する場合は、辞書にある変数がすべて消去されるまで
再帰的に置換を行う必要があります。
@c COMMON

@c EN
If two trees cannot be unified, @code{#f} is returned.
@c JP
二つの木が単一化できない場合は@code{#f}が返されます。
@c COMMON

@example
(unify '(a (a)) '(x x) symbol-comparator number-comparator fold)
 @result{} #f
@end example

@end defun

@defun unify-merge a b var-cmpr val-cmpr tuple-fold make-tuple
@c MOD util.unification
@c EN
Unify two trees @var{a} and @var{b}, and apply the result substitutions
to create a new tree eliminating variables.
@c JP
二つの木、@var{a}と@var{b}を単一化し、結果の置換を適用して変数を消去した
新たな木を返します。
@c COMMON

@c EN
See the entry of @code{util.unification} above for the description
of @var{var-cmpr}, @var{val-cmpr}, @var{tuple-fold} and
@var{make-tuple}.
@c JP
引数@var{var-cmpr}、@var{val-cmpr}、@var{tuple-fold}、@var{make-tuple}に関しては
上の@code{util.unification}の説明を参照してください。
@c COMMON

@example
(unify-merge '(a 3 (c b)) '(c b (2 e))
             symbol-comparator
             number-comparator
             fold
             (^[_ elts] elts))
 @result{} (2 3 (2 3))
@end example

@c EN
If two trees can't be unified, @code{#f} is returned.
@c JP
二つの木が単一化できなければ、@code{#f}が返されます。
@c COMMON
@end defun


@c ----------------------------------------------------------------------
@node CGI utility, CGI testing, Unification, Library modules - Utilities
@section @code{www.cgi} - CGI utility
@c NODE CGIユーティリティ, @code{www.cgi} - CGIユーティリティ

@deftp {Module} www.cgi
@mdindex www.cgi
@c EN
Provides a few basic functions useful to write a CGI script.

In order to write CGI script easily, you may want to use
other modules, such as @code{rfc.uri} (@pxref{URI parsing and construction}),
@code{text.html-lite} (@pxref{Simple HTML document construction}) and
@code{text.tree} (@pxref{Lazy text construction}).

Note: it seems that there is no active formal specification for CGI.
See @uref{http://w3c.org/CGI/} for more information.
@c JP
CGIスクリプトを書くのに便利ないくつかの基本的な手続きを提供します。

CGIスクリプトを手軽に書くにはこのモジュールの他に、
@code{rfc.uri} (@ref{URI parsing and construction})、
@code{text.html-lite} (@ref{Simple HTML document construction})、
@code{text.tree} (@ref{Lazy text construction}) 等のモジュールを併せて
使うとよいでしょう。

注：現在有効な、CGIに関する「正式な」仕様というのはどうも無いようです。
@uref{http://w3c.org/CGI/}あたりを参照して下さい。
@c COMMON
@end deftp

@c EN
@subheading Metavariables
@c JP
@subheading メタ変数
@c COMMON

@deffn {Parameter} cgi-metavariables :optional metavariables
@c MOD www.cgi
@c EN
Normally, httpd passes a cgi program various information
via environment variables.
Most procedures in @code{www.cgi} refer to them (meta-variables).
However, it is sometimes inconvenient to require environment variable access
while you're developing cgi-related programs.
With this parameter, you can overrides the information of meta-variables.

@var{Metavariables} should be a list of two-element lists.
Car of each inner list names the variable, and its cadr gives the
value of the variable by string.

For example, the following code overrides @code{REQUEST_METHOD}
and @code{QUERY_STRING} meta-variables during execution of
@code{my-cgi-procedure}.  (@xref{Parameters},
for the details of @code{parameterize}).
@c JP
通常、httpdはcgiプログラムに様々な情報を環境変数経由で渡します。
@code{www.cgi}中の多くの手続きはその情報(メタ変数)を参照します。
しかし、cgiに関連するプログラムを開発中に環境変数にアクセスするのは
不便な場合もあります。
このパラメータを使うと、メタ変数をオーバライドすることができます。

@var{Metavariables}は2要素のリストのリストです。
内側のリストは、最初の要素が変数名を、2つめの要素がその値を、それぞれ
文字列で与えます。

例えば次のコードは@code{REQUEST_METHOD}と
@code{QUERY_STRING}のメタ変数を@code{my-cgi-procedure}の実行期間中に
上書きします。(@code{parameterize}の詳細については
@ref{Parameters}を参照して下さい)。
@c COMMON

@example
(parameterize ((cgi-metavariables '(("REQUEST_METHOD" "GET")
                                    ("QUERY_STRING" "x=foo"))))
  (my-cgi-procedure))
@end example
@end deffn

@defun cgi-get-metavariable name
@c MOD www.cgi
@c EN
Returns a value of cgi metavariable @var{name}.
This function first searches the parameter @code{cgi-metavariables},
and if the named variable is not found, calls @code{sys-getenv}.

CGI scripts may want to use @code{cgi-get-metavariable} instead
of directly calling @code{sys-getenv}; doing so makes reuse of
the script easier.
@c JP
@var{name}で指定されるCGIメタ変数の値を返します。
この関数はまずパラメータ@code{cgi-metavariables}を探し、
指定されたメタ変数が見つからなければ@code{sys-getenv}を呼びます。

CGIスクリプトは、なるべく@code{sys-getenv}を直接呼ぶのではなく
@code{cgi-get-metavariable}を使うのが良いでしょう。
スクリプトの再利用もしやすくなります。
@c COMMON
@end defun

@c EN
@subheading Parameter extraction
@c JP
@subheading パラメータの取得
@c COMMON

@defun cgi-parse-parameters :key :query-string :merge-cookies :part-handlers
@c MOD www.cgi
@c EN
Parses query string and returns associative list of parameters.
When a keyword argument @var{query-string} is given, it is used
as a source query string.  Otherwise, the function checks the
metavariable @code{REQUEST_METHOD} and obtain the query string
depending on the value (either from stdin or from the
metavariable @code{QUERY_STRING}).
If such a metavariable is not defined and
the current input port is a terminal, the function prompts the user
to type parameters; it is useful for interactive debugging.
@c JP
CGIプログラムに渡されたquery stringをパーズして、パラメータの連想リストにして
返します。文字列がキーワード引数@var{query-string}に与えられればそれがパーズすべき
query stringとなります。その引数が渡されなければこの手続きは
メタ変数@code{REQUEST_METHOD}を参照し、その値によって標準入力もしくは
メタ変数@code{QUERY_STRING}からquery stringが取られます。
そのようなメタ変数が定義されておらず、かつ現在の入力ポートが端末である場合、
インタラクティブにデバッグをしているものと考えて、
この手続きはプロンプトを出してユーザにパラメータの入力を促します。
@c COMMON

@c EN
If @code{REQUEST_METHOD} is @code{POST}, this procedure can handle
both @code{application/x-www-form-urlencoded} and
@code{multipart/form-data} as the enctype.  The latter is usually
used if the form has file-uploading capability.

When the post data is sent by @code{multipart/form-data},
each content of the part is treated as a value of the parameter.
That is, the content of uploaded file will be seen as one big
chunk of a string.  The other information, such as the original file
name, is discarded.   If it is not desirable to read entire file
into a string, you can customize the behavior by the @var{part-handler}
argument.  The details are explained in the "Handling file uploads"
section below.
@c JP
@code{REQUEST_METHOD}が@code{POST}の場合、この手続きはenctypeとして
@code{application/x-www-form-urlencoded}と@code{multipart/form-data}の
両方を処理できます。後者は通常、ファイルアップロード機能を持つフォームに使われます。

POSTデータが@code{multipart/form-data}で送られて来た場合、
各パートの内容がパラメータの値となります。すなわち、アップロードされた
ファイルはその内容がひとつの文字列として得られることになります。
元のファイル名のようなその他の情報は捨てられます。これが望ましい動作で
ない場合は、@var{part-handlers}引数によって動作をカスタマイズすることができます。
詳しくは下の「ファイルアップロードの処理」で説明します。
@c COMMON

@c EN
When a true value is given to @var{merge-cookies}, the cookie
values obtained from the metavariable @code{HTTP_COOKIE}
are appended to the result.
@c JP
キーワード引数@var{merge-cookies}に真の値が与えられた場合は、
メタ変数@code{HTTP_COOKIE}からクッキーの値が読まれ、解析されて
結果に追加されます。
@c COMMON

@c EN
Note that the query parameter may have multiple values,
so @code{cdr} of each element in the result is a list, not an atom.
If no value is given to the parameter, @code{#t} is placed as its value.
See the following example:
@c JP
パラメータは複数の値を取り得るため、結果のパラメータに対応する値は常にリストになります。
パラメータに値が与えられていなければ、結果のパラメータに対する値には@code{#t}が置かれます。
次の例を参照して下さい。
@c COMMON
@example
(cgi-parse-parameters
  :query-string "foo=123&bar=%22%3f%3f%22&bar=zz&buzz")
 @result{} (("foo" "123") ("bar "\"??\"" "zz") ("buzz" #t))
@end example
@end defun


@defun cgi-get-parameter name params :key :default :list :convert
@c MOD www.cgi
@c EN
A convenient function to obtain a value of the parameter @var{name} from
parsed query string @var{params}, which is the value
@code{cgi-parse-parameters} returns.  @var{Name} should be a string.
@c JP
@code{cgi-parse-parameters}が返す、パーズされたQuery文字列@var{params}から、
名前@var{name}を持つパラメータの値を簡単に取り出すための手続きです。
@var{name}は文字列です。
@c COMMON

@c EN
Unless true value is given to @var{list}, the returned value is
a scalar value.  If more than one value is associated to @var{name},
only the first value is returned.  If @var{list} is true, the
returned value is always a list, even @var{name} has only one value.
@c JP
キーワード引数@var{list}に真の値が与えられていなければ、
返される値はスカラー値です。パラメータ@var{name}に複数の値が与えられた場合でも、
最初の値のみが返されます。@var{list}に真の値が与えられれば、返されるのは
常に値のリストとなります。
@c COMMON

@c EN
After the value is retrieved, you can apply a procedure to
convert the string value to the appropriate type by giving
a procedure to the @var{convert} argument.  The procedure must
take one string argument.  If @var{list} is true, the convert
procedure is applied to each values.
@c JP
キーワード引数@var{convert}に手続きを与えると、対応する値が取り出された後でその
手続きが値を引数として呼ばれます。これによって値を文字列から必要な型へと変換することが
できます。@var{list}に真の値が与えられている場合、変換手続きは各値に対して呼ばれ、
その結果のリストが@var{cgi-get-parameter}から返されます。
@c COMMON

@c EN
If the parameter @var{name} doesn't appear in the query,
a value given to the keyword argument @var{default} is returned;
the default value of @var{default}
is @code{#f} if @var{list} is false, or @code{()} otherwise.
@c JP
パラメータ@var{name}がQuery中に現れなかった場合は、
@var{default}に与えられた値がそのまま
返されます。@var{default}が省略された場合、@var{list}が偽であれば@code{#f}が、
真であれば@code{()}が返されます。
@c COMMON
@end defun

@c EN
@subheading Output generation
@c JP
@subheading 出力の生成
@c COMMON


@defun cgi-header :key status content-type location cookies
@c MOD www.cgi
@c EN
Creates a text tree (@pxref{Lazy text construction}) for the
HTTP header of the reply message.  The most simple form is
like this:
@c JP
HTTPリプライメッセージのヘッダを、テキストツリー形式(@ref{Lazy text construction}参照)
で作成して返します。最も簡単な呼び出しでは次のようになります。
@c COMMON
@example
(tree->string (cgi-header))
  @result{} "Content-type: text/html\r\n\r\n"
@end example

@c EN
You can specify alternative content-type by the keyword argument
@var{content-type}.   If you want to set cookies to the client,
specify a list of cookie strings to the keyword argument @var{cookies}.
You can use @code{construct-cookie-string} (@pxref{HTTP cookie handling})
to build such a list of cookie strings.
@c JP
キーワード引数@var{content-type}によってContent typeを指定できます。
また、@var{cookies}にクッキー文字列のリストを渡すことにより、
クライアントにクッキーを設定できます。クッキー文字列を構築するには手続き
@code{construct-cookie-string} (@ref{HTTP cookie handling}参照)
が使えます。
@c COMMON

@c EN
The keyword argument @var{location} may be used to generate
a @code{Location:} header to redirect the client to the specified URI.
You can also specify the @code{Status:} header by the keyword argument
@var{status}.   A typical way to redirect the client is as follows:
@c JP
キーワード引数@var{location}は、@code{Location}ヘッダを作成して
クライアントを別のURIに誘導するのに使えます。また、@code{Status}ヘッダを
指定するために@var{status}キーワード引数が使えます。クライアントを
別URIに転送するよくある方法は次のようなものです。
@c COMMON

@example
(cgi-header :status "302 Moved Temporarily"
            :location target-uri)
@end example

@end defun

@deffn {Parameter} cgi-output-character-encoding :optional encoding
@c MOD www.cgi
@c EN
The value of this parameter specifies the character encoding scheme (CES)
used for CGI output by @code{cgi-main} defined below.
The default value is Gauche's native encoding.
If the parameter is set other than the native encoding, @code{cgi-main}
converts the output
encoding by @code{gauche.charconv} module
(@pxref{Character code conversion}).
@c JP
このパラメータの値は次に説明する@code{cgi-main}が出力するデータの
文字符合化法(CES)を指定します。デフォルトの値はGaucheのネイティブエンコーディング
です。それ以外の値がセットされている場合、@code{cgi-main}は
@code{gauche.charconv}モジュールを用いて出力のエンコーディングの変換を
行います。
(@ref{Character code conversion}参照)。
@c COMMON
@end deffn


@c EN
@subheading Convenience procedures
@c JP
@subheading 便利な手続き
@c COMMON

@defun cgi-main proc :key on-error merge-cookies output-proc part-handlers
@c MOD www.cgi
@c EN
A convenient wrapper function for CGI script.
This function calls @code{cgi-parse-parameters}, then calls
@var{proc} with the result of @code{cgi-parse-parameters}.
The keyword argument @var{merge-cookies} is passed to
@code{cgi-parse-parameters}.
@c JP
CGIスクリプトのための便利なラッパー手続きです。
この手続きは、まず@code{cgi-parse-parameters}を呼び出してCGIスクリプトに
渡されたパラメータを解析し、続いてその結果を引数として@var{proc}を呼び出します。
キーワード引数@var{merge-cookies}は、与えられればそのまま
@code{cgi-parse-parameters}に渡されます。
@c COMMON

@c EN
@var{proc} has to return a tree of strings
(@pxref{Lazy text construction}), including the HTTP header.
@code{cgi-main} outputs the returned tree to the current output port
by @code{write-tree}, then returns zero.
@c JP
手続き@var{proc}はHTTPヘッダを含むドキュメントを
テキストツリー構造(@ref{Lazy text construction}参照)で
返さなければなりません。@code{cgi-main}はそれを@code{write-tree}を使って
現在の出力ポートに書き出し、0を返します。
@c COMMON

@c EN
If an error is signaled in @var{proc}, it is caught and an HTML
page reporting the error is generated.  You can customize the
error page by providing a procedure to the @var{on-error} keyword argument.
The procedure takes an @code{<condition>} object (@pxref{Conditions}),
and has to return a tree of string for the error reporting HTML
page, including an HTTP header.
@c JP
もし@var{proc}内でエラーが起こった場合、そのエラーは捕捉されて、エラーを報告する
HTMLページが作成されて出力されます。このエラーページは、@var{on-error}キーワード引数に
手続きを渡すことでカスタマイズできます。@var{on-error}に渡された手続きは
エラー発生時に@code{<condition>}オブジェクト(@ref{Conditions}参照)
を引数として呼ばれ、HTTPヘッダを含むドキュメントをテキストツリー構造で返さねばなりません。
@c COMMON

@c EN
When output the result, @code{cgi-main} refers to
the value of the parameter @code{cgi-output-character-encoding},
and converts the character encoding if necessary.
@c JP
@code{cgi-main}は最終的な結果を出力を書き出す時に
パラメータ@code{cgi-output-character-encoding}を参照し、
必要ならば出力の文字エンコーディングを変換します。
@c COMMON

@c EN
The output behavior of @code{cgi-main} can be customized
by a keyword argument @var{output-proc}; if it is given,
the text tree (either the normal return value of @var{proc},
or an error page constructed by the error handler) is passed
to the procedure given to @var{output-proc}.  The procedure
is responsible to format and output a text to the current
output port, including character conversions, if necessary.
@c JP
@code{cgi-main}の出力のふるまいはキーワード引数@var{output-proc}で
カスタマイズできます。@var{output-proc}が渡された場合、それは
@var{proc}の戻り値、あるいはエラーハンドラが作成したテキストツリー構造を
受け取る手続きでなければなりません。その手続きはテキストツリーを
フォーマットして現在の出力ポートに出力しなければなりません。
必要ならば文字エンコーディングの変換もその手続き内で行います。
@c COMMON

@c EN
The keyword argument @var{part-handlers} are simply passed to
@code{cgi-parse-parameters}, by which you can customize
how the file uploads should be handled.  See the "Handling file
uploads" section below for the details.

If you specify to use temporary file(s) by it, @code{cgi-main}
makes sure to clean up them whenever @var{proc} exits,
even by error.   See @code{cgi-add-temporary-file} below
to utilize this feature for other purpose.
@c JP
キーワード引数@var{part-handlers}は、そのまま@code{cgi-parse-parameters}
に渡されます。この引数によって、ファイルアップロードの際の動作をカスタマイズ
できます。詳しくは下の「ファイルアップロードの処理」の項を参照して下さい。

この引数で、一時ファイルを使うように指定した場合、@code{cgi-main}は
@var{proc}から抜ける際に(エラーでも正常終了でも)一時ファイルを
消去します。この機能を他でも利用するには@code{cgi-add-temporary-file}の項を
参考にして下さい。
@c COMMON

@c EN
Before calling @var{proc}, @code{cgi-main} changes the buffering mode
of the current error port to @code{:line} (See @code{port-buffering}
in @ref{Common port operations} for the details about the buffering mode).
This makes the error output easier for web servers to capture.
@c JP
@var{proc}を呼ぶ前に、@code{cgi-main}はカレントエラーポートの
バッファリングモードを@code{:line}に変更します。
(バッファリングモードの詳細については@ref{Common port operations}の
@code{port-buffering}の項を参照してください)。
これはwebサーバがcgiスクリプトのエラー出力を捕捉しやすくするためです。
@c COMMON

@c EN
The following example shows the parameters given to the CGI program.
@c JP
以下の例はCGIに渡されたパラメータ全てをテーブルにして表示します。
@c COMMON

@example
#!/usr/local/bin/gosh

(use text.html-lite)
(use www.cgi)

(define (main args)
  (cgi-main
    (lambda (params)
      `(,(cgi-header)
        ,(html-doctype)
        ,(html:html
          (html:head (html:title "Example"))
          (html:body
           (html:table
            :border 1
            (html:tr (html:th "Name") (html:th "Value"))
            (map (lambda (p)
                   (html:tr
                    (html:td (html-escape-string (car p)))
                    (html:td (html-escape-string (x->string (cdr p))))))
                 params))))
       ))))
@end example
@end defun


@defun cgi-add-temporary-file filename
@c MOD www.cgi
@c EN
This is supposed to be called inside @var{proc} of @code{cgi-main}.
It registers @var{filename} as a temporary file, which should be
unlinked when @var{proc} exits.  It is a convenient way to ensure
that your cgi script won't leave garbages even if it throws an error.
It is OK in @var{proc} to unlink or rename @var{filename} after
calling this procedure.
@c JP
この手続きは@code{cgi-main}に渡される@var{proc}中で呼ばれることを
想定しています。
この手続きは、@var{filename}を一時ファイルとして登録し、@var{proc}が
終了する際に消去されるようにします。cgiスクリプトがエラー終了した場合
などでもごみを残さないようにする便利な方法です。
この手続きを呼んだ後で、@var{proc}が@var{filename}を消去したり
名前を変えたりしても構いません。
@c COMMON
@end defun

@deffn {Parameter} cgi-temporary-files
@c MOD www.cgi
@c EN
Keeps a list of filenames registered by @code{cgi-add-temporary-file}.
@c JP
@code{cgi-add-temporary-file}で登録された一時ファイルを保持するパラメータです。
@c COMMON
@end deffn

@c EN
@subheading Handling file uploads
@c JP
@subheading ファイルアップロードの処理
@c COMMON

@c EN
As explained in @code{cgi-parse-parameters} above, file uploads
are handled transparently by default, taking the file content
as the value of the parameter.   Sometimes you might want to change this
behavior, for the file might be quite big and you don't want
to keep around a huge chunk of a string in memory.  It is possible to
customize handling of file uploads of @code{cgi-parse-parameters}
and @code{cgi-main} by @var{part-handlers} argument.
(The argument is only effective for the form data submitted by
@code{multipart/form-data} enctype)
@c JP
@code{cgi-parse-parameters}の項で説明したように、ファイルアップロードは
デフォルトでは透過的に扱われます。すなわち、アップロードされた
ファイルの内容がパラメータの値となります。
これは望みの動作ではないかもしれません。例えばアップロードされるファイルが
巨大であることが予想されるなら、それを全てメモリに読み込んで持ち回りたくは
ないかもしれません。@code{cgi-parse-parameters}や@code{cgi-main}の
@var{part-handlers}引数によって、ファイルアップロードの
処理をカスタマイズすることが可能です。
(この引数は、フォームデータが@code{multipart/form-data} enctypeで
送られた場合にのみ意味を持ちます)。
@c COMMON

@c EN
The @var{part-handlers} argument is, if given, a list of lists;
each inner list is a form of
@code{(@var{name-pattern} @var{action} @var{kv-list} @dots{})}.
Each uploaded file with a matching parameter name with @var{name-pattern} is
handled according to @var{action}.  (Here, a parameter name
is the 'name' attribute given to the @code{input} element in the
submitted form, not the name of the uploaded file).
@c JP
@var{part-handlers}引数が与えられている場合、それはリストのリストで、
内部のリストは@code{(@var{name-pattern} @var{action} @var{kv-list} @dots{})} の形式で
なければなりません。
アップロードされたファイルは、そのパラメータ名が@var{name-pattern}に
マッチした場合に@var{action}で指示されるように処理されます。
(ここで、パラメータ名とはsubmitされたフォームの@code{input}要素に与えられた
'name'属性のことです。アップロードされたファイルの名前ではありません)。
@c COMMON

@c EN
@var{Name-pattern} must be either a list of string (matches one of them),
a regexp, or @code{#t} (matches anything).
@c JP
@var{name-pattern}は文字列のリストか、正規表現か、@code{#t}です。
文字列のリストの場合はそれのいずれかとパラメータ名が等しければマッチと
みなされます。@code{#t}は全てのものにマッチします。
@c COMMON

@c EN
@var{Action} must be either one of the followings:
@table @code
@item #f
Default action, i.e. the content of the uploaded file is turned into
a string and becomes the value of the parameter.
@item ignore
The uploaded content is discarded.
@item file
The uploaded content is saved in a temporary file.  The value of
the parameter is the pathname of the temporary file.

For this action, you can write an entry like
@code{(@var{name-pattern} file @var{prefix})}, to specify the
prefix of the pathname of the temporary file.  For example, if you
specify @code{("image" file "/var/mycgi/incoming/img")},
the file uploaded as @code{"image"} parameter will be stored as
something like @file{/var/mycgi/incoming/img49g2Ua}.

The application should move the temporary file to appropriate
location; if you're using @code{cgi-main}, the temporary files
created by this action will be unlinked when @code{cgi-main} exits.

@item file+name
Like @code{file}, but the value of the parameter is a list of
temporary filename and the filename passed by the client.
It is useful if you want to use client's filename (but do not
blindly assume the client sends a valid pathname; for example,
you shouldn't use it to rename the uploaded file without
validating it).

@item @var{procedure}
In this case, @var{procedure} is called to handle the uploaded
contents.  It is called with four arguments:
@code{(procedure @var{name} @var{filename} @var{part-info} @var{iport})}.

@var{Name} is the name of the parameter.  @var{Filename} is
the name of the original file (pathname in the client).
@var{Part-info} is a @code{<mime-part>} object that keeps information
about this mime part,  and @var{iport} is where the body can be
read from.
For the details about these arguments,
see @ref{MIME message handling}; you might be able to
use procedures provided by @code{rfc.mime}, such as @code{mime-retrieve-body},
to construct your own procedure.

If you create a temporary file in @var{procedure}, you can call
@code{cgi-add-temporary-file} to make sure it is removed even if
an error occurs during cgi processing.
@end table
@c JP
@code{action}は次のいずれかの値でなければなりません。
@table @code
@item #f
デフォルトのアクションです。すなわち、アップロードされたファイルの内容が
文字列として読み込まれ、パラメータの値となります。
@item ignore
アップロードされたファイルの内容を無視します。
@item file
アップロードされたファイルの内容は一時ファイルへと格納されます。
パラメータの値は、一時ファイルの名前となります。

このアクションを使う場合は、エントリを
@code{(@var{name-pattern} file @var{prefix})} のように書くことも
でき、その場合は@var{prefix}が一時ファイルのパス名のプリフィクスとして
使われます。例えば@code{("image" file "/var/mycgi/incoming/img")}
のようにしておくと、@code{"image"}パラメータとしてアップロードされた
ファイルが@file{/var/mycgi/incoming/img49g2Ua}のような一時ファイルに
格納されることになります。

アプリケーションは、この一時ファイルを(必要ならば)適切な場所に
移動しなければなりません。@code{cgi-main}を用いている場合は、
一時ファイルは@code{cgi-main}を抜ける際に(まだあれば)unlinkされます。

@item file+name
@code{file}と同様ですが、パラメータの値が一時ファイル名と
クライアントが送ってきたファイル名からなるリストになります。
クライアントが送信したファイル名を利用したい場合に便利です
(ただ、クライアントが常に正しいファイル名を送って来ると仮定しては
いけません。例えば、アップロードされたファイルを
チェック無しにクライアントが送ってきた名前にrenameするというような
ことは避けてください)。


@item @var{procedure}
この場合、アップロードされた内容を処理するために、手続き@var{procedure}が
呼ばれます。手続きは4つの引数を伴って呼ばれます：
@code{(procedure @var{name} @var{filename} @var{part-info} @var{iport})}.

@var{name}はパラメータの名前、@var{filename}はオリジナルファイルの名前
(クライアント側でのパス名)です。@var{part-info}は@code{<mime-part>}オブジェクトで、
このMIMEパートの情報を保持しており、そして@var{iport}は内容を読むための入力ポートです。
これらの引数の詳しい意味については@ref{MIME message handling}を
参照して下さい。独自の@var{procedure}を書く際に、@code{rfc.mime}の
@code{mime-retrieve-body}のような手続きが使えるかもしれません。

@var{procedure}内で一時ファイルを作る場合は、それを
@code{cgi-add-temporary-file}で登録しておけば、cgi処理中に
エラーが起きた場合でも一時ファイルが消去されるようにすることができます。
@end table
@c COMMON

@c EN
If @var{kv-list} is given after @var{action}, it must be a
keyword-value list and further modifies action.  The following
keywords are supported.
@c JP
@var{action}の後ろに@var{kv-list}が与えられた場合、それは
キーワード-値リストでなければなりません。次のキーワードがサポートされています。
@c COMMON

@table @code
@item :prefix
@c EN
Valid only if @var{action} is either @code{file} or @code{file+name}.
Specifies the prefix of the temporary file.  If you give
@code{:prefix "/tmp/foo"}, for example, the file is saved
as something like @file{/tmp/fooxAgjeQ}.
@c JP
@var{action}が@code{file}か@code{file+name}の時のみ有効です。
一時ファイルのプリフィクスを指定します。例えば@code{:prefix "/tmp/foo"}を
与えると、ファイルは@file{/tmp/fooxAgjeQ}のような名前でセーブされます。
@c COMMON
@item :mode
@c EN
Valid only if @var{action} is either @code{file} or @code{file+name}.
Specifies the mode of the temporary file in unix-style integer.  By default
it is @code{#o600}.
@c JP
@var{action}が@code{file}か@code{file+name}の時のみ有効です。
一時ファイルのモードをunix式の整数で指定します。デフォルトは@code{#o600}です。
@c COMMON
@end table


@c EN
Note that the parameters that are not file uploads are not the subject
of @var{part-handlers}; such parameter values are always turned into a string.
@c JP
ファイルアップロード以外のパラメータは@var{part-handlers}の対象外である
ことに注意して下さい。それらのパラメータの値は常に文字列へと変換されます。
@c COMMON


@c EN
Here's a short example.  Suppose you have a form like this:
@c JP
簡単な例を示します。例えば次のようなフォームがあったとします。
@c COMMON

@example
<form enctype="multipart/form-data" method="POST" action="mycgi.cgi">
<input type="file" name="imagefile" />
<input type="text" name="description" />
<input type="hidden" name="mode" value="normal" />
</form>
@end example

@c EN
If you use @code{cgi-parse-parameters} in @file{mycgi.cgi}
without @var{part-handlers} argument,
you'll get something like the following as the result.
(The actual values depend on how the web client filled the form).
@c JP
@file{mycgi.cgi}内で、@code{cgi-parse-parameters}を
@var{part-handlers}引数なしで使った場合は、
例えば次のようなリストがパラメータパージングの結果として得られるでしょう。
(実際の値は、webクライアントがどのようにフォームを埋めたかに依存します)。
@c COMMON

@example
(("imagefile" #*".....(image file content as a string)....")
 ("description" "my image")
 ("mode" "normal"))
@end example

@c EN
If you pass @code{'(("imagefile" file :prefix "/tmp/mycgi"))}
to @var{part-handlers}
instead,
you might get something like the following, with the
content of uploaded file saved in @file{/tmp/mycgi7gq0B}
@c JP
ここでもし、@code{'(("imagefile" file :prefix "/tmp/mycgi"))}を
@var{part-handlers}に
渡したなら、替わりに次のような結果が得られるでしょう。
ここで、アップロードされたファイルは@file{/tmp/mycgi7gq0B}にセーブ
されていることになります。
@c COMMON

@example
(("imagefile" "/tmp/mycgi7gq0B")
 ("description" "my image")
 ("mode" "normal"))
@end example

@c EN
If you use a symbol @code{file+name} instead of @code{file} above,
you'll get something like @code{("/tmp/mycgi7gq0B" "logo.jpg")} as
the value of @code{"imagefile"}, where @code{"logo.jpg"} is the
client-side filename.   (Note: the client can send any string
as the name of the file, so @emph{never} assume it is a valid
pathname).
@c JP
上の例でシンボル@code{file}のかわりに@code{file+name}を使えば、
例えば@code{"imagefile"}の値として@code{("/tmp/mycgi7gq0B" "logo.jpg")}
のようなものが得られるでしょう。ここで@code{"logo.jpg"}は
アップロードされたファイルのクライアント側でのパス名です。
(注意：クライアントは任意の文字列をファイル名として送信することが
できるため、その文字列が有効なパス名であることを仮定してはなりません。)

@c COMMON

@c @c EN
@c Now, you pass the following structure to @var{part-handlers}:
@c @c JP
@c 次のような構造を@var{part-handlers}に渡した場合：
@c @c COMMON

@c @example
@c `(("imagefile"
@c   ,(lambda (name fname info iport)
@c      (receive (outp tmpfile) (sys-mkstemp "/var/log/mycgi/tmp")
@c        (mime-retrieve-body info iport outp)
@c        (close-output-port outp)
@c        (cgi-add-temporary-file tmpfile)
@c        (string-append fname ":" tmpfile))))
@c  )
@c @end example

@c @c EN
@c You'll get something like the following; i.e. the cgi application
@c can see the client-side file name as well as the temporary file name.
@c @c JP
@c 例えば次のようなパーズ結果が得られるでしょう。つまり、
@c cgiアプリケーションは一時ファイル名と同時に
@c クライアント側でのファイル名も参照することができます。
@c @c COMMON

@c @example
@c (("imagefile" "logo.jpg:/var/log/mycgi/tmp820iQj")
@c  ("description" "my image")
@c  ("mode" "normal"))
@c @end example


@c ----------------------------------------------------------------------
@node CGI testing, CSS parsing and construction, CGI utility, Library modules - Utilities
@section @code{www.cgi.test} - CGI testing
@c NODE CGIのテスト, @code{www.cgi.test} - CGIのテスト

@deftp {Module} www.cgi.test
@mdindex www.cgi.test
@c EN
This module defines a useful procedures to test CGI script.
The test actually runs the named script, with specified environment
variable settings, and retrieve the output.  Your test procedure
then examine whether the output is as expected or not.
@c JP
CGIスクリプトをテストするための便利な手続きを定義しています。
このテストは、指定された環境変数をセットし、実際にスクリプトを
実行し、出力を取得します。ユーザのテスト手続きは、その出力が
期待したものであるかどうかを検査します。
@c COMMON
@end deftp

@defun cgi-test-environment-ref envvar-name
@defunx {(setter cgi-test-environment-ref)} envvar-name value
@c MOD www.cgi.test
@c EN
The module keeps a table of default values of environment variables
with which the cgi script will be run.  These procedures allow
the programmer to get/set those default values.

Note that you can override these default values and/or pass additional
environment variables for each call of cgi script.
@c JP
モジュールにより、CGIスクリプトが実行される際の環境変数の
デフォルト値のテーブルが保持されます。プログラマは、これらの
手続きを使ってそのデフォルト値を取得したり設定したりできます。

CGIスクリプトの呼び出し毎に、これらのデフォルト値を上書きしたり、
追加の環境変数を渡したりできます。

@c EN
The following environment variables are set by default.
@c JP
デフォルトでは、下記の環境変数が設定されています。
@c COMMON
@multitable @columnfractions .5 .5
@item Name @tab Value
@item @code{SERVER_SOFTWARE}
@tab @code{cgitest/1.0}
@item @code{SERVER_NAME}
@tab @code{localhost}
@item @code{GATEWAY_INTERFACE}
@tab @code{CGI/1.1}
@item @code{SERVER_PROTOCOL}
@tab @code{HTTP/1.1}
@item @code{SERVER_PORT}
@tab @code{80}
@item @code{REQUEST_METHOD}
@tab @code{GET}
@item @code{REMOTE_HOST}
@tab @code{remote}
@item @code{REMOTE_ADDR}
@tab @code{127.0.0.1}
@end multitable
@end defun

@defun call-with-cgi-script script proc :key (environment ()) (parameters #f)
@c MOD www.cgi.test
@c EN
Runs a script with given environment, and calls @var{proc} with
one argument, an input port which is connected to the pipe of script's
standard output.
@c JP
与えられた環境でスクリプトを実行し、そのスクリプトの標準出力のパイプに
接続された入力ポートを1つ引数に取る @var{proc} を呼び出します。

@c EN
The argument @var{script} should be a list of
program name and its arguments.  Each element are
passed to @code{x->string} first to stringify.
@c JP
引数 @var{script} は、プログラムの名前とその引数のリストでなければ
なりません。リストの要素はそれぞれ、文字列化されるためにまず
@code{x->string}に渡されます。

@c EN
The script is run under the environment given by @var{environment}
variable and the default test environment described above.
The @var{environment} argument must be an associative list, in which each
key (@code{car}) is the name of the environment variable and
its @code{cdr} is the value.  Both are passed to @code{x->string} first.
If the same environment variable appears in @var{environment} and
the default test environment, the one in @var{environment} is used.
@c JP
スクリプトは、変数 @var{environment} で与えられる環境と、上述した
デフォルトのテスト環境の下で実行されます。
@var{environment}は、キー(@code{car})がその環境変数の名前、
@code{cdr}が対応する値であるような連想リストでなければなりません。
両方ともまず @code{x->string} に渡されます。
@var{environment} とデフォルトのテスト環境に同じ環境変数がある場合は、
@var{environment} にあるものが使われます。

@c EN
Additionally, if an associative list is given to the @var{parameters}
argument, a query string is built from it and passed the script.
The actual method to pass the query string depends on the value
of @code{REQUEST_METHOD} environment variable in the setting.
If @code{REQUEST_METHOD} is either @code{GET} or @code{HEAD},
the query string is put in an environment variable @code{QUERY_STRING}.
If it is @code{POST}, the query string is fed to the standard
input of the script.  In the latter case, @code{CONTENT_TYPE}
is set to @code{application/x-www-form-urlencoded} and
@code{CONTENT_LENGTH} are set to the length of @code{QUERY_STRING}
automatically.  If @code{REQUEST_METHOD} is other values,
@var{parameters} is ignored.
You can bypass this mechanism and set up environment variable
@code{QUERY_STRING} directly, if you wish.
@c JP
さらに、引数 @var{parameters} に連想リストが渡された場合、そこから
クエリストリングが作られスクリプトに渡されます。
クエリストリングを渡す実際のメソッドは、環境変数 @code{REQUEST_METHOD}の
値に依存します。@code{REQUEST_METHOD} が @code{GET} か @code{HEAD} で
ある場合は、クエリストリングは環境変数 @code{QUERY_STRING} に置かれます。
@code{REQUEST_METHOD} が @code{POST} の場合は、クエリストリングは
スクリプトの標準入力から取得されます。後者の場合、@code{CONTENT_TYPE} には
@code{application/x-www-form-urlencoded}が、
@code{CONTENT_LENGTH} には @code{QUERY_STRING}の長さが、それぞれ自動的に
セットされます。@code{REQUEST_METHOD} がその他の値の場合は、
@var{parameters} は無視されます。
必要であれば、このメカニズムをバイパスして、環境変数 @code{QUERY_STRING} を
直接セットアップすることも可能です。
@c COMMON
@end defun

@defun run-cgi-script->header&body script reader :key environment parameters
@c MOD www.cgi.test
@c EN
A convenient wrapper of @code{call-with-cgi-script}.
The @var{script}, @var{environment} and @var{parameters} are passed
to @code{call-with-cgi-script} as they are.
The output of the script is parsed by
@code{run-cgi-script->header&body}.
First, the RFC2822 header fields are parsed by
@code{rfc822-read-headers} (@pxref{RFC822 message parsing}).
Then, the @var{reader} is called with an input port which
is piped to the script's output.
@c JP
@code{call-with-cgi-script} の便利なラッパー手続きです。
@var{script}、@var{environment}、@var{parameters}は、
そのまま @code{call-with-cgi-script}に渡されます。
スクリプトの出力は、@code{run-cgi-script->header&body}により
パーズされます。
最初に、RFC2822ヘッダフィールドが @code{rfc822-read-headers}
(@ref{RFC822 message parsing}参照)によりパーズされます。
次に、@var{reader}が、スクリプトの出力にパイプされた入力ポートと
ともに呼ばれます。

@c EN
@code{Run-cgi-script->header&body} returns two values,
the list of headers (as parsed by @code{rfc822-read-headers}),
and the return value of @var{reader}.
@c JP
@code{run-cgi-script->header&body}は、ヘッダのリスト
(@code{rfc822-read-headers}によりパーズされたもの)と
@var{reader}の戻り値の2つの値を返します。
@c COMMON
@end defun

@defun run-cgi-script->sxml script :key environment parameters
@c MOD www.cgi.test
@c EN
This is a procedure that uses @code{ssax:xml->sxml}
(@pxref{Functional XML parser}) as the @var{reader}
in @code{run-cgi-script->header&body}.
Useful when you're testing a cgi script that produces
well-formed HTML and/or XML document.
@c JP
この手続きでは、@code{run-cgi-script->header&body}の
@var{reader}として、@code{ssax:xml->sxml}
(@ref{Functional XML parser}参照)を使います。
整形式(Well-formed)のHTMLやXMLドキュメントを生成する
CGIスクリプトをテストする場合に便利です。
@c COMMON
@end defun

@defun run-cgi-script->string script :key environment parameters
@defunx run-cgi-script->string-list script :key environment parameters
@c MOD www.cgi.test
@c EN
These procedures use @code{port->string}
and @code{port->string-list}
(@pxref{Input utility functions}) as the @var{reader}
in @code{run-cgi-script->header&body}, respectively.
@c JP
これらの手続きは、@code{run-cgi-script->header&body}の
@var{reader}として、それぞれ @code{port->string}、
@code{port->string-list}を使います。
@c COMMON
@end defun

@c EN
An example:
@c JP
例:
@c COMMON
@example
(run-cgi-script->string-list "bbs.cgi"
                             :environment '((REMOTE_ADDR . "12.34.56.78"))
                             :parameters '((command . "view")
                                           (page . 1234)))
@end example


@c ----------------------------------------------------------------------
@node CSS parsing and construction,  , CGI testing, Library modules - Utilities
@section @code{www.css} - CSS parsing and construction
@c NODE CSSのパーズと構築, @code{www.css} - CSSのパーズと構築

@deftp {Module} www.css
@c EN
This module provides tools to convert between S-expression and CSS.

The S-expression CSS (SxCSS) is a convenient way to manipulate
CSS in Scheme.
@c JP
このモジュールはS式とCSSを相互変換するツールを提供します。

S式CSS(SxCSS)はCSSをSchemeから操作するのに便利な方法です。
@c COMMON
@end deftp

@c EN
For example, the following CSS and SxCSS are equivalent, and
can be converted back and forth:
@c JP
例えば、次のCSSとSxCSSは等価で、相互に変換可能です。
@c COMMON

CSS:
@example
body @{ padding-left: 11em;
       font-family: Georgia, "Times New Roman", Times, serif;
       color: purple;
       background-color: #d8da3d @}
ul.navbar li @{ background: white;
               margin: 0.5em 0;
               padding: 0.3em;
               border-right: 1em solid black @}
ul#spec > a @{ text-decoration: none @}
a:visited @{ color: purple !important @}
@end example

SxCSS:
@example
((style-rule body
   (padding-left (11 em))
   (font-family (:or Georgia "Times New Roman" Times serif))
   (color purple)
   (background-color (color "d8da3d")))
 (style-rule ((ul (class navbar)) li)
   (background white)
   (margin #((0.5 em) 0))
   (padding (0.3 em))
   (border-right #((1 em) solid black)))
 (style-rule ((ul (id spec)) > a) (text-decoration none))
 (style-rule (a (: visited)) (color purple !important)))
@end example

@c EN
See the ``CSS in S-expression'' section below for the complete
specification.
@c JP
完全な仕様については下の ``S式CSS'' を参照してください。
@c COMMON

@c EN
@subheading Constructing CSS
@c JP
@subheading CSSの構築
@c COMMON

@defun construct-css sxcss :optional oport
@c MOD www.css
@c EN
Take SxCSS and writes out CSS to the given port, defaulted to
the current output port.
@c JP
SxCSSを取り、与えられたポートにCSSを書き出します。@var{oport}のデフォルトは
現在の出力ポートです。
@c COMMON
@end defun

@c EN
@subheading Parsing CSS
@c JP
@subheading CSSのパーズ
@c COMMON

@defun parse-css :optional iport
@c MOD www.css
@c JP
Read CSS from the given port, defaulted to the current input port,
and returns SxCSS.

When it encounters unparsable CSS (either a malformed CSS, or
unsupported syntax), it emits a warning message, ignore the
unparsable part and tries to continue reading the rest.

NB: Currently we don't handle @code{@@charset} directive; we assume
the text is already in the port's encoding.  We may support
it in future versions.
@c JP
CSSを与えられたポートから読み、SxCSSを返します。@var{iport}のデフォルトは
現在の入力ポートです。

パーズできないCSS (不正なCSSか、サポートされていない構文) に出会った場合、
warningメッセージを出力してその箇所を飛ばし、次にパーズできるところから処理を続けます。

註：今のところ、@code{@@charset}ディレクティブは無視され、
入力テキストはポートのエンコーディングであると仮定されます。将来は対応するかもしれません。
@c COMMON
@end defun

@defun parse-css-file file :key encoding
@c MOD www.css
@c EN
Read the CSS text from the given file and parse it using
@code{parse-css}.  Again, we don't handle @code{@@charset} directive
yet, and you have to pass @code{encoding} argument if
the CSS text isn't in the Gauche's native character encoding.
@c JP
与えられたファイルからCSSを読み、@code{parse-css}を使ってパーズして結果をSxCSSで
返します。@code{@@charset}ディレクティブはまだ認識されないので、
CSSファイルがGaucheのネイティブエンコーディングと異なるエンコーディングで書かれている
場合は、@var{encoding}にエンコーディング名を渡してください。
@c COMMON
@end defun

@defun parse-css-selector-string str
@c MOD www.css
@c EN
This parses the selector part of the CSS.
@c JP
CSSのセレクター部分をパーズするユーティリティです。
@c COMMON

@example
(parse-css-selector-string "ul li.item span#foo")
  @result{} (ul (li (class item)) (span (id foo)))

(parse-css-selector-string "h1,h2")
  @result{} (:or h1 h2)
@end example
@end defun

@c EN
@subheading CSS in S-expression
@c JP
@subheading S式CSS
@c COMMON

@c EN
The following is the complete rules of SxCSS syntax.
@c JP
完全なSxCSSの構文規則を以下に示します。
@c COMMON

@smallexample
<sxcss>      : (@{<style-rule> | <at-rule>@} ...)

<style-rule> : (style-rule <pattern> <declaration> ...)
             | (style-decls <declaration> ...)

<pattern>   : <selector> | (:or <selector> ...)
<selector>  : <simple-selector>
            | <chained-selector>
<chained-selector> : (<simple-selector> . (<op>? . <chained-selector>))
<op>        : > | + | ~
<simple-selector> : <element-name>
            | (<element-name> <option> ...)
<option>    : (id <name>)                           ; E#id
            | (class <ident>)                       ; E.class
            | (has <ident>)                         ; E[attrib]
            | (= <ident> <attrib-value>)            ; E[attrib=val]
            | (~= <ident> <attrib-value>)           ; E[attrib~=val]
            | (:= <ident> <attrib-value>)           ; E[attrib|=val]
            | (*= <ident> <attrib-value>)           ; E[attrib*=val]
            | (^= <ident> <attrib-value>)           ; E[attrib^=val]
            | ($= <ident> <attrib-value>)           ; E[attrib$=val]
            | (:not <negation-arg>)                 ; E:not(s)
            | (: <ident>)                           ; E:pseudo-class
            | (: (<fn> <ident> ...))                ; E:pseudo-class(arg)
            | (:: <ident>)                          ; E::pseudo-element
<element-name> : <ident> | *
<attrib-value> : <ident> | <string>
<negation-arg> | <element-name> | * | <option>  ; except <negation-arg>

<declaration>  : (<ident> <expr> <expr2> ... <important>?)
<important> : !important
<expr>      : <term>
            | (/ <term> <term> ...)
            | (:or <term> <term> ...)
            | #(<term> <term> ...)             ; juxtaposition
<term>      : <quantity> | (- <quantity>) | (+ <quantity>)
            | <string> | <ident> | <url> | <hexcolor> | <function>
<quantity>  : <number>
            | (<number> %)
            | (<number> <ident>)
<url>       | (url <string>)
<hexcolor>  | (color <string>)  ; <string> must be hexdigits
<function>  | (<fn> <arg> ...)
<arg>       | <term> | #(<term> ...) | (/ <term> <term> ...)

<at-rule>    : <at-media-rule> | <at-import-rule>
                   ; NB: Other at-rules are not supported yet
<at-media-rule>  : (@@media (<symbol> ...) <style-rule> ...)
<at-import-rule> : (@@import <string> (<symbol> ...))
@end smallexample

@c EN
NB: Negation op is @code{:not} instead of @code{not}, 
since @code{(not <negation-arg>)}
would be ambiguous from the simple node named "not" with one option.
@c JP
註: 否定オペレータは@code{not}ではなく@code{:not}です。
というのは、@code{(not <negation-arg>)}だと ``not'' と言う名前を持ち
一つのオプションを持つノードと区別できないからです。
@c COMMON

@c EN
NB: @code{style-decls} selector rule is currently won't appear in
the @code{parse-css} output; it can be used in SxCSS to make
@code{construct-css} render declarations only, which can be
used in the @code{style} attribute of the document, for example.
@c JP
註: @code{style-decls}セレクタルールは@code{parse-css}の出力には
現れません。
ドキュメントの@code{style}属性に渡すCSS断片を生成したい場合に、
@code{(style-decls <declaration> ...)}を@code{construct-css}に渡します。
@c COMMON
@example
(with-output-to-string 
 (cut construct-css
      '((style-decls (width (50 %))
                     (padding #(0 (10 pt) 0 (10 pt)))))))
  @result{} "width:50%;padding:0 10pt 0 10pt"
@end example

@c Local variables:
@c mode: texinfo
@c coding: utf-8
@c end:
