@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
* Backward-compatible real elementary functions::  compat.real-elementary-functions
* Concurrent sequences::        control.cseq
* Futures::                     control.future
* A common job descriptor for control modules::  control.job
* Plumbing ports::              control.plumbing
* Parallel map::                control.pmap
* Scheduler::                   control.scheduler
* 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
* Range::                       data.range
* Ring buffer::                 data.ring-buffer
* Skew binary random-access lists::  data.skew-list
* Sparse data containers::      data.sparse
* Trie::                        data.trie
* Universally unique lexicographically sortable identifier::  data.ulid
* 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
* Mathematical constants::      math.const
* Mersenne-Twister random number generator::  math.mt-random
* Prime numbers::               math.prime
* Simplex solver::              math.simplex
* 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 client::                 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
* Text filling::                text.fill
* Gap buffer::                  text.gap-buffer
* Localized messages::          text.gettext
* Simple HTML document construction::  text.html-lite
* Accessing info document::     text.info
* Multicolumn formatting::      text.multicolumn
* Display with pager::          text.pager
* Parsing input stream::        text.parse
* Showing progress on text terminals::  text.progress
* Segmented string matching::   text.segmented-match
* Shell text utilities::        text.sh
* 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
* R6RS identifier syntax::      util.identifier-syntax
* 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
* Temporal relation::           util.temporal-relation
* Topological sort (legacy)::   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 MOD compat.chibi-test
@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, Backward-compatible real elementary functions, 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 Backward-compatible real elementary functions, Concurrent sequences, Rational-less arithmetic, Library modules - Utilities
@section @code{compat.real-elementary-functions} - Backward-compatible real elementary functions
@c NODE 後方互換な実数初等関数, @code{compat.real-elementary-functions} - 後方互換な実数初等関数

@deftp {Module} compat.real-elementary-functions
@mdindex compat.real-elementary-functions
@c EN
Gauche 0.9.12 and earlier had undocumented real-only elementary functions,
such as @code{%sin} and @code{%exp}.  They were intended to be a building
block of the complex elementary functions, hence prefixed with @code{%}.
However, they were visible in @code{gauche} module, and sometimes used
directly because they were fast.
@c JP
Gauche 0.9.12とそれ以前のバージョンでは、正式にドキュメントされていませんでしたが、
実数のみを対象とした@code{%sin}や@code{%exp}といった初等関数が提供されていました。
複素数までを対象にした初等関数はそれらの上に構築されていて、
実数対象バージョンは内部ルーチンという意図でした(なので@code{%}が頭についています)が、
@code{gauche}モジュールで見えるようになっていたのと、複素数バージョンより速かったので、
過去のコードでこれらの関数を直接呼んでいるコードがあります。
@c COMMON

@c EN
SRFI-94 introduced names for real-only elementary functions
such as @code{real-sin}, so we changed built-in @code{%sin} etc.
to follow that names.  @xref{Arithmetics}, for those real-only
elementary functions.
@c JP
SRFI-94で、実数のみ対象の初等関数に@code{real-sin}などの名前が規定されたので、
0.9.13から@code{%sin}などを@code{real-sin}にリネームした上で正式にドキュメントしました。
@ref{Arithmetics}に説明があります。
@c COMMON

@c EN
This module is to ease migration from the legacy code that uses
old names.  Just add the following form at the beginning of
old code and the source would work with both versions.
@c JP
このモジュールは、古い名前を使っている既存のコードからの移行を補助するためのものです。
次のフォームを付け加えてやれば、古いコードはどのバージョンのGaucheでも動きます。
@c COMMON

@example
(cond-expand
  [(library (compat real-elementary-functions))
   (use compat.real-elementary-functions)]
  [else])
@end example

@c EN
New code must use @code{real-sin} etc. instead of the names provided here.
@c JP
新規コードは、このモジュールにある名前ではなく@code{real-sin}などの名前を使ってください。
@c COMMON
@end deftp

@defun %exp x
@defunx %sin x
@defunx %cos x
@defunx %tan x
@defunx %sinpi x
@defunx %cospi x
@defunx %tanpi x
@defunx %asin x
@defunx %acos x
@defunx %atan x
@defunx %sinh x
@defunx %cosh x
@defunx %tanh x
@defunx %sqrt x
@defunx %expt x a
@c MOD compat.real-elementary-functions
@c EN
These are the same as the built-in procedures replacing preceding @code{%}
with @code{real-}; e.g. @code{%exp} @equiv{} @code{real-exp}.
@xref{Arithmetics}, for the description of built-in procedures.
@c JP
これらは、@code{%}を@code{real-}で置き換えた組み込み手続きと同じです。
(例: @code{%exp} @equiv{} @code{real-exp})。
これらの組み込み手続きについては@ref{Arithmetics}を参照してください。
@c COMMON
@end defun

@defun %log x :optional base
@c MOD compat.real-elementary-functions
@c EN
This is a real-only logarithm of @var{x} base @var{base}.
@var{x} must be a non-negative real
number, and @var{base} must be a positive real number.
If @var{base} is omitted, Napier's number is assumed, that is,
it returns a natural logarithm of @var{x}.
If @var{x} is 0, @code{-inf.0} is returned.
@c JP
これは実数のみを対象とした、@var{base}を底とする@var{x}の対数関数です。
@var{x}は非負実数、@var{base}は正の実数でなければなりません
@var{base}が省略された時はネイピア数が使われます。
すなわち、@var{x}の自然対数を返します。
@var{x}が0の時は@code{-inf.0}が返されます。
@c COMMON

@c EN
Gauche does not have built-in @code{real-log}, to avoid conflict with
SRFI-94's @code{real-log} which takes @var{base} argument first.
For real-only natural logarithm, Gauche has @code{real-ln}.
@c JP
Gaucheは組み込みでは@code{real-log}を提供しません。
SRFI-94が底を第一引数にする@code{real-logを}を定義しているので、混同を避けるためです。
実数対象の自然対数には、組み込みの@code{real-ln}が使えます。
@c COMMON

@c EN
@xref{R7RS flonum}, which defines flonum-only version of logarithms
sich as @code{fllog}, @code{fllog2}, and @code{fllog10}.
@c JP
また、@ref{R7RS flonum}には、flonum専用の対数関数である
@code{fllog}、@code{fllog2}、@code{fllog10}等が定義されています。
@c COMMON
@end defun


@c ----------------------------------------------------------------------
@node Concurrent sequences, Futures, Backward-compatible real elementary functions, Library modules - Utilities
@section @code{control.cseq} - Concurrent sequences
@c NODE 並行シーケンス, @code{control.cseq} - 並行シーケンス

@deftp {Module} control.cseq
@mdindex control.cseq
@c EN
Concurrent sequence (cseq) is a lazy sequence (@pxref{Lazy sequences}), but
the generator runs in a separate thread.  You can use producer-consumer
pararellism very easily using cseq; from the consumer side,
it just looks like an ordinary list.  Synchornization is implicitly
taken care of.

Internally, it uses mtqueue (@pxref{Queue}) for synchronization.
@c JP
並行シーケンス (cseq) はジェネレータが別スレッドで走る遅延シーケンスです
(遅延シーケンスについては@ref{Lazy sequences}参照)。
cseqを使うと、生産者-消費者型の並列性を簡単に書けます。
消費者側からは、cseqは単なるリストに見え、同期は自動的に取られます。

内部的には、同期のためにmtqueueが使われています (@ref{Queue}参照)。
@c COMMON
@end deftp

@defun generator->cseq gen :key queue-length
@c MOD control.cseq
@c EN
Create a lazy sequence from generator, much like @code{generator->lseq},
except that @var{gen} runs in a separate thread.
@c JP
@code{generator->lseq}のように、ジェネレータから遅延シーケンスを作って返しますが、
ジェネレータ@var{gen}自体は別スレッドで実行されます。
@c COMMON

@c EN
The returend value looks like an ordinary list, but its
cdrs are computed in parallel.  If a cdr isn't computed yet, the reader
thread waits until a value becomes available.  The generator @var{gen}
can be called to generate values asynchronously, until the internal queue
gets full.  (Compare this to an ordinary lseq, in which @var{gen} is called
when it is required, and it runs in the same thread as the caller.)
@c JP
返される値は通常のリストのように見えますが、cdr方向のリストの要素は
並行して計算されます。cdrを取ろうとしてそれがまだ計算されていなければ、
読み出し側のスレッドはその値が計算されるまで待ちます。
ジェネレータ@var{gen}は別スレッドで非同期に実行され、
内部キューがいっぱいになるまで値を生成し続けます。
(対比として、
通常のlseqでは、@var{gen}は値が必要になった時に、読み出すスレッドで実行されます。)
@c COMMON

@c EN
If @var{gen} raises an error, it is caught, and reraised when the
consumer reads to the point when @var{gen} raised the error.
@c JP
@var{gen}がエラーを投げた場合、それは捕捉され、
消費者がそのエラーが起きたポイントまで読み進めた時に消費者側のスレッドで再度投げられます。
@c COMMON

@c EN
The optional @var{queue-length} must be a nonnegative exact integer or @code{#f}.
If it is an integer, it specifies the length of the internal queue.
If it is @code{#f}, an appropriate value is selected by the library
(currently 64).
@c JP
省略可能な引数@var{queue-length}は非負の正確な整数か@code{#f}でなければなりません。
整数の場合は、内部のキューの長さを指定します。
@code{#f}の場合はライブラリのデフォルトの長さが使われます。
@c COMMON

@c EN
Note that Gauche's lseq read-ahead one item (@pxref{Lazy sequences}).  So
even if you set the queue length to 0, @var{gen} is called before
the consumer reads out any value.
@c JP
Gaucheのlseqは一要素先読みすることに注意してください(@ref{Lazy sequences}参照)。
キュー長を0に指定しても、@var{gen}は消費者が値を呼び出す前に一回呼び出されます。
@c COMMON
@end defun


@defun coroutine->cseq proc :key queue-length
@c MOD control.cseq
@c EN
Returns an lseq, whose value is generated in @var{proc}, which is called
in a separate thread.  (See also @code{coroutine->lseq},
@ref{Lazy sequence constructors}).
The @var{proc} argument is a procedure to be called with one argument,
@var{yield}.  The @var{yield} argument is a procedure, and whenever it is
called with a value, that value becomes the next item of the resulting lseq.
When @var{proc} returns, it becomes the end of the lseq.
@c JP
@code{coroutine->lseq} (@ref{Lazy sequence constructors}) のように、
値が@var{proc}によって生成されるlseqを返しますが、@var{proc}自体は別スレッドで
実行されます。
@var{proc}引数は、引数@var{yield}を取る手続きです。
@var{yield}引数は1引数の手続きで、それが呼び出されると、引数に渡された値が
lseqの次の要素になります。
@var{proc}がリターンしたら、lseqはそこで終端となります。
@c COMMON

@c EN
If @var{proc} raises an error, it is caught, and reraised when the
consumer reads to the point when previously generated values are all read
and next value is about to read.
@c JP
@var{proc}がエラーを投げた場合、それは捕捉され、
消費者がその箇所まで読み進めた時に消費者スレッドで再度投げ直されます。
@c COMMON

@c EN
The optional @var{queue-length} must be a nonnegative exact integer or @code{#f}.
If it is an integer, it specifies the length of the internal queue.
If it is @code{#f}, an appropriate value is selected by the library
(currently 64).
@c JP
省略可能な引数@var{queue-length}は非負の正確な整数か@code{#f}でなければなりません。
整数の場合は、内部のキューの長さを指定します。
@code{#f}の場合はライブラリのデフォルトの長さが使われます。
@c COMMON
@end defun


@c ----------------------------------------------------------------------
@node Futures, A common job descriptor for control modules, Concurrent sequences, Library modules - Utilities
@section @code{control.future} - Futures
@c NODE Future, @code{control.future} - Future

@deftp {Module} control.future
@mdindex control.future
@c EN
A @emph{future} is a simple construct for concurrent computation.

It encloses an expression, and compute its value concurrently.  The result
of computation can be retrieved later with @code{future-get}.
@c JP
@emph{future}は並行計算を簡単にする構造です。

指定された式の計算を並行して行います。計算結果は@code{future-get}で取り出すことができます。
@c COMMON

@c EN
Futures are introduced in MultiLisp, in which retrieval of the computed
value is implicit---a future is substituted with the result automatically.
Racket and Guile have futures as a library, though the primitive to
retrieve the result is called @code{touch}.  We avoided to use the name
since @code{touch} is too generic.
@c JP
futureはMultiLispで実装されました。
MultiLispのfutureは暗黙的、つまり計算が終わるとその結果に自動的に置き換わるものでした。
RacketとGuileはライブラリでfutureを提供していますが、
結果の取り出しを@code{touch}と呼んでいます。@code{touch}という名前は一般的にすぎるので、
Gaucheでは@code{future-get}と呼ぶことにしました。
@c COMMON
@end deftp

@defmac future expr
@c MOD control.future
@c EN
Returns a future object, which runs the computation of @var{expr} in
a separate thread.  The result(s) of @var{expr} can be retrieved by
@code{future-get}.   Note that @var{expr} can yield multiple values.
@c JP
@var{expr}を別スレッドで計算するfutureオブジェクトを返します。
@var{expr}の結果は@code{future-get}で取り出せます。
(@var{expr}は多値を生成することもできます)。
@c COMMON

@c EN
The @var{expr} is evaluated in the same environment
as @code{future} appears, though if an exception raised within @var{expr}
is not caught, its delivery is delayed until you call @code{future-get}.
@c JP
@var{expr}は@code{future}式と同じ環境で評価されます。
ただし、@var{expr}が捕捉されない例外を投げた場合は、@code{future-get}が呼ばれるまで
その例外の配送は遅延されます。
@c COMMON

@c EN
The following example runs HTTP access concurrently with other computation,
and retrieves the result later.
@c JP
次の例では、HTTPアクセスを他の計算と並行して走らせて、後で結果を取り出しています。
@c COMMON

@example
(use control.future)
(use rfc.http)

(let1 f (future (http-get "example.com" "/"))
  ... some computation ...
  (receive (code headers body) (future-get f)
    ...))
@end example

@end defmac

@defun make-future thunk
@c MOD control.future
@c EN
Returns a future that calls @var{thunk} in a separate thread.
@c JP
@var{thunk}を別スレッドで呼ぶfutureを返します。
@c COMMON

@example
(future expr) @equiv{} (make-future (lambda () expr))
@end example
@end defun


@defun future? obj
@c MOD control.future
@c EN
Returns @code{#t} if @var{obj} is a future, @code{#f} otherwise.
@c JP
@var{obj}がfutureなら@code{#t}を、そうでなければ@code{#t}を返します。
@c COMMON
@end defun


@defmac future-get future :optional timeout timeout-expr
@c MOD control.future
@c EN
The @var{future} argument must be an expression that yields a future.
This macro retrieves its the result(s).
@c JP
@var{future}引数はfutureを生成する式でなければなりません。
このマクロはその結果を取り出します。
@c COMMON

@c EN
If the result of @var{future} is already available, it is returned immediately.
If @var{future} is still computing, @code{future-get} blocks until
the result is ready by default.  You can limit how long you will wait by
@var{timeout} argument, which can be @code{#f} (default, no timeout),
a nonnegative real numebr (relative time in seconds), or
a @code{<time>} object (absolute timepoint).  If the timeout reaches
before the result is available, @var{timeout-expr} is evaluated
in the tail context of the call of @code{future-get}.
When @var{timeout-expr} is omitted, @code{#f} is assumed.
@c JP
@var{future}の結果が既に求まっていれば、この手続きはただちにそれを返します。
まだ計算中であった場合は、デフォルトでこの手続きは計算が終わるまでブロックします。
待つ時間の上限を@var{timeout}引数で指定することもできます。
@var{timeout}が@code{#f}(デフォルト)なら無制限に待ち、
非負実数ならその秒数だけ待ち、@code{<time>}オブジェクトならそれで指定される
絶対時間まで待ちます。タイムアウトが起きた場合は@var{timeout-expr}が
@code{future-get}の呼び出しの末尾コンテクストで評価されます。
@var{timeout-expr}が省略された場合のデフォルトは@code{#f}です。
@c COMMON

@c EN
Since this is a macro, you can put multi-value yielding expression
in @var{timeout-expr}.  It is convenient to give the timeout values
for a multi-value yielding future:
@c JP
これはマクロなので、多値を生成する式を@var{timeout-expr}に与えることが
できます。多値を生成するfutureに対するタイムアウト値を指定するのに便利です。
@c COMMON

@example
(define f (future (sys-sleep 1) (values 'a 'b 'c)))

(future-get f 0.1 (values 'x 'y 'z))
 @result{} @r{returns 3 values:} x y z
@end example

@c EN
If an uncaught exception is raised during computation in the future,
it is kept and reraised from @code{future-get}.  It is handled
in the dynamic environment of @code{future-get} (not the one in the original
@code{future} call).
If you call @code{future-get}
again on such future, the effect is undefined
(currently it returns @code{#<undef>} without raising an exception, but
it may change in future).
@c JP
futureの計算中に捕捉されない例外が投げられた場合、それは@code{future-get}を呼んだ時点で
@code{future-get}の動的環境で再び投げられます。
そのfutureにもう一度@code{future-get}を呼んだ場合の動作は未定義です
(現在は、二度目以降は例外を投げることなく@code{#<undef>}が返されますが、
将来変わる可能性があります)。
@c COMMON

@c EN
NB: Up to Gauche 0.9.15, @code{future-get} was a procedure.  We changed
it to a macro to allow multiple timeout values naturally.

For the backward compatibility, @code{future-get} is actually defined
as a hybrid macro (@pxref{Hybrid macros}),
so the existing code that passes @code{future-get}
as a higher-order function still works:
@c JP
註: Gauche 0.9.15までの@code{future-get}は手続きでしたが、
多値のタイムアウト値を自然に扱うために、マクロに変更されました。

互換性のために、@code{future-get}は実際にはハイブリッドマクロとして
定義されています (@ref{Hybrid macros}参照)。
@code{future-get}を高階手続きとして引数に渡している次のようなコードは
そのまま動きます:
@c COMMON

@example
(map future-get (list (future 1) (future 2))) @result{} (1 2)
@end example

@c EN
The only visible change from 0.9.15 code is when @var{timeout-expr}
is evaluated: In the previous releases, it was evaluated when you
call @code{future-get}; in the current releases, it is evaluated
when the timeout occurs.  If the exsting code relies on the timing,
it needs to be updated.
@c JP
0.9.15以前のコードとの唯一の目に見える違いは、いつ@var{timeout-expr}が
評価されるかです。以前のリリースでは、それは@code{future-get}の呼び出し時に
評価されていましたが、現在のリリースではタイムアウトが起きた時点で評価されます。
このタイミングに依存している既存のコードがあれば、アップデートが必要です。
@c COMMON
@end defmac

@defun future-done? future
@c MOD control.future
@c EN
Returns @code{#t} if computation in @var{future} is finished,
@code{#f} otherwise.
@c JP
@var{future}の計算が終わっていれば@code{#t}を、そうでなければ@code{#f}を返します。
@c COMMON
@end defun



@c ----------------------------------------------------------------------
@node A common job descriptor for control modules, Plumbing ports, Futures, 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 Plumbing ports, Parallel map, A common job descriptor for control modules, Library modules - Utilities
@section @code{control.plumbing} - Plumbing ports
@c NODE ポートの配管, @code{control.plumbing} - ポートの配管

@deftp {Module} control.plumbing
@mdindex control.plumbing
@c EN
This module provides utilities to use ports as communication channles
between threads.  Although some use cases don't involve threads,
the general mechanism implicitly use threads.   For example, a @emph{pump}
connects an input port and an output port, making the data available
from the input port to be written to the output port.  It spawns a
thread to read from the given input.
@c JP
このモジュールは、ポートをスレッド間のコミュニケーションチャネルとして使う
ユーティリティを提供します。ユースケースによってはスレッドを必ずしも必要としませんが、
一般的なメカニズムとして、暗黙のスレッドが使われることがあります。
例えば「ポンプ」と呼ばれるデバイスは入力ポートと出力ポートをつなぎ、
入力ポートに届いたデータを自動的に出力ポートに送ります。
このデバイスは内部で入力ポートからデータを読み出すスレッドをspawnします。
@c COMMON

@c EN
With this module, you can construct a system that takes data from
ports, and delivers it to other ports.  It is like you construct
plumbing system with multiple inlets and outlets; hence we named it
@emph{plumbing}.
@c JP
このモジュールを使って、1つ以上のポートからデータを吸い出し、それを1つ以上のポートへと
送り届けるシステムを作ることができます。
あたかも注水口(inlet)と排水口(outlet)がある配管(plumbing)システムを作るような
ものなので、このシステムを@emph{plumbing}と呼びます。
@c COMMON

@c EN
See @code{make-plumbing} below for the complete specification of
plumbing.
@c JP
plumbingの完全な仕様については下の@code{make-plumbing}の項を参照してください。
@c COMMON
@end deftp

@c EN
@subheading Plumbing system
@c JP
@subheading 配管システム
@c COMMON

@defun make-plumbing
@c MOD control.plumbing
@c EN
Creates and returns a new plumbing.
@c JP
新たなplumbingを作って返します。
@c COMMON

@c EN
To function, a plumbing need to have one or more @emph{inlets} and
one or more @emph{outlets}.  Data flowing in from inlets will flow out to
outlets.
@c JP
機能させるためには、plumbingは1つ以上の@emph{inlet} (注水口) と
1つ以上の@emph{outlet} (排水口)を持つ必要があります。
データはinletから流れ込み、outletから流れ出してゆきます。
@c COMMON

@c EN
Each inlet/outlet port can be either an input port or an output port; so
we'll have the following four cases:
@c JP
inlet, outletそれぞれどちらにも、入力ポート、出力ポートのいずれもつなぐことができます。
すなわち、次の4つの組み合わせがあり得ます。
@c COMMON

@table @asis
@c EN
@item Inlet input port
@c JP
@item Inlet入力ポート
@c COMMON
@c EN
An input port that provides data from a producer.  A dedicated thread
is spanwed to read and handle the data from this port.
@c JP
生産者から送られるデータを読み出せる入力ポートです。
このポートが繋がれた場合、専用のスレッドが作られポートからデータを読み出します。
@c COMMON
@c EN
@item Inlet output port
@c JP
@item Inlet出力ポート
@c COMMON
@c EN
An output port, to which a producer can write data.  Data written to
this port will be available to outlet ports.
@c JP
このポートに書き込まれたデータが配管システムに流れてゆきます。
@c COMMON
@c EN
@item Outlet input port
@c JP
@item Outlet入力ポート
@c COMMON
@c EN
An input port from which a consumer can read data.  It has an internal buffer
to keep data flowed in from inlets.
@c JP
配管を流れたデータが送られて、消費者がそこから流されたデータを読み出すことができる
入力ポートです。内部に、送られたデータを読み出されるまで保持しておくバッファを持っています。
@c COMMON
@c EN
@item Outlet output port
@c JP
@item Outlet出力ポート
@c COMMON
@c EN
An output port to which the data will be written.
@c JP
配管を流れたデータが送られる出力ポートです。
@c COMMON
@end table

@c EN
All read/write operations are mutexed, so you can use a plumbing
as a communication channel between threads.
@c JP
読み書きの動作は排他制御されているので、plumbingをスレッド間のコミュニケーションチャネル
として使うことができます。
@c COMMON

@c EN
The following example connects subprocess's stdout and stderr into
the current output port.  Both output of the subprocess is automatically
read from the pipe and sent to the current output port as produced.
@c JP
下の例は、サブプロセスのstdoutとstderrを現在の出力ポートにつなぐ例です。
サブプロセスからの両出力は、自動的にパイプから読み出されて逐次
現在の出力ポートへと送られます。
@c COMMON

@example
(use gauche.process)
(use control.plumbing)

(let ([p (run-process '(ping "127.0.0.1") :output :pipe :error :pipe)]
      [plumbing (make-plumbing)])
  (add-inlet-input-port! plumbing (process-output p))
  (add-inlet-input-port! plumbing (process-error p))
  (add-outlet-output-port! plumbing (current-output-port)))
@end example

@c EN
For typical plumbing configurations, there are utility procedures
defined so that you don't need to connect pots manually; see
``Preconfigured plumbings'' section below.
@c JP
典型的な配管構成については、ユーティリティ手続きが定義されていて
いちいちポートをひとつづつ繋がなくても良いようになっています。
下の ``組み立て済みplumbing'' の項を参照してください。
@c COMMON
@end defun

@defun plumbing? obj
@c MOD control.plumbing
@c EN
Returns @code{#t} if @var{obj} is a plumbing, @code{#f} if not.
@c JP
@var{obj}がplumbingであれば@code{#t}を、そうでなければ@code{#f}を返します。
@c COMMON
@end defun

@defun plumbing-inlet-ports plumbing
@defunx plumbing-outlet-ports plumbing
@c MOD control.plumbing
@c EN
Returns a list of ports connected to the @var{plumbing}'s inlets
and outlets, respectively.
@c JP
それぞれ、@var{plumbing}のinletおよびoutletに接続されたポートのリストを返します。
@c COMMON
@end defun

@defun plumbing-get-port plumbing name
@c MOD control.plumbing
@c EN
The @var{name} argument must be a symbol.
Returns a port connected to @var{plumbing} and with @var{name}.
Returns @code{#f} if there's no such ports.
@c JP
@var{name}引数はシンボルでなければなりません。
@var{plumbing}に接続されたポートで、名前@var{name}を持つものを返します。
該当するポートが無ければ@code{#f}が返ります。
@c COMMON
@end defun

@defun port-plumbing port
@c MOD control.plumbing
@c EN
A port opened for a plumbing with @code{open-outlet-input-port},
@code{open-inlet-output-port}, or other utility procedures, keeps
which plumbing it belongs to.  This procedure returns the plumbing
associated with @var{port}.  If @var{port} is not made from
a plumbing, @code{#f} is returned.
@c JP
@code{open-outlet-input-port}や@code{open-inlet-output-port}、あるいは
それらを使うユーティリティ手続きによって、plumbingのために作られたポートは、
そのプロパティとして元になったplumbingへの参照を保持しています。
この手続きは@var{port}が保持しているplumbingを返します。
@var{port}がplumbingによって作られたものでない場合は@code{#f}が返されます。
@c COMMON

@c EN
Note that an existing port added to a plumbing by
@code{add-inlet-output-port!} etc. does not keep the plumbing
it is attached to, and this procedure returns @code{#f} on such a port.
@c JP
既にあるポートを@code{add-inlet-output-port!}等でplumbingに接続した場合は、
そのポートはplumbingによって作られたわけではないので、この手続きは@code{#f}を返す
ことに注意してください。
@c COMMON
@end defun

@c EN
@subheading Creating and attaching ports to plumbing
@c JP
@subheading plumbingにポートを作ったり接続したりする
@c COMMON

@defun open-inlet-output-port plumbing :optional name
@c MOD control.plumbing
@c EN
Creates an output port connected to @var{plumbing}'s inlet; that is,
the data written to the port will flow to @var{plumbing}'s outlets.
@c JP
@var{plumbing}のinletに接続された出力ポートを作って返します。
このポートに書き込まれたデータは、@var{plumbing}を通ってそのoutletに流れてゆきます。
@c COMMON

@c EN
The optional @var{name} should be a symbol or @code{#f}.  If it is
a symbol, the port will be retrieved from @var{plumbing} with
@code{plumbing-get-port}.
@c JP
省略可能な@var{name}引数はシンボルか@code{#f}でなければなりません。
これがシンボルの場合、作られたポートは@code{plumbing-get-port}で
@var{plumbing}から取り出すことができます。
@c COMMON

@c EN
Applying @code{port-plumbing} on the returned port returns @var{plumbing}.
@c JP
また、返されたポートに@code{port-plumbing}を適用すると@var{plumbing}が得られます。
@c COMMON

@c EN
Once you close the returned port, the port is removed from @var{plumbing}.
Once all inlet ports are closed, the outlet ports of @var{plumbing}
get EOF.
@c JP
返されたポートをクローズすると、それは@var{plumbing}から取り除かれます。
全てのinletポートがクローズされた時に、@var{plumbing}のoutletポートはEOFを受け取ります。
@c COMMON
@end defun

@defun add-inlet-input-port! plumbing iport :optional name
@c MOD control.plumbing
@c EN
Connects an existing input port @var{iport} to @var{plumbing}'s inlet.
A thread in @var{plumbing} reads from @var{iport} and feeds the data
to its outlets.
@c JP
既存の入力ポート@var{iport}を@var{plumbing}のinletに接続します。
@var{iport}からデータを読み出し、それを@var{plumbing}のoutletに送るための
スレッドが作られます。
@c COMMON

@c EN
The optional @var{name} should be a symbol or @code{#f}.  If it is
a symbol, the port will be retrieved from @var{plumbing} with
@code{plumbing-get-port}.
@c JP
省略可能な@var{name}引数はシンボルか@code{#f}でなければなりません。
これがシンボルの場合、作られたポートは@code{plumbing-get-port}で
@var{plumbing}から取り出すことができます。
@c COMMON

@c EN
Once EOF is read from @var{iport}, it is removed from @var{plumbing}.
Once all inlet ports are closed, the outlet ports of @var{plumbing}
get EOF.
@c JP
@var{iport}からEOFが読まれたら、そのポートは@var{plumbing}から取り除かれます。
全てのinletポートがクローズされた時に、@var{plumbing}のoutletポートはEOFを受け取ります。
@c COMMON
@end defun

@defun open-outlet-input-port plumbing :optional name
@c MOD control.plumbing
@c EN
Creates an input port connected to @var{plumbing}'s outlet; that is,
from that port you can read the data fed to @var{plumbing}'s inlets.
@c JP
@var{plumbing}のoutletに接続された入力ポートを作って返します。
@var{plumbing}のinletに流れ込んだデータをそのポートから読み出すことができます。
@c COMMON

@c EN
The optional @var{name} should be a symbol or @code{#f}.  If it is
a symbol, the port will be retrieved from @var{plumbing} with
@code{plumbing-get-port}.
@c JP
省略可能な@var{name}引数はシンボルか@code{#f}でなければなりません。
これがシンボルの場合、作られたポートは@code{plumbing-get-port}で
@var{plumbing}から取り出すことができます。
@c COMMON

@c EN
Applying @code{port-plumbing} on the returned port returns @var{plumbing}.
@c JP
返されたポートに@code{port-plumbing}を適用すると@var{plumbing}が得られます。
@c COMMON

@c EN
Once all inlets are closed, the returned port yields EOF.
You can close the returned port at any time; then the port is removed
from @var{plumbing}'s outlets and no data will be delivered to it.
@c JP
全てのinletがクローズされると、返されたポートからEOFが読まれます。
返されたポートはいつでもクローズできます。クローズされるとそれは
@var{plumbing}のoutletから取り除かれ、データは送られなくなります。
@c COMMON
@end defun

@defun add-outlet-output-port! plumbing oport :optional name :key close-on-eof asynchronous
@c MOD control.plumbing
@c EN
Connects an existing output port @var{oport} to @var{plumbing}'s outlet.
Data flowed in from @var{plumbing}'s inlet will be written to @var{oport}.
@c JP
既存の出力ポート@var{oport}を@var{plumbing}のoutletに接続します。
@var{plumbing}に流れ込んだデータはその都度@var{oport}に送られます。
@c COMMON

@c EN
The optional @var{name} should be a symbol or @code{#f}.  If it is
a symbol, the port will be retrieved from @var{plumbing} with
@code{plumbing-get-port}.
@c JP
省略可能な@var{name}引数はシンボルか@code{#f}でなければなりません。
これがシンボルの場合、作られたポートは@code{plumbing-get-port}で
@var{plumbing}から取り出すことができます。
@c COMMON

@c EN
You can close the returned port at any time; then the port is removed
from @var{plumbing}'s outlets and no data will be delivered to it.
@c JP
返されたポートはいつでもクローズできます。クローズされるとそれは
@var{plumbing}のoutletから取り除かれ、データは送られなくなります。
@c COMMON

@c EN
By default, @var{oport} is left as is after all inlets are closed;
@var{plumbing} won't write anything to @var{oport} but you can still write to
it.  If you specify a true value to the @var{close-on-eof} keyword argument,
however, @var{plumbing} will close @var{oport} when all of its inlets are closed.
It is useful, for example, when @var{oport} is a file output port and
you want to close it once @var{plumbing} is done.  However, if @var{oport}
is a standard output port for logging purpose, you don't want it to be
automatically closed.
@c JP
デフォルトでは、全てのinletがクローズされた後でも@var{oport}はオープンしたままにされます。
@var{plumbing}がそれ以降そこに書き込むことはありませんが、
@var{oport}に追加で出力することはできます。
ただし、@var{close-on-eof}キーワード引数に真の値を指定すると、
@var{plumbing}は全てのinletがクローズされた時点で@var{oport}をクローズします。
これは、例えばファイルを出力用にオープンしてそのポートを@var{oport}として
渡し、データが来なくなったら自動的にクローズしたい、という場合に便利です。
けれども、例えばログ出力を監視するために@var{oport}に標準出力を渡すといった場合は、
勝手にクローズされると困るでしょう。
@c COMMON

@c EN
If a true value is given to the @var{asynchronous} keyword argument,
a thread is spawn to feed the data to @var{oport}; it is useful if
@var{oport} can be blocked, e.g. an OS pipe or a socket.
Without @var{asynchronous}, blocked output to @var{oport} causes
data flow to inlets to be blocked as well.  With @var{asynchronous},
other threads can keep feeding to inlets.
@c JP
@var{asynchronous}キーワード引数に真の値が渡された場合、
@var{oport}にデータを送るための専用スレッドが作られます。
これは、@var{oport}がOSのパイプやソケットのようにブロックする可能性がある場合に
便利です。@var{asynchronous}が無い場合、@var{oport}がブロックすると
plumbing全体がブロックしてしまう可能性があります。
@var{asynchronous}を指定しておくと、このポートへの出力以外は動きつづけます。
@c COMMON
@end defun

@defun plumbing spec @dots{}
@c MOD control.plumbing
@c EN
A utility plumbing constructor.  It creates a new plumbing,
and adds inlets and outlets as specified by @var{spec}s,
then returns the plumbing.  Each @var{spec} must be one of
the following forms.  In the description, @var{iport}
is an input port, @var{oport} is an output port, and
@var{name} is a symbol.
@c JP
plumbingを簡単に組み立てるためのユーティリティです。
新しいplumbingを作り、@var{spec}に従ってinletとoutletを接続して、
作られたplumbingを返します。各@var{spec}は以下に挙げる形式のいずれかです。
説明中、@var{iport}は入力ポート、@var{oport}は出力ポート、
@var{name}はシンボルです。
@c COMMON

@table @code
@item (< @var{iport})
@itemx (< @var{iport} @var{name})
@c EN
Adds @var{iport} to the plumbing's inlet, optionally naming it
with @var{name}.
@c JP
@var{iport}をplumbingのinletに接続します。名前@var{name}をつけることもできます。
@c COMMON
@item (< @var{name})
@c EN
Creates an inlet output port with name @var{name}.
The output port can be retrieved by @code{plumbing-get-port}.
@c JP
名前@var{name}を持つinlet出力ポートを作ります。
作られた出力ポートは@code{plumbing-get-port}で取り出すことができます。
@c COMMON
@item (> @var{oport})
@itemx (> @var{oport} @var{name})
@itemx (> @var{oport} (@var{option} @dots{}))
@itemx (> @var{oport} @var{name} (@var{option} @dots{}))
@c EN
Adds @var{oport} to the plumbing's outlet, optional naming it
with @var{name}.  Options can be one of the keywords @code{:close-on-eof},
@code{:coe}, @code{asynchronous}, and @code{:async}.  @code{:close-on-eof}
and @code{asynchronous} has the effect of giving true to those keyword
arguments to @code{add-outlet-output-port!}.  @code{:coe} and @code{:async}
are synonyms of @code{:close-on-eof} and @code{:asynchronous}, respectively.
@c JP
@var{oport}をplumbingのouletに接続します。@var{name}が与えられればそれが
名前になります。また、@var{option}としてキーワード
@code{:close-on-eof}、@var{:coe}、@code{:asynchronous}、@code{:async}の
組み合わせを指定することができます。@code{:close-on-eof}、@code{:asynchronous}は
@code{add-outlet-output-port!}で同名のキーワード引数に真の値を指定するのと同じ効果
を持ちます。@code{:coe}と@code{:async}はそれぞれ@code{:close-on-eof}と
@code{:asynchronous}の省略形です。
@c COMMON
@item (> @var{name})
@c EN
Creates an outlet input port with name @var{name}.
The output port can be retrieved by @code{plumbing-get-port}.
@c JP
名前@var{name}を持つoutlet入力ポートを作ります。
作られたポートは@code{plumbing-get-port}で取り出せます。
@c COMMON
@end table
@end defun

@c EN
@subheading Preconfigured plumbings
@c JP
@subheading 組み立て済みplumbing
@c COMMON

@c EN
The following are convenience procedures to construct typical
plumbings.
@c JP
以下に挙げるのは、典型的な組み立てのplumbingを作る便利手続きです。
@c COMMON

@defun make-pipe :key num-inlets num-outlets
@c MOD control.plumbing
@c EN
A pipe is a passive plumbing device that has inlet output port(s) and
outlet input port(s).
Data written to the inlet output ports
will be buffered and available to read from the outlet input ports.
This procedure creates a pipe
with @var{num-inlets} inlet output ports
and @var{num-outlets} outlet input ports,
and returns two values, a list of inlet ports and a list of outlet ports.
@c JP
パイプはinlet出力ポートとoutlet入力ポートを持つ受動的なplumbingです。
inlet出力ポートに書き込まれたデータは各outlet入力ポートにバッファされ、
読み出されるのを待ちます。
この手続きは、@var{num-inlets}個のinlet出力ポートと、
@var{num-outlets}個のoutlet出力ポートを持つパイプを作り、
inletポートのリストとoutletポートのリストの2つの値を返します。
@c COMMON

@c EN
Both @var{num-inlets}
and @var{num-outlets} should be a positive exact integer.  If omitted,
1 is assumed.
@c JP
@var{num-inlets}と@var{num-outlets}はともに正の正確な整数でなければなりません。
省略された場合は1とみなされます。
@c COMMON

@c EN
If there are more than one outlets, data stream is duplicated; each consumer
reads the same data.  Buffers are attached to each outlet, so each
consumer can read the outlet in its own pace.
@c JP
outletが複数ある場合、データストリームは複製されます。つまり、それぞれの消費者は
同じデータを読み出します。それぞれのoutletが独立したバッファを持つので、
各消費者はそれぞれのペースで読み出すことができます。
@c COMMON

@c EN
The created plumbing can be obtained by applying @code{port-plumbing}
to any of the returned ports.
@c JP
作られたplumbingを得るには、返されたポートのいずれかに@code{port-plumbing}を
適用します。
@c COMMON

@c EN
This procedure is similar to @code{sys-pipe}, which creates a pair
of ports using OS's pipe mechanism (@pxref{Other file operations}).
However, the pipe device
created by @code{make-pipe} is a user-land construct and only for
inter-thread communication; it can't be used for inter-process
communication.  On the other hand, you can have n-in m-out pipe
using @code{make-pipe}.
@c JP
この手続きは@code{sys-pipe}と似ていますが、
@code{sys-pipe}はOSのパイプを使い、その両端に繋がれた入力ポートと出力ポートを
返します (@ref{Other file operations}参照)。
@code{make-pipe}が作るパイプはあくまでユーザ空間の構築物で、
プロセス間通信には使えず、スレッド間通信にしか使えません。
一方、@code{make-pipe}はn-入力/m-出力のパイプを作ることができます。
@c COMMON
@end defun

@defun make-pump inlet-iports outlet-oports
@c MOD control.plumbing
@c EN
A pump is an active plumbing device that reads data from
the given inlet input ports, and write it out to the given
outlet output ports.
@c JP
ポンプは与えられた入力ポートからデータを読み出し、それを
与えられた出力ポートへと送り出す、アクティブなplumbingです。
@c COMMON

@c EN
The @var{inlet-iports} argument must be a list of input ports,
and @var{outlet-oports} argument must be a list of output ports.
@c JP
@var{inlet-iports}引数は入力ポートのリスト、
@var{outlet-oports}引数は出力ポートのリストでなければなりません。
@c COMMON

@c EN
A dedicated thread is spawn to each inlet input port to read
from it.
@c JP
各inlet入力ポートそれぞれに対し、そこから読み出すスレッドがスポーンされます。
@c COMMON
@end defun

@defun open-broadcast-output-port oport @dots{}
@c MOD control.plumbing
@c EN
All the arguments must be output ports.
Returns an output port such that data written to it go to every @var{oport}.
Internally, it creates a plumbing, adds @var{oport}s to its outlet,
and returns a new inlet output port.  The plumbing can be retrieved
by calling @code{port-plumbing} on the returned port.
@c JP
引数は全て出力ポートでなければなりません。
新たな出力ポートを返します。そのポートに書かれたデータは、全ての@var{oport}へと送られます。
内部的には、この手続きはplumbingを作り、@var{oport} @dots{}をoutletに接続し、
そしてinlet出力ポートを返します。返されたポートに@code{port-plumbing}を適用すれば
plumbingが得られます。
@c COMMON

@c EN
This is Common Lisp's @code{make-broadcast-stream}.
@c JP
これはCommon Lispの@code{make-broadcast-stream}にあたります。
@c COMMON
@end defun

@defun open-tapping-input-port inlet-iport outlet-oport :key close-on-eof
@c MOD control.plumbing
@c EN
It creates a pump, a plumbing that reads from @var{inlet-iport} and
writes out the read data to @var{outlet-oport}.  Additionally, it creates
and returns an outlet input port, from which you can read the data
flowing in the pump.
@c JP
これは、@var{inlet-port}からデータを吸出し@var{outlet-oport}に送り出すポンプを
作りますが、同時にそこに流れるデータを読み出せるoutlet入力ポートを作って返します。
@c COMMON

@c EN
An example use case is to monitor process output.  You spawn a process
with its stdout connected to a pipe, then call
@code{(open-tapping-input-port (process-output subprocess) (current-output-port))}.
With this, the subprocess's output automatically flows to your process's output.
However, that data is also available from the returned input port,
and you can check it.
@c JP
例えばそれは、プロセスの出力を監視するのに使えます。
標準出力をパイプに流す子プロセスを作り、
@code{(open-tapping-input-port (process-output subprocess) (current-output-port))} を呼びます。
すると、子プロセスの出力は自動的に現在の出力ポートに流されますが、
そのデータは戻り値の入力ポートから読み出せるので、そこで監視することができます。
@c COMMON

@c EN
Note that the data passed from @var{inlet-iport} to @var{outlet-oport} are
buffered for the returned input port until you read from it.  If you're
done with monitoring, you can close the returned input port safely; the
data will no longer be buffered, but the pump will keep running until
the input reaches EOF.
@c JP
@var{inlet-iport}から読み出され@var{outlet-oport}に送られるデータは、
戻り値の入力ポートからも読み出せるようにバッファされることに注意してください。
監視する必要がなくなったらいつでも、戻り値の入力ポートを閉じることができます。
そうすれば流れるデータはバッファされなくなりますが、ポンプはinletからのデータが
EOFに達するまで動きつづけます。
@c COMMON

@c EN
The pump plumbing is available by calling @code{port-plumbing} on the
returned input port.
@c JP
ポンプのplumbingは、戻り値の入力ポートに@code{port-plumbing}を適用すると得られます。
@c COMMON
@end defun

@c ----------------------------------------------------------------------
@node Parallel map, Scheduler, Plumbing ports, Library modules - Utilities
@section @code{control.pmap} - Parallel map
@c NODE 並列map, @code{control.pmap} - 並列map

@deftp {Module} control.pmap
@mdindex control.pmap
@c EN
This module provides high-level utilities to run code in parallel
using threads.
For example, the @code{pmap} procedure applies the given procedure
on each elements in the collection and gathers the results into a list,
just like @code{map}, but the appliation of the procedure is done in parallel.
@c JP
このモジュールは、コードを複数スレッドで並列に走らせる高レベルユーティリティを提供します。
例えば@code{pmap}は、@code{map}と同様に、
与えられたコレクションの各要素に手続きを適用してその結果をリストにして返しますが、
手続きの適用は並列に行われます。
@c COMMON

@c EN
A desired parallelization strategy differs for application, so we also
pvovide @emph{mapper} objects, that encapsulate how the work is distributed.
@c JP
応用によって望ましい並列化戦略が違うので、仕事の割り振りの戦略をカプセル化する
@emph{mapper}オブジェクトも提供されます。
@c COMMON
@end deftp

@c EN
@subheading High-level API
@c JP
@subheading 高レベルAPI
@c COMMON

@defun pmap proc collection :key mapper
@c MOD control.pmap
@c EN
The @var{proc} argument must be a procedure that takes one argument,
and @var{collection} must be a collection (@pxref{Collection framework}).
@c JP
@var{proc}はひとつの引数を取る手続き、@var{collection}はコレクションです
(@ref{Collection framework}参照)。
@c COMMON

@c EN
Applies @var{proc} on each element of @var{collection}, possibly concurrently
using multiple threads.  The result is gathered into a list and
returned.
@c JP
@var{collection}の各要素に、@var{proc}を適用します。
適用は複数のスレッドを使って並行して行われるかもしれません。結果はリストにまとめられて返されます。
@c COMMON

@c EN
You can pass a mapper to the @var{mapper} keyword argument to specify how
the task is distibuted to multiple threads.
@c JP
@var{mapper}キーワード引数にmapperを渡すことで、各スレッドにどのように仕事が
割り振られるかをカスタマイズできます。
@c COMMON

@c EN
If a @var{proc} raises an uncaptured condition, it is reraised
by @var{pmap}.  If uncaptured conditions are raised concurrently
from multiple threads, one of them are reraised, while others are
discarded.
@c JP
@var{proc}が捕捉されないコンディションをraiseした場合、
@var{pmap}はそれを再raiseします。複数のスレッドから同時に
捕捉されないコンディションが上がった場合は、どれかひとつが再raiseされ
他は捨てられます。

@c COMMON
@end defun

@defun pfind pred collection :key mapper
@defunx pany pred collection :key mapper
@c MOD control.pmap
@c EN
These are to be used to find one element that satisfies the predicate @var{pred}.
As soon as the element is found, other tasks are cancelled.
@c JP
これらは、@var{pred}を満たす要素を一つ見つけたい時に使えます。
条件に合う要素が見つかった時点で、他のタスクはキャンセルされます。
@c COMMON

@c EN
@code{pfind} is like @code{find} that returns the element that satisfies
@var{pred}, while @code{pany} is like @code{any} that returns the result
of @var{pred} that isn't @code{#f}.
@c JP
@code{pfind}は@code{find}のように、@var{pred}を満たす要素を見つけたらその要素自身を
返します。一方、@code{pany}は@code{any}と同じように、
@var{pred}が@code{#f}でない値を返したらその返り値を返します。
@c COMMON

@c EN
If no element satisfies @var{pred}, @code{#f} is returned.
@c JP
@var{pred}を満たす要素が一つも無ければ@code{#f}が返ります。
@c COMMON

@c EN
If there are more than one element that satisfy @var{pred}, which one is picked
depends on various factors, so you shouln't count on a deterministic behavior.
@c JP
@var{pred}を満たす要素が複数あった場合にどれが返るかは様々な状況に依存するので、
決定的な振る舞いを期待すべきではありません。
@c COMMON

@c EN
If @var{pred} raises an uncaptured condition, remaining tasks are
cancelled and the condition is reraised.
@c JP
@var{pred}が捕捉されないコンディションをraiseした場合、
他のタスクはキャンセルされ、コンディションが再raiseされます。
@c COMMON
@end defun

@subheading Mappers

@c EN
A mapper is an object that encapsulates a strategy to run
tasks in parallel.  We provide the following mappers.
@c JP
mapperはタスクを並列に走らせる戦略をカプセル化したものです。
次のmapperが提供されます。
@c COMMON

@table @code
@item Static mapper
@c EN
Creates several threads and distribute the tasks evenly.  It is suitable
when the number of tasks are large and each task is expected to take
mostly same amount of time, for it takes less overhead than other
multi-threading mappers.
@c JP
いくつかのスレッドを作り、タスクを均等に割り振ります。
タスク数が多く、各タスクにかかる時間がそれほど分散しない場合に適しています。
他のマルチスレッドmapperよりもオーバヘッドが少ないです。
@c COMMON
@item Pool mapper
@c EN
Uses thread pool to process the tasks.  It is suitable when the number
of tasks are large and/or the execution time of each task varies
a lot.  You can also reuse the pooled threads, so that you can
reduce the overhead of thread creation.
@c JP
スレッドプールを使ってタスクを処理します。タスク数が多いか、
各タスクの実行にかかる時間の分散が大きい場合に適しています。
また、スレッドプールを再利用することもでき、スレッド作成のオーバヘッドを削減できます。
@c COMMON
@item Fully concurrent mapper
@c EN
Creates one thread per each task.  It is suitable when the task
involves blocking I/O calls, and the number of tasks are not so large.
@c JP
タスクの数だけスレッドを作成して実行します。タスク数がそれほど多くなく、
タスクの中でブロッキングI/Oをする場合に適しています。
@c COMMON
@item Sequential mapper
@c EN
This runs tasks sequentially in a calling thread.  No concurrency involved.
It serves two purposes: (1) On a single-core system, this is the least
overhead strategy, and (2) You can test the algorithmic correctness
without complication of concurrency.   On single-core systems,
this mapper is the default value of @code{default-mapper}.
@c JP
これは呼び出したスレッド内でタスクを逐次的に実行します。並行実行は行われません。
これには2つの目的があります。(1)シングルコアのシステムでは、
これが最もオーバヘッドの少ない戦略です。(2)並行性による複雑さを除外してアルゴリズムの
動作を確かめるのに使えます。
シングルコアシステムでは、これが@code{default-mapper}の初期値です。
@c COMMON
@end table

@deffn {Parameter} default-mapper
@c MOD control.pmap
@c EN
A parameter keeping a mapper to be used by @code{pmap} etc. when no
mapper is specified.
@c JP
@code{pmap}等が使うmapperの省略時の値を保持するパラメータです。
@c COMMON

@c EN
The default is a static mapper (with the number of threads same as
the number of available cores) if Gauche is running system with
more than one core, or a sequential mapper otherwise.
@c JP
Gaucheが複数コアのシステム上で走っている場合はコア数と同じスレッドを使う
static mapperが、そうでなければsequential mapperが初期値となります。
@c COMMON

@c EN
The mapper set to this parameter is reused, or even is used
simultaneously from multiple @code{pmap} calls.
Pool mappers with external pool keeps a given thread pool in it,
so you should be careful to use such mapper as the default mapper.
@c JP
このパラメータにセットされたmapperは再利用されたり、複数の@code{pmap}呼び出しから
同時に使われたりする可能性があります。
外部スレッドプールを使うpool mapperはスレッドプールを共有するので、
それをデフォルトのmapperに設定する時は注意してください。
@c COMMON
@end deffn

@defun sequential-mapper
@c MOD control.pmap
@c EN
Returns a sigleton instance of the sequential mapper.
@c JP
sequential mapperのシングルトンインスタンスを返します。
@c COMMON
@end defun

@defun make-static-mapper :optional num-threads
@c MOD control.pmap
@c EN
Returns a new instance of a static mapper, which spawns @var{num-threads}
threads on execution, each of which handles evenly divided tasks.
This mapper is suitable if you have large number of small tasks with
even load.

If @var{num-threads} is omitted, the number of available
processors returned by @code{sys-available-processors}
is used (@pxref{Environment inquiry}).
@c JP
static mapperの新しいインスタンスを作って返します。
このmapperは@code{pmap}の実行のたびに@var{num-threads}のスレッドを作成し、
必要な仕事を均等に割り振ります。小さく均等なタスクを大量にこなす場合に便利です。

@var{num-threads}が省略された場合は、@code{sys-available-processors}
が返すプロセッサ数を使います
(@ref{Environment inquiry}参照)。
@c COMMON
@end defun

@defun make-pool-mapper :optional external-pool
@c MOD control.pmap
@c EN
Returns a new instance of a pool mapper, which uses a thread pool
(@pxref{Thread pools}) to run the tasks.  It is suitable when the load
of tasks varies a lot.
@c JP
スレッドプールを使うpool mapperの新たなインスタンスを作って返します。
タスクごとに計算負荷が大きく変動する場合に適しています。
@c COMMON

@c EN
If @var{external-pool} is not given, the mapper creats a thread
pool, and shut it down, every time high-level mapping operation is called.
This usage is local; that is, the thread pool is contained within
one call of @code{pmap} etc., and won't be shared.
@c JP
@var{external-pool}が指定されなければ、mapperは高レベルのマッピング操作が呼ばれる
度に新たなスレッドプールを作り、マッピング操作が終わったらプールをシャットダウンします。
この場合、ひとつのスレッドプールは一回の@code{pmap}などの呼び出しだけに使われ、
他と共有されることはありません。
@c COMMON

@c EN
Alternatively, you can pass an existing thread pool to @var{external-pool}
to be used.  The pool will be reused every time you use this mapper instance.
Using an external pool will eliminate overhead of thread pool creation and
shutting down every time you run @code{pmap}; however, you have to be
aware of those caveats:
@c JP
あるいは、既にあるスレッドプールを@var{external-pool}引数に渡すこともできます。
その場合、このmapperインスタンスが使われる場面全てで、そのスレッドプールは再利用されます。
外部スレッドプールを使うことで、@code{pmap}を呼ぶ度にスレッドプールを作ったり
シャットダウンしたりするオーバヘッドを避けることができます。
しかし、次の点に注意しなければなりません。
@c COMMON
@itemize @bullet
@item
@c EN
It's your responsibility to shut down the thread pool after you're done
with the mapper.
@c JP
mapperをもう使わなくなってからスレッドプールをシャットダウンするのは、
ユーザの責任です。
@c COMMON
@item
@c EN
The mapper keeps the given thread pool and reuses it every time
it is passed to @code{pmap} etc., so you have to make sure that
one mapper is not used simultaneously in more than one @code{pmap} etc..
Be careful using this type of pool mapper as the default mapper.
@c JP
mapperは渡されたスレッドプールを@code{pmap}の呼び出しに使いまわすので、
ひとつのpool mapperが複数の@code{pmap}呼び出しで同時に使われることがないように
管理してやる必要があります。特に、デフォルトのmappersとして外部スレッドプールを
使うpool mapperを設定するのは危険です。
@c COMMON
@end itemize
@end defun

@defun make-fully-concurrent-mapper :optional timeout timeout-val
@c MOD control.pmap
@c EN
Returns a new instance of a fully-concurrent mapper, which spawns
as many threads as the elements in the given collection to perform
the operation concurrently.  It is suitable when you don't have
many tasks, but each task may perform blocking I/O calls.
The overhead of creating threads are relatively large, but
you may be able to utilize CPU more while most of the threads are
waiting I/O.
@c JP
タスクの数だけスレッドを作成し、全てを並行に評価する完全並行mapperを作って返します。
タスクの数が比較的少数で、各タスクがI/Oなどでブロックする場合に適しています。
スレッドを作成するオーバヘッドが比較的大きいですが、スレッドがI/O待ちの間に
CPUを有効活用できます。
@c COMMON

@c EN
The optional @var{timeout} argument can specify
the timeout value for threads to run.  As in @code{thread-join!},
it can be either a @code{<time>} object to specify an absolute
point of time, a real number for the number of seconds from
the current time, or @code{#f} to run it indefinitely.
The default is @code{#f}.

If timeout reaches, @var{timeout-val} is used in place of
the result of @var{proc}, which is defaulted to @code{#f}.
@c JP
省略可能な@var{timeout}引数で、スレッドにタイムアウトを指定できます。
@code{thread-join!}のtimeout引数と同様に、@code{<time>}オブジェクトによる
絶対時刻、実数による現在時刻からの相対秒、そしてタイムアウトを設けない@code{#f}が
指定できます。省略時はタイムアウトしません。

タイムアウトした場合、@var{timeout-val}が@var{proc}の結果の代わりに使われます。
@var{timeout-val}の省略時値は@code{#f}です。
@c COMMON

@c EN
NB: If @var{timeout} reaches, the running threads are terminated by
@code{thread-terminate!}.  If the thread is locking a mutex
when it occurs, the mutex becomes `abandoned' state.  The resources
being used then may not be properly cleaned up.  If you need
to ensure proper cleanup in bounded time, you need to code it in @var{proc}
explicitly.
@c JP
註: スレッドがタイムアウトした場合、
走行中のスレッドは@code{thread-terminate!}で終了させられます。
この時スレッドがmutexをロックしていればそれはabandoned状態になりますし、
リソースを掴んでいたら適切なクリーンアップがなされないかもしれません。
スレッドの実行を制限時間内に納め、かつクリーンアップを確実にしたい場合は、
そういうロジックを明示的に@var{proc}に組み込んでください。
@c COMMON
@end defun

@c ----------------------------------------------------------------------
@node Scheduler, Thread pools, Parallel map, Library modules - Utilities
@section @code{control.scheduler} - Scheduler
@c NODE スケジューラ, @code{control.scheduler} - スケジューラ

@deftp {Module} control.scheduler
@mdindex control.scheduler
@c EN
A scheduler is a device to run tasks in scheduled time.
@c JP
スケジューラは、予定された時刻にタスクを走らせるデバイスです。
@c COMMON

@c EN
Each scheduler manages one or more tasks.  Each task has attached
time to run.  A task can be run once, or can be run periodically.
@c JP
各スケジューラは一つ以上のタスクを管理します。各タスクには、それがいつ走るかを
指定する時刻が付随します。タスクは一回だけ走らせることも、
定期的に走らせることもできます。
@c COMMON

@c EN
For portable code, you can use SRFI-120 (@pxref{Timer APIs}),
which is written on top of this module.
@c JP
ポータブルなコードでは、このモジュールの上に構築された
SRFI-120を使うこともできます(@ref{Timer APIs}参照)。
@c COMMON
@end deftp

@deftp {Class} <scheduler>
@clindex scheduler
@c MOD control.scheduler
@c EN
A device to run tasks in scheduled time.  Each instance of this class
have its own thread, and maintains a list of tasks along the information
when each task should be run.  Tasks can be registered by
@code{scheduler-schedule!}.
@c JP
タスクを予定された時刻に走らせるデバイスです。
各スケジューラインスタンスは独自のスレッドを持ち、
タスクとそれをいつ走らせるかのリストを管理しています。
タスクは@code{scheduler-schedule!}で登録できます。
@c COMMON

@c EN
If a task throws an error, a procedure bound to @code{error-handler}
slot is invoked with the thrown condition as the only argument.
If no @code{error-handler} is registered, or @code{error-handler}
throws an error again, then the scheduler stops.  The thrown condition
is kept in the scheduler and can be retrieved with
@code{scheduler-terminate!}.
@c JP
タスクがエラーを投げた場合、@code{error-handler}スロットに格納された手続きが、
コンディションオブジェクトを引数として呼ばれます。
@code{error-handler}が設定されていない場合、あるいは@code{error-handler}が
エラーを投げた場合はスケジューラが停止します。
投げられたコンディションはスケジューラの中に保存され、
@code{scheduler-terminate!}で取り出せます。
@c COMMON

@defivar {<scheduler>} error-handler
@c EN
This slot can be initialized with @code{:error-handler} keyword argument.
It must be either @code{#f} or a procedure that takes one argument.
If it is a procedure, it is invoked when a task throws an error,
and the argument is the raised condition.
The result of @code{error-handler} procedure is discarded.
@c JP
このスロットは@code{:error-handler}キーワード引数で初期化できます。
値は@code{#f}もしくは引数をひとつ取る手続きでなければなりません。
手続きの場合、それはタスクがエラーを投げた時に、
投げられたコンディションオブジェクトを引数として呼び出されます。
手続きの戻り値は捨てられます。
@c COMMON
@end defivar
@end deftp

@defun scheduler-running? scheduler
@c MOD control.scheduler
@c EN
Returns @code{#t} iff @var{scheduler} is running.
@c JP
@var{scheduler}が動作中なら@code{#t}を、そうでなければ@code{#f}を返します。
@c COMMON
@end defun


@defun scheduler-schedule! scheduler thunk when :optional interval
@c MOD control.scheduler
@c EN
Inserts a new tasks that runs @var{thunk} into @var{scheduler}.
The task can be run once, or periodically.
@c JP
@var{thunk}を走らせる新たなタスクを@var{scheduler}に加えます。
タスクは一回だけ走らせることも、定期的に走らせることもできます。
@c COMMON

@c EN
The @var{when} argument specifies when the task should first run.
It can be either one of the followings:
@c JP
@var{when}引数が、最初にタスクを走らせるタイミングを指定します。
次のいずれかの値が使えます。
@c COMMON

@table @asis
@c EN
@item @code{<time>} object of @code{type-utc} or @code{time-tai} type
Specifies the aboslute point of time.
@c JP
@item @code{type-utc}か@code{time-tai}型の@code{<time>}オブジェクト
絶対的な時刻を指定します。
@c COMMON
@c EN
@item @code{<time>} object of @code{time-duration} type
Specifies the relative time since this procedure is called.
@c JP
@item @code{time-duration}型の@code{<time>}オブジェクト
この手続きを呼んだ時点からの相対的な時刻を指定します。
@c COMMON
@c EN
@item real number
Specifies the relative time in seconds since this procedure is called.
@c JP
@item 実数
この手続きを呼んだ時点からの秒数を指定します。
@c COMMON
@end table

@c EN
The optional @var{interval} argument can be @code{#f}, real number
or @code{<time>} object of @code{time-duration} type.  If it is @code{#f}
or 0, the task is one-shot, that is, not repeated.  Otherwise,
the task is repeated with the specified interval---the real number
specifies the number of seconds.
@c JP
省略可能な@var{interval}引数は、@code{#f}、実数、もしくは@code{time-duration}型の
@code{<time>}オブジェクトです。@code{#f}または@code{0}の場合、
タスクは一回だけ実行され、繰りかえされません。
そうでなければ、タスクは指定の時間間隔で繰り返し実行されます。
実数の場合の単位は秒です。
@c COMMON

@c EN
Returns an integer that identifies the task.  The task id can
be used to cancel or reschedule the task.
@c JP
手続きは、タスクを指定する整数を返します。この値は後でタスクをリスケジュールしたり
キャンセルするのに使えます。
@c COMMON
@end defun


@defun scheduler-reschedule! scheduler task-id when :optional interval
@c MOD control.scheduler
@c EN
Change the schedule of the task specified by @var{task-id} in the
scheduler.  The meaning of @var{when} and @var{interval} argument is
the same as @code{scheduler-schedule!}.
@c JP
@var{task-id}で指定されるタスクのスケジュールを変更します。
@var{when}および@var{interval}の意味は@code{scheduler-schedule!}と同じです。
@c COMMON

@c EN
The same types of values as @code{scheduler-schedule!} are allowed for
@var{when} and @var{interval} arguments, as well as a symbol
@code{unchanged}, which indicates that value is left alone by
the operation.  Note that omitting @var{interval} means task will be
non-repeating.  If you want to change just the next time the repeating
task is executed, pass @code{unchanged} to the @var{interval}.
@c JP
@var{when}と@var{interval}引数は、@code{scheduler-schedule!}と同じものの他、
シンボル@code{unchanged}も許されます。@code{unchanged}が渡された場合は
その引数に関して以前の設定が引き継がれます。@var{interval}を省略することは
タスクを繰り返さないという指定になることに注意してください。
次にタスクが実行される時刻を変更したいが、繰り返しの周期はそのままにしておきたい、
という場合は@var{interval}に@code{unchanged}を渡してください。
@c COMMON

@c EN
If the scheduler doesn't have a task with @var{task-id}, an exception
is raised.
@c JP
@var{task-id}に該当するタスクがなければエラーが投げられます。
@c COMMON
@end defun


@defun scheduler-remove! scheduler task-id
@c MOD control.scheduler
@c EN
Remove the task specified by @var{task-id} from the scheduler.
If the task is actually removed, @code{#t} is returned.
If the scheduler doesn't have a task with @var{task-id}, @code{#f} is returned.
@c JP
@var{task-id}で指定されるタスクをスケジューラから取り除きます。
実際にタスクが取り除かれたら@code{#t}を、
該当するタスクが無かった場合は@code{#f}を返します。
@c COMMON
@end defun


@defun scheduler-exists? scheduler task-id
@c MOD control.scheduler
@c EN
Returns @code{#t} iff the scheduler has the task with @var{task-id}
in the queue.  Note that once the task is executed and not repeating,
the task is removed from the queue.
@c JP
スケジューラが@var{task-id}で指定されるタスクを持っていれば@code{#t}を、
そうでなければ@code{#f}を返します。
繰り返さないタスクは一度実行されたらスケジューラから取り除かれることに注意してください。
@c COMMON
@end defun

@defun scheduler-terminate! scheduler :key on-error
@c MOD control.scheduler
@c EN
Stop the scheduler.  Tasks still in the scheduler's queue won't executed,
and no new task will be accepted.   Once the scheduler is terminated,
it can't be restarted.
@c JP
スケジューラを停止します。スケジューラのキューに残っているタスクはもう実行されず、
また新しいタスクを追加することもできなくなります。
一度停止したスケジューラを再起動することはできません。
@c COMMON

@c EN
If no task has raised an exception, or all exceptions are handled
by the error-handler of the scheduler, this procedure returns @code{#t}
after the scheduler is stopped.
@c JP
タスクがこれまで例外をあげたことがないか、スケジューラの@code{error-handler}で
例外が全て処理済みであった場合、この手続きはスケジューラが停止した後で
@code{#t}を返します。
@c COMMON

@c EN
If any task has raised an exception and not handled by
the error-handler, the behavior depends on the @var{on-error}
keyword argumnent, which should be one of the following:
@c JP
タスクが例外を上げていてスケジューラの@code{error-handler}で処理されて
いなかった場合、この手続きの振る舞いは@var{on-error}引数で決まります。
可能な値は次のいずれかです。
@c COMMON

@table @code
@item :reraise
@c EN
The exception is reraised from @code{scheduler-terminate!}.
This is the default.
@c JP
処理されなかった例外が、@code{scheduler-terminate!}から改めて投げられます。
これがデフォルトの振る舞いです。
@c COMMON
@item :return
@c EN
The exception is returned from @code{scheduler-terminate!}.
@c JP
処理されなかった例外が@code{scheduler-terminate!}の戻り値として返されます。
@c COMMON
@end table
@end defun

@c ----------------------------------------------------------------------
@node Thread pools, Password hashing, Scheduler, 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.
@c JP
スレッドプールを提供します。
@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}.

While this procedure is called, no new jobs should be put into @var{pool}.
@c JP
ジョブ待ち行列が空になり、すべての実行中のジョブも終了するまで待ちます。
終了待ちは@var{check-interval}にナノ秒で指定される間隔でスレッドプールを
ポールすることで行われます。すべてのジョブが終了したら@code{#t}を返します。

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

この手続きが呼ばれている間、新しいジョブが@var{pool}に投入されてはなりません。
@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 the 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 evicted 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 the 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.  It needs to implement the dictionary
protocol (@pxref{Dictionary framework}).
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 the hash function.
@c JP
ストレージは、キーとキャッシュ内部の構造とをマッピングする辞書です。
ディクショナリプロトコルを実装しているクラスのオブジェクトでなければなりません
(@ref{Dictionary framework}参照)。
デフォルトでは与えられた比較器を使うハッシュテーブルが使われるので、
比較器はハッシュ関数を持っていなければなりません。
比較器が省略された場合は@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
(e.g. access timestamp), 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.
The insertion may cause eviction of exising entries.
@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
@c EN
The @code{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.
@c JP
@code{initialize}メソッドは最初に@code{next-method}を呼ばなければなりません。
それによって@code{comparator}と@code{storage}スロットが適切に初期化されます。
また、@code{storage}スロットに既にデータが入っているかどうかを調べ、
そうであれば他の内部構造をそれに合わせて初期化する必要があります。
@c COMMON
@item
@c EN
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.
@c JP
@code{cache-evict!}と@code{cache-clear!}のデフォルトメソッドはキャッシュの
@code{storage}だけを更新します。サブクラスが他の内部状態を持っている場合は、
それらの一貫性を保つようなメソッドを定義する必要があります。
@c COMMON
@item
@c EN
The default method of @code{cache-write!} is just @code{cache-evict!}
followed by @code{cache-register!}.  You may provide an alternative method
if you can do it more efficiently, which is often the case.
@c JP
@code{cache-write!}のデフォルトメソッドは、@code{cache-evict!}を呼んでから
@code{cache-register!}を呼ぶだけです。
より効率の良い実装があれば(あることが多いでしょう)、
このメソッドをオーバライドするのが良いでしょう。
@c COMMON
@end itemize

@c EN
There are several procedures that help implementing cache subclasses:
@c JP
キャッシュのサブクラスを実装するのに便利な手続きがいくつか用意してあります:
@c COMMON

@defun cache-comparator cache
@defunx cache-storage cache
@c MOD data.cache
@c EN
Returns the comparator and the storage of the cache, respectively.
@c JP
キャッシュの@code{comparator}と@code{storage}を返します。
@c COMMON
@end defun

@c EN
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:
@c JP
典型的なキャッシュは、storageとしての辞書と、キューで作られます。
ここでstorageは、キーを@code{(<n> . <value>)}にマップし、
キューは@code{(<key> . <n>)}を保持します。
ただし@code{<n>}はタイムスタンプやカウンタなど何からの数値です。
キャッシュがこの「キューと辞書」を使って実装されている場合は、
以下の共通手続きが使えるでしょう:
@c COMMON

@defun cache-populate-queue! queue storage
@c MOD data.cache
@c EN
You can call this in the @code{initialize} method to set up the
queue.  This procedure walks @var{storage} (a dictionary that maps
keys to @code{(<n> . <value>)}) to construct @code{(<key> . <n>)}
pairs, sorts it in increasing order of @code{<n>}, and pushes them
into the @var{queue}.
@c JP
@code{initialize}メソッドの中でこの手続きを呼ぶことにより、
キューを初期化できます。この手続きは、キーを@code{(<n> . <value>)}にマップする辞書である
@var{storage}を走査し、@code{(<key> . <n>)}というペアを作り、
@code{<n>}の昇順にソートしてそれを@var{queue}にプッシュします。
@c COMMON
@end defun

@defun cache-compact-queue! queue storage
@c MOD data.cache
@c EN
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, and you push the read timestamp to the queue
for every read).  This procedure 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.
@c JP
キューに、同じキーを持つエントリが複数含まれることがあります。
しばしば、そういった重複エントリが多くなりすぎる場合があります
(例えばキーが読み出される度にタイムスタンプをキューにプッシュしていて、
同じキーが何度も読まれた場合)。この手続きはキューを走査し、
キーが重複しているエントリは最新のもの以外を取り除きます。
この操作の後では、キューの長さとstorageのエントリ数は一致しているはずです。
@c COMMON
@end defun

@defun cache-renumber-entries! queue storage
@c MOD data.cache
@c EN
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!}.
@c JP
この手続きはキュー内の@code{<n>}を、順序を変えることなく、0から昇順に付け直し、
@code{<n>}の最大値を返します。キーが重複するエントリは@code{cache-compact-queue!}と
同様に、最新のもの以外取り除かれます。
@c COMMON

@c EN
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 a reasonable range.
@c JP
@code{<n>}に単調増加する数を使っていて、長い時間の後では@code{<n>}がbignum
になって効率が落ちる心配があれば、この手続きを適宜呼ぶことで@code{<n>}を適切な
範囲内に収めることができるでしょう。
@c COMMON
@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 pred heap :optional failure
@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},
the thunk @var{failure} is called, whose default is @code{(^[] #f)}.
This is O(n) operation.
@c JP
ヒープの中で、述語@var{pred}を満たす要素を返します。@var{pred}を満たす要素が
複数ある場合にどれが返るかは不定です。@var{pred}を満たす要素が無ければ
サンク@var{failure}が呼ばれます。@var{failure}のデフォルトは
@code{(^[] #f)}です、O(n)の操作です。
@c COMMON

@c EN
Note: The argument order used to be @code{(binary-heap-find heap pred)}
until 0.9.10.  We changed it to align other *-find procedures.
The old argument order still work for the backward compatibility,
but the new code should use the current order.
@c JP
註: 0.9.10まで、引数の順序は@code{(binary-heap-find heap pred)}でしたが、
他の *-find 系インタフェースと合わせるために変更されました。
互換性のため、古いインタフェースで呼び出しても動作するようになっていますが、
新たに書くコードは新しいインタフェースを使ってください。
@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
@c EN
This module provides a functional double-ended queue (deque,
pronounced as ``deck'').
@c JP
このモジュールは、両端キュー (deque、「デック」と読みます) の機能を提供します。
@c COMMON

@c EN
Almost all procedures in this module are now a part of R7RS large.
@xref{R7RS immutable deques}, for description of the following
@c JP
このモジュールのほぼ全ての手続きは、R7RS-largeに取り込まれました。
以下の手続きについては@ref{R7RS immutable deques}を参照してください。
@c COMMON
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
@c EN
Creates an ideque of length @var{n} with all the elements being
@var{init}.  If @var{init} is omitted, @code{#f} is used.
@c JP
@var{n}個の@var{init}で初期化されたidequeを作って返します。
@var{init}が省略された場合は@code{#f}が使われます。
@c COMMON

@c EN
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}.
@c JP
この手続きは、他のデータ構造との対称性のためだけに提供されていて、
SRFI-134には含まれていません。ポータブルなコードは
@code{ideque-tabulate}を使って同じようなことができます。
@c COMMON
@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
@c EN
Creates and returns an immutable map containing
key-value associations given by an assoc-list @var{alist}.
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.
@c JP
連想リスト@var{alist}で指定されるキーと値の組み合わせを持つ変更不可なマップを新たに作って返します。
これは@code{make-imap}で空のimapを作ってから@code{imap-put}で一要素づつ値を追加するよりも効率的です。
@c COMMON

@c EN
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.
@c JP
@var{comparator}引数はキーの比較に使うので比較手続きを持っていなければなりません。
省略された場合は@code{default-comparator}が使われます。
比較器について詳しくは@ref{Basic comparators}を参照してください。
@c COMMON

@c EN
The third form creates a key comparator from a equality
predicate @var{key=?} and less-than predicate @code{key<?},
both must accept two keys.
@c JP
三つ目の形式は、等価判定述語@var{key=?}と比較述語@var{key<?}の組み合わせで
キーの比較方法を指定するものです。どちらの述語も二つのキーを取ります。
@c COMMON

@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
@c EN
Returns a new immutable map with the same content (and the same comparator)
as @var{tree-map}.
@c JP
@var{tree-map}と同じ内容、同じ比較器を持つ変更不可なマップを返します。
@c COMMON
@end defun

@defun imap? obj
@c MOD data.imap
@c EN
Returns @code{#t} if @var{obj} is an immutable map,
@code{#f} otherwise.
@c JP
@var{obj}が変更不可なマップなら@code{#t}を、そうでなければ@code{#f}を返します。
@c COMMON
@end defun

@defun imap-empty? immap
@c MOD data.imap
@c EN
Returns @code{#t} if an immutable map @var{immap} is empty,
@code{#f} otherwise.
@c JP
変更不可なマップ@var{immap}が空なら@code{#t}を、そうでなければ@code{#f}を返します。
@c COMMON
@end defun

@defun imap-exists? immap key
@c MOD data.imap
@c EN
Returns @code{#t} if @var{key} exists in an immutable map @var{immap}.
@c JP
変更不可なマップ@var{immap}がキー@var{key}を持っていれば@code{#t}を、
そうでなければ@code{#f}を返します。
@c COMMON
@end defun

@defun imap-get immap key :optional default
@c MOD data.imap
@c EN
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.
@c JP
変更不可なマップ@var{immap}中のキー@var{key}に対応する値を返します。
@var{immap}が@var{key}を持っていない場合、@var{default}引数が与えられていれば
その値を返し、なければエラーが投げられます。
@c COMMON
@end defun

@defun imap-put immap key val
@c MOD data.imap
@c EN
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).
@c JP
変更不可なマップ@var{immap}に、キー@var{key}と値@var{val}の対応を付け加えた
(あるいは、既に対応があった場合は置き換えた)新たな変更不可なマップを作って返します。
この操作はO(log n)です。
@c COMMON

@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
@c EN
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}.
@c JP
変更不可なマップ@var{immap}から、キー@var{key}に対応するエントリを
取り除いた新たな変更不可なマップを作って返します。
@var{immap}に@var{key}が含まれていなかった場合、返されるマップは
元のマップと同じ内容を持ちます。
@c COMMON

@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
@c EN
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.
@c JP
変更不可なマップ@var{immap}中で、最小または最大のキーと、それに対応する値を
ペアにして返します。@var{immap}が空の場合は@code{#f}を返します。
@c COMMON
@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
@c EN
Priority map is a dictionary that can map keys to values, while
the entries are sorted by their @emph{values}.
(If the entries are sorted by keys, it's a treemap--@pxref{Treemaps}).
@c JP
プライオリティマップは、キーを値にマッピングする辞書で、
エントリが値によってソートされているものです
(エントリがキーでソートされているのはツリーマップです。@ref{Treemaps}参照)。
@c COMMON

@c EN
It is useful when you wanted a sorted sequence, with quick access by
keys that are associated to each value.
@c JP
ソートされたシーケンスだけれど、
キーによって特定の値に素早くアクセスする必要もある、という場合に便利です。
@c COMMON

@c EN
Note: If what you need is just a priority queue, you can use
@code{data.heap} (@pxref{Heap}).
@c JP
註: 必要なものがプライオリティキューなら、
@code{data.heap}が使えます (@ref{Heap}参照)。
@c COMMON
@end deftp

@deftp {Class} <priority-map>
@cindex priority-map
@c MOD data.priority-map
@c EN
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.
@c JP
プライオリティマップのクラスです。公開スロットはありません。
プライオリティマップのインスタンスは、@code{make}メソッドではなく
@code{make-priority-map}で作る必要があります。
@c COMMON

@c EN
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}).
@c JP
@code{<ordered-dictionary>}を継承し、ディクショナリプロトコルを実装しています。
キーから値へのマッピングに関わる操作は、ディクショナリのジェネリック関数を
使ってください(@ref{Generic functions for dictionaries}参照)。
@c COMMON

@c EN
When iterated, it iterates increasing order of values.
@c JP
イテレートする場合は、値の増加順になります。
@c COMMON
@end deftp

@defun make-priority-map :key key-comparator value-comparator
@c MOD data.priority-map
@c EN
Creates and returns an empty priority map.
It can take @var{key-comparator}, which is used to compare keys,
and @var{value-comparator}, which must have ordering predicate
and is used to order values.
When omitted, @code{default-comparator} is assumed.
@c JP
空のプライオリティマップを作って返します。
@var{key-comparator}はキーの比較に使われる比較器であり、
また@var{value-comparator}は値の順序づけに使われる
順序手続きを持った比較器でなければなりません。
省略された場合はどちらも@code{default-comparator}が使われます。
@c COMMON

@c EN
If you apply @code{dict-comparator} on a priority map,
its @var{key-comparator} is returned.
@c JP
プライオリティマップに@code{dict-comparator}を適用すると、
@var{key-comparator}が返されます。
@c COMMON
@end defun

@defun dict->priority-map dict :optional value-comparator
@c MOD data.priority-map
@c EN
Creates and returns a priority map that contains the same key-value entries
as given dictionary @var{dict}.
The priority map's key comparator is the same as the key comparator
of @var{dict}, and its value comparator is @var{value-comparator},
defaulted to @code{default-comparator}.
@c JP
ディクショナリ@var{dict}と同じキー-値のエントリを持つプライオリティマップを作って
返します。作られるマップのキー比較器は@var{dict}のキー比較器と同一で、
値比較器は@var{value-comparator}です。後者が省略された場合は
@code{default-comparator}が使われます。
@c COMMON
@end defun

@defun alist->priority-map alist :optional key-comparator value-comparator
@c MOD data.priority-map
@c EN
Creates and returns a priority map that contains the key-value pairs
in an assoc list @var{alist}.
The optional @var{key-comparator} and @var{value-comparator}
are used to build a priority map.  When omitted, @code{default-comparator}
is used.
@c JP
連想リスト@var{alist}に含まれるキー-値ペアを内容とするプライオリティマップを作って
返します。省略可能引数@var{key-comparator}と@var{value-comparator}が
プライオリティマップの構築に使われます。省略された場合は@code{default-comparator}
となります。
@c COMMON
@end defun

@defun priority-map-min pmap
@defunx priority-map-max pmap
@c MOD data.priority-map
@c EN
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.
@c JP
プライオリティマップ@var{pmap}中の、それぞれ最小の値および最大の値を持つエントリの
キーと値をペアにして返します。

@var{pmap}が空の場合は@code{#f}を返します。

@var{pmap}中に、@var{value-comparator}で比較して同じになる値を持つエントリが
複数ある場合は、そのうちのどれか一つが返されます。
@c COMMON
@end defun

@defun priority-map-min-all pmap
@defunx priority-map-max-all pmap
@c MOD data.priority-map
@c EN
Return a pair of a list of keys and a value, where the value is smallest or
largest in the priority map @var{pmap}, respectively.  The keys includes
all the entries that has the same value.  The caller shouldn't modify
the returned key list.
@c JP
プライオリティマップ@var{pmap}中の、それぞれ最小の値および最大の値を持つエントリを
全て選び、そのキーのリスト、および値そのものをペアにして返します。
そのリストにあるキーは全て同じ値を持つということです。
返されるキーのリストは変更してはなりません。
@c COMMON

@c EN
If @var{pmap} is empty, @code{#f} is returned.
@c JP
@var{pmap}が空の場合は@code{#f}を返します。
@c COMMON
@end defun

@defun priority-map-pop-min! pmap
@defunx priority-map-pop-max! pmap
@c MOD data.priority-map
@c EN
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.
@c JP
それぞれ、最小および最大の値を持つエントリをひとつ@var{pmap}から取り除き、
そのエントリのキーと値をペアにして返します。

@var{pmap}が空の場合は@code{#f}を返します。

@var{pmap}中に、@var{value-comparator}で比較して同じになる値を持つエントリが
複数ある場合は、そのうちのどれか一つが選ばれます。
@c COMMON
@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

@menu
* Queue classes and constructors::
* Queue predicates::
* Queue basic operations::
* Queue other accessors::
* Queue as channel::
@end menu

@node Queue classes and constructors, Queue predicates, Queue, Queue
@subsection Queue classes and constructors
@c NODE キューのクラスとコンストラクタ

@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

@defivar {<mtqueue>} closed
@c EN
A boolean flag, set to @code{#f} initially.
If this is true, the queue no longer accepts a new
data by @code{enqueue!} etc.  This slot is read-only and can only
be changed atomically by @code{enqueue/wait!}, @code{queue-push/wait!},
@code{dequeue/wait!} and @code{queue-pop/wait!}.
This is useful when an mtqueue used as a channel is being shutdown.
@c JP
論理値のフラグ。初期値は@code{#f}です。
これが真になると、@code{enqueue!}などによる新たなデータの挿入ができなくなります。
このスロットは読み出し専用で、@code{enqueue/wait!}、@code{queue-push/wait!}、
@code{dequeue/wait!}、@code{queue-pop/wait!}によってアトミックにセットすることが
できます。
これは、mtqueueをチャネルとして使っていて、シャットダウンする場合に有用です。
@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 copy-queue queue
@c MOD data.queue
@c EN
Returns a copy of the queue.  If @var{queue} is an mtqueue,
a fresh mtqueue with the same content and max length is returned.
@c JP
キュー@var{queue}のコピーを返します。@var{queue}がmtqueueなら、
同じ内容と最大長を持つ新たなmtqueueが返されます。
@c COMMON
@end defun

@node Queue predicates, Queue basic operations, Queue classes and constructors, Queue
@subsection Queue predicates
@c NODE キューに関する述語

@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

@node Queue basic operations, Queue other accessors, Queue predicates, Queue
@subsection Basic queue operations
@c NODE 基本的なキュー操作

@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!}.  @xref{Queue as channel}, for the details.)
@c JP
@var{queue}がmtqueueの場合、渡されたオブジェクト全ての追加は
アトミックに行われます。すなわち、途中に別スレッドが要素を挿入する
ことはありません。さらに、@code{max-length}スロットが正の有限値を
持っており、この@code{enqueue!}の実行によってキューの要素数が
@code{max-length}を越えることになる場合は、@var{queue}は
変更されずエラーとなります。
(@code{max-length}がゼロの場合、この手続きは常にエラーとなります。
@code{enqueue/wait!}を使ってください。@ref{Queue as channel}参照。)
@c COMMON

@c EN
If @var{queue} is an mtqueue and it is closed, no change is made
to it and an error is thrown.
@c JP
@var{queue}がmtqueueで既にクローズされていた場合は、キューは変更されず
エラーが投げられます。
@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{closed}の値も
チェックされます。詳しくは上の@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{closed}の値も
チェックされます。詳しくは上の@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} (@pxref{Queue other accessors}).
@c JP
キューの全ての内容をリストにして返します。キューそのものは空になります。
キューが既に空の場合は空リストが返されます。
@code{queue->list}も参照してください(@ref{Queue other accessors})。
@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


@node Queue other accessors, Queue as channel, Queue basic operations, Queue
@subsection Other queue accessors
@c NODE その他のキューのアクセサ

@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 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 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

@node Queue as channel,  , Queue other accessors, Queue
@subsection Queue as channel
@c NODE チャネルとしてのキュー

@c EN
Mtqueues can be used as a communication channel between threads
to implement producer-consumer pattern.  Using @code{enqueue/wait!},
the producer is suspended when the queue is full, until
the consumer reads the items to make room.  Using @code{dequeue/wait!},
the consumer is suspended when the queue is empty, until
the producer make items available.
@c JP
Mtqueueはスレッドを使った生産者-消費者パターンの並行動作に使えます。
生産者が@code{enqueue/wait!}でキューに要素を挿入しようとして
キューが一杯であった場合、消費者が要素を取り出すまで待ちます。
消費者が@code{dequeue/wait!}でキューから要素を取り出そうとして
キューが空であった場合、生産者が要素を挿入するまで待ちます。
@c COMMON

@c EN
You can specify timeouts for those procedures as well, in case
some threads got stuck.
@c JP
また、これらの手続きにはタイムアウトを設定することができ、
スレッドがスタックした場合に対応できます。
@c COMMON

@defun enqueue/wait! mtqueue obj :optional timeout timeout-val close
@defunx queue-push/wait! mtqueue obj :optional timeout timeout-val close
@c MOD data.queue
@c EN
Insert @var{obj} to @var{mtqueue}.  Like @code{enqueue!} and
@code{queue-push!}, @code{euqueue/wait!} inserts @var{obj} at the
end of the queue (so that it will be retrieved after existing
items are dequeued), while @var{queue-push/wait!} inserts @var{obj}
at the beginning of the queue (so that it will be retrieved
next call of dequeue).

If the queue is full, the caller is blocked.
The caller is unblocked when items are taken, or the timeout
reaches.

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{obj}を@var{mtqueue}に挿入します。
@code{enqueue!}/@code{queue-push!}と同様に、
@code{enqueue/wait!}は@var{obj}をキューの末尾に
(従って、既にある要素が全て取り除かれてから@var{obj}が取られます)、
@code{queue-push/wait!}は@var{obj}をキューの先頭に
(従って、@var{obj}は次のdequeueで取られます)、それぞれ挿入します。

キューが既に一杯である場合、呼び出しはブロックします。
キューから要素が取り出されて空きができるか、タイムアウトした場合に
これらの手続きは戻ります。

@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

@c EN
The last optinoal argument, @code{close}, closes the queue if it is given
and true.  The close operation is done atomically, and if you're calling
@code{enqueue/wait!} or @code{queue-push/wait!}, @var{obj} is guaranteed
to be the last item put in the queue.  It effectively ``shut down''
the channel.
@c JP
最後の省略可能引数@code{close}は、もし真の値が与えられれば、キューをクローズします。
クローズはアトミックに行われるので、
@code{enqueue/wait!}や@code{queue-push/wait!}を呼び出したのであれば、
@var{obj}が最後にキューに追加されるデータであることが保証されます。
これはチャネルの「シャットダウン」操作と考えることができます。
@c COMMON

@c EN
If @var{mtqueue} is already closed, an error is raised
 without modifying the queue.
The check and queue insertion is done atomically, to eliminate
the possibility that other thread tries to enqueue between the
check and insetion.
@c JP
もし@var{mtqueue}が既にクローズされていたらエラーが投げられます。
キューは変更されません。
フラグのチェックとキューへの挿入はアトミックに行われるので、
チェックと挿入の間に他のスレッドがenqueueしてしまうことはありません。
@c COMMON

@end defun

@defun dequeue/wait! mtqueue :optional timeout timeout-val close
@defunx queue-pop/wait! mtqueue :optional timeout timeout-val close
@c MOD data.queue
@c EN
Remove one item from the head of the queue and returns it.
Both procedures works exactly the same.  You can use @code{dequeue/wait!}
to pair with @code{enqueue/wait!}, and @code{queue-pop/wait!}
with @code{queue-push/wait!}, for clarity.

The caller thread would block if the queue is empty.
The blocked caller thread is unblocked either
when the blocking condition is resolved, or the timeout
condition is met.

See the @code{enqueue/wait!} entry above for the meaning of
@var{timeout}, @var{timeout-val}, and @var{close} arguments.
@c JP
キューの先頭から要素を取り出して返します。
どちらの手続きも全く同じ動作ですが、
@code{dequeue/wait!}は@code{enqueue/wait!}と対で、
@code{queue-pop/wait!}は@code{queue-push/wait!}と対で使うとわかりやすいでしょう。

呼び出しスレッドは、キューが空であった場合ブロックします。
キューに要素が追加されるか、タイムアウトが起きたら戻ってきます。

@var{timeout}、@var{timeout-val}、@var{close}引数については
上の@code{enqueue/wait!}を参照してください。
@c COMMON
@end defun

@defun mtqueue-close! mtqueue
@c MOD data.queue
@c EN
Closes the mtqueue without inserting or retrieving objects.
If the mtqueue is closed, it does nothing.
@c JP
mtqueueに要素を追加することなくキューをクローズします。
キューが既にクローズされていた場合は何もしません。
@c COMMON
@end defun


@c ----------------------------------------------------------------------
@node Random data generators, Range, 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

@c EN
A part of the functionality of this module is turned into
SRFI-194, but it gives different names/API for the consistency of other SRFIs
(@pxref{Random data generators (SRFI)}).
@c JP
このモジュールの一部の機能はSRFI-194になりましたが、
同SRFIでは他のSRFIとの一貫性から異なる名前/APIを採用しています
(@ref{Random data generators (SRFI)}参照)。
@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 Random source
@c JP
@subheading 乱数源
@c COMMON

@deffn {Parameter} random-data-random-source
@c MOD data.random
@c EN
Its value must be a SRFI-27 random source (@pxref{Sources of random bits}).
The initial value is SRFI-27's @code{default-random-source}.

When generators are created with the utilities of this module, it captures
the dynamic value of this parameter, from which the random values are
generated.  Changing the parameter value after generators are created
won't affect their behavior.
@c JP
このパラメータの値はSRFI-27の乱数発生源でなければなりません
(@ref{Sources of random bits}参照)。初期値はSRFI-27の
@code{default-random-source}です。

このモジュールのユーティリティでジェネレータを作った場合、その作成時の
パラメータの動的な値が捕獲され、ジェネレータはそれを使って乱数を生成します。
ジェネレータの作成後にこのパラメータの値を変えてもジェネレータの動作には影響しません。
@c COMMON
@end deffn

@c EN
Note: Up to 0.9.13, generators created with this module refers to the
dynamic value of the current random source every time it generates
a random value, so that prebuilt network of random values can be affected
by modifying the current random source.  However it incurs overhead for
each random number generation, and generally it is cheaper to reconstruct
a new generators with the different random source.
The current behavior is consistent with SRFI-194.

The following two procedures are to swap current random source.  They
are still supported but no longer effective.
@c JP
註: 0.9.13まで、このモジュールで作られるジェネレータは乱数生成の度に現在の乱数源を
参照していました。これにより、一度構築した乱数生成のネットワークのふるまいを、
現在の乱数源をいじることで変えられますが、乱数発生の度に若干のオーバヘッドも生じます。
一般に、異なる乱数源を使いたければそれを現在の乱数源として新にジェネレータを
作成した方が安価でしょう。それに、現在のふるまいはSRFI-194と一貫性があります。

以下のふたつの手続きは現在の乱数源を置き換えるために提供されていましたが、
今では効果がありません。
@c COMMON

@example
random-data-seed          with-random-data-seed
@end example


@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
Creates and returns uniform integer generators.
Each generates 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
Creates and returns a generator of
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 fixnums
@defunx int8s
@defunx uint8s
@defunx int16s
@defunx uint16s
@defunx int32s
@defunx uint32s
@defunx int64s
@defunx uint64s
@defunx booleans
@c MOD data.random
@c EN
These are preconstructed generators by @code{fixnum$} etc.  Provided
for the convenience, but note that the random source they use is
fixed to @code{default-random-source}.
@c JP
これらは@code{fixnum$}などを使ってあらかじめ作られたジェネレータです。
簡便のために提供されています。ただ、乱数発生源は@code{default-random-source}
に固定であることに注意してください。
@c COMMON
@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

@c EN
Note also that floating point numbers are not uniformly distributed
within the given real number range.  When you uniformly sample
from a certain real number range, the returned flonums would very likely
have the same or closer exponent of the bounds of the range.
If that's what you want, it's ok.  If you want a sample uniformly from
a valid flonum values, see @code{finite-flonums$} below.
@c JP
また、浮動小数点数は与えられた実数範囲の中で一様に分布していないことに注意してください。
ある実数範囲から一様にサンプリングした場合、得られるほとんどの実数の指数部は、
範囲の上下限の指数と同じかそれに近いものになります。それが必要なものでしたら良いのですが、
有効な浮動小数点数から一様にサンプリングしたい場合は、下の@code{finite-flonums$}
を見てください。
@c COMMON
@end defun

@defun finite-flonums$
@c EN
Returns a flonum generator that samples uniformly from all possible
finite flonums.  It is not the same as uniformly sampling real numbers,
since floating-point numbers are not distributed evenly.
This is more useful if you want feed random flonums for testing,
than uniformly distributed real numbers, for the latter has
rather skewed distribution of exponents.
@c JP
可能な全ての有限の浮動小数点数から一様にサンプリングする浮動小数点数ジェネレータ
を返します。これは実数を一様にサンプリングするのとは異なります。
浮動小数点数は実数空間で一様に分布していないからです。
これは、テスト用途でランダムな浮動小数点数を使いたい場合に便利です。
実数範囲で一様サンプリングすると、得られる数値の指数部は非常に偏ったものになるからです。
@c COMMON
@end defun

@defun complexes-rectangular$ re-lb re-ub im-lb im-ub
@defunx complexes-polar$ [origin] mag-lb mag-ub :optional ang-lb ang-ub
@c EN
Returns a fresh generator of complex numbers uniformly.
All the @var{*-lb} and @var{*-ub} arguments must be real numbers, and each
@var{*-ub} argument must be greater than or equal to the corresponding
@var{*-lb} argument.  The @var{origin} argument is a complex number.

Generators returned by
@code{complexes-rectangular$} sample a rectangular area
where its real value is between @var{re-lb} and @var{re-ub} inclusive,
and its imaginary value is between @var{im-lb} and @var{im-ub} inclusive.

Generators returned by
@code{complexes-rectangular$} samples an annulus whose origin is
@var{origin}, whose magnitude is between @var{mag-lb} and @var{mag-ub}
inclusive, and whose angle is between @var{ang-lb} and @var{ang-ub}
radians inclusive.  If @var{origin}, @var{ang-lb}, and/or @var{ang-ub}
are omitted, they're defaulted to 0+0i, 0, and 2π.
@c JP
複素数を一様に生成する新たなジェネレータを作って返します。
全ての@var{*-lb}および@var{*-ub}引数は実数でなければならず、@var{*-ub}は
@var{*-lb}以上でなければなりません。@var{origin}は複素数です。

@code{complexes-rectangular$}が返すジェネレータは、
実部が@var{re-lb}と@var{re-ub}の間にあり、
虚部が@var{im-lb}と@var{im-ub}の間にある矩形領域中の複素数を生成します。
境界は含まれます。

@code{complexes-rectangular$}が返すジェネレータは、
@var{origin}を中心とし、半径が@var{mag-lb}と@var{mag-ub}、
切り取り角が@var{ang-lb}と@var{ang-ub}の間にある部分環状領域の中にある
複素数を生成します。境界は含まれます。
@var{origin}、@var{ang-lb}、@var{ang-ub}が
省略された場合は、それぞれ0+0i, 0, 2πが使われます。
@c COMMON
@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

@c EN
NB: The probability density function p(x) is
@code{(* (/ mean) (exp (- (/ x mean))))}.  Some definition of exponential
distribution uses a decay parameter λ such that p(x) is
@code{(* λ (exp (- (* x λ))))}.   That is, @i{λ} = 1/@i{mean}.
@c JP
註: 確率密度関数 p(x) は@code{(* (/ mean) (exp (- (/ x mean))))} です。
指数分布の定義では、期待値のかわりに、減衰パラメータ λ を使って確率密度関数を
@code{(* λ (exp (- (* x λ))))}とする流儀もあります。
この場合、@i{λ} = 1/@i{mean}です。
@c COMMON
@end defun

@defun reals-power-law$ xmin power
@c MOD data.random
@c EN
Creates a generator that yields finite positive real numbers greater
than or equal
to @var{xmin}, and follows the power-law probability density function
p(x) = (α-1)/xmin (x/xmin)^@{-α@}, where x >= xmin and α > 1.
The @var{power} argument specifies α.

The @var{xmin} argument must be a positive real numebr, and @var{power}
must be a real number greater than 1.
@c JP
冪乗則に従った確率で有限の正実数を生成するジェネレータを作って返します。
確率密度関数p(x)は(α-1)/xmin (x/xmin)^@{-α@}と表せます。ここでx ≧ xmin、α > 1 です。
@var{power}引数がαを指定します。

@var{xmin}は正の実数、@var{power}は1より大きい実数でなければなりません。
@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

@c EN
The resulting generator is exhausted when all the input generators are exhausted.
@c JP
返されるジェネレータは、全ての入力ジェネレータが終端に達した時に終わりとなります。
@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.  The default value is @code{(integers-poisson$ 4)}.
@c JP
@code{lists-of}、@code{vectors-of}、@code{strings-of}で
@var{sizer}引数が省略された場合に使われるsizerです。

値は、非負整数か、非負整数を生成するジェネレータでなければなりません。
デフォルトの値は@code{(integers-poisson$ 4)}です。
@c COMMON
@end deffn

@c ----------------------------------------------------------------------
@node Range, Ring buffer, Random data generators, Library modules - Utilities
@section @code{data.range} - Range
@c NODE レンジ, @code{data.range} - レンジ

@deftp {Module} data.range
@mdindex data.range
@c EN
A @emph{range} object is an immutable sequence with O(1) indexed access
to the elements, and each element may be computed procedurally.
For example, a range of intergers between 0 and N can be trivially
realized as a range, where @var{i}-th element is simply computed by
@code{identity}.  It is a lot more space-efficient than actually generating
a sequence containing every number.

It also allows certain operations efficient, such as taking subsequence
or appending sequences.

A range object can be used with @code{:range} qualifier in the
SRFI-42 eager comprehension (@pxref{Eager comprehensions}).
@c JP
レンジオブジェクトはO(1)で要素にアクセスでき、
そして各要素が手続き的に計算されるような不変なシーケンスです。
例えば、0からNまでの整数のレンジ、というのは、@var{i}番目の要素を計算する手続きが
@code{identity}であるようなレンジとして簡単に実現できるでしょう。
これは、全ての整数を持つシーケンスを作るよりずっと軽いです。

レンジはまた、一部分だけ取り出したレンジを作ったり、
レンジ同士をつなげたりする操作を効率的に行えます。

レンジオブジェクトはSRFI-42 先行評価的内包表記の@code{:range} qualifierに
渡すこともできます (@ref{Eager comprehensions}参照)。
@c COMMON

@c EN
A portable range object interface is defined in @code{srfi.196}.
We implement the range object as a @code{<sequence>}, so that all
sequence framework interface can be used on the ranges
(@pxref{Sequence framework}).  We also provide some additional
procedures that are not in SRFI-196.
@c JP
ポータブルなレンジオブジェクトのインタフェースは@code{srfi.196}で
規定されています。Gaucheではレンジオブジェクトを@code{<sequence>}として
実装し、シーケンスプロトコルも使えるようにしています
(@ref{Sequence framework}参照)。またこのモジュールでは@code{srfi.196}にない
手続きも提供されます。
@c COMMON
@end deftp

@c EN
@subheading Classes
@c JP
@subheading クラス
@c COMMON

@deftp {Class} <range>
@clindex range
@c EN
Range object class.  Internally we use several subclasses
according to the nature of the range, but externally all
ranges can be treated as an instance of @code{<range>}.
@c JP
レンジオブジェクトのクラスです。内部的には、異なるレンジの性質に合わせて
いくつかのサブクラスを使っていますが、外部的には全てのレンジを
@code{<range>}クラスのインスタンスとして扱って構いません。
@c COMMON
@end deftp

@deftp {Class} <range-meta>
@clindex range-meta
@c EN
The metaclass of @code{<range>} class.
@c JP
@code{<range>}クラスのメタクラスです。
@c COMMON
@end deftp

@c EN
@subheading Constructors
@c JP
@subheading コンストラクタ
@c COMMON

@defun range length indexer
[SRFI-196]
@c MOD data.range
@c EN
Creates and returns a range of length @var{length},
whose @var{i}-th element (0 <= @code{i} < @var{length}))
is determined by a procedure @var{indexer}, which takes @var{i}
as the sole argument and returns the corresponding element.
@c JP
長さが@var{length}で、@var{i}番目の要素(0 <= @code{i} < @var{length}))
が@code{(@var{indexer} @var{i})}で計算されるようなレンジを作って返します。
@c COMMON

@c EN
Note that @var{indexer} must run in O(1) time, and must be
referentially transparent.  The impelemntation may ``expand''
the range, that is, computes the element values into a flat
vector internally.
@c JP
手続き@var{indexer}はO(1)の時間オーダーで動作し、参照透過でなければなりません。
実装によっては、内部で要素の値をフラットベクタにキャッシュすることもありえます。
@c COMMON

@example
(range->list (range 5 (^i (+ i 10))))
 @result{} (10 11 12 13 14)
@end example
@end defun

@defun numeric-range start end :optional step
[SRFI-196]
@c MOD data.range
@c EN
Creates and returns a range of numbers starting from @var{start} (inclusive)
and ending below @var{end} (exclusive), increasing with @var{step}.
The default value of @var{step} is 1.
@c JP
@var{start}から始まり、@var{step}ごとに増加し、@var{end}未満で終わる数値のレンジを
作って返します。@var{step}が省略された場合は1が使われます。
@c COMMON

@example
(range->list (numeric-range 2 6))
 @result{} (2 3 4 5)

(range->list (numeric-range 0 5 2/3))
 @result{} (0 2/3 4/3 2 8/3 10/3 4 14/3)
@end example
@end defun

@defun iota-range length :optional start step
[SRFI-196]
@c MOD data.range
@c EN
Creates and returns a range of numbers.  Total length of the range
is @var{length}.  The range starts from @var{start} (default 0),
and increased with @var{step} (default 1).
@c JP
長さが@var{length}で、@var{start}から始まり@var{step}ごとに増加する
数値のレンジを作って返します。@var{start}、@var{step}の省略時の値は
それぞれ0と1です。
@c COMMON

@example
(range->list (iota-range 5))
  @result{} (0 1 2 3 4)

(range->list (iota-range 7 1 -1/7))
  @result{} (1 6/7 5/7 4/7 3/7 2/7 1/7)
@end example
@end defun

@defun vector-range vec :optional start end
[SRFI-196+]
@c MOD data.range
@c EN
Returns a range over the given vector @var{vec}.
The vector is kept in the range, so you shouldn't mutate @var{vec}.
See also @code{vector->range} below.
@c JP
ベクタ@var{vec}にアクセスするレンジを作って返します。
ベクタはそのままレンジのデータ元として使われるので、
この後で@var{vec}を変更してはなりません。
下の@code{vector->range}も参照。
@c COMMON

@c EN
The optional @var{start} and @var{end} arguments limits the
range of the vector to be used.
They are Gauche's extension and not in SRFI-196.
@c JP
省略可能引数@var{start}と@var{end}はベクタの使う範囲のインデックスを制限します。
これらの引数はGaucheの独自拡張で、SRFI-196にはありません。
@c COMMON

@example
(range->list (vector-range '#(a b c)))
  @result{} (a b c)

(range->list (vector-range '#(a b c d e) 1 4))
  @result{} (b c d)

(range-ref (vector-range '#(a b c d e) 2) 0)n
  @result{} c
@end example
@end defun

@defun uvector-range uvec :optional start end
@c MOD data.range
@c EN
Returns a range over the given uniform vector @var{uvec}.
The uniform vector is kept in the range, so you shouldn't mutate @var{uvec}.

The optional @var{start} and @var{end} arguments limits the
range of the uniorm vector to be used.
@c JP
ユニフォームベクタ@var{uvec}にアクセスするレンジを作って返します。
ユニフォームベクタはそのままレンジのデータ元として使われるので、
この後で@var{uvec}を変更してはなりません。

省略可能引数@var{start}と@var{end}はベクタの使う範囲のインデックスを制限します。
@c COMMON
@end defun

@defun bitvector/bool-range bvec :optional start end
@defunx bitvector/int-range bvec :optional start end
@c MOD data.range
@c EN
Returns a range over the given bitvector @var{bvec}.
@code{Bitvector/bool-range} regards @var{bvec} as a boolean vector,
while @code{bitvector/int-range} regards it as a vector of 0 and 1.
@xref{Bitvectors}, for the details of bitvectors.
Note that @var{bvec} is kept in the range, so you shouldn't mutate @var{bvec}.

The optional @var{start} and @var{end} arguments limits the
range of the bitvector to be used.
@c JP
ビットベクタ@var{bvec}にアクセスするレンジを作って返します。
@code{bitvector/bool-range}は@var{bvec}を真偽値のベクタ、
@code{bitvector/int-range}は0と1からなるベクタとみなします。
ビットベクタについて詳しくは@xref{Bitvectors}を参照してください。
@var{bvec}はレンジオブジェクトの中から直接参照されるので、
後から@var{bvec}を変更してはなりません。

省略可能な@var{start}、@var{end}引数はビットベクタのうち使われる範囲を制限します。
@c COMMON
@end defun

@defun string-range str :optional start end
[SRFI-196]
@c MOD data.range
@c EN
Returns a range over each character in the given string @var{str}.
The string is kept in the range, so you shouldn't mutate @var{str}.

The optional @var{start} and @var{end} arguments limits the
range of the string to be used.
They are Gauche's extension and not in SRFI-196.
@c JP
文字列@var{str}の各文字にアクセスするレンジを作って返します。
@var{str}はレンジオブジェクトから直接参照されるので、後で@var{str}を変更してはなりません。

省略可能な@var{start}、@var{end}引数は文字列のうち使われる範囲を制限します。
これはSRFI-196に対するGaucheの拡張です。
@c COMMON

@example
(range->list (string-range "abc"))
  @result{} (#\a #\b #\c)

(range->list (string-range "abcde" 1 4))
  @result{} (#\b #\c #\d)
@end example
@end defun

@defun range-append range @dots{}
[SRFI-196]
@c MOD data.range
@c EN
Returns a new range that walks over concatenation of the given ranges.
@c JP
与えられたレンジをつなぎ合わせたレンジを新たに作って返します。
@c COMMON
@end defun

@defun range-reverse range :optional start end
[SRFI-196+]
@c MOD data.range
@c EN
Returns a new range that walks over the elements of @var{range}, but
in reverse order.

The optional @var{start} and @var{end} arguments limits the
range of the vector to be used.
They are Gauche's extension and not in SRFI-196.
@c JP
@var{range}の各要素を逆順にアクセスする新たなレンジを作って返します。

省略可能な@var{start}、@var{end}引数は@var{range}のうち使われる範囲を制限します。
これはSRFI-196に対するGaucheの拡張です。
@c COMMON

@example
(range->list (range-reverse (string-range "abc")))
  @result{} (#\c #\b #\a)

(range->list (range-reverse (string-range "abcdef" 1 4)))
  @result{} (#\d #\c #\b)
@end example
@end defun

@c EN
@subheading Predicates
@c JP
@subheading 述語
@c COMMON

@defun range? obj
[SRFI-196]
@c MOD data.range
@c EN
Returns true iff @var{obj} is a range.
@c JP
@var{obj}がレンジなら@code{#t}を、そうでなければ@code{#f}を返します。
@c COMMON
@end defun

@defun range=? elt= range @dots{}
[SRFI-196]
@c MOD data.range
@c EN
Returns true iff all ranges have the same length, and any pair
of corresponding elements in the given ranges are equal in terms of
@code{elt=} predicate.

As edge cases, when zero or one range is given, @code{#t} is returned.
@c JP
与えられたレンジがすべて同じ長さで、
かつすべてのレンジのペアの対応する要素が@code{elt=}で比較して
等しい場合に@code{#t}を、そうでなければ@code{#f}を返します。

エッジケースとして、ゼロ個または一個のレンジが与えられた場合は無条件に@code{#t}を
返します。
@c COMMON

@example
(range=? eqv? (numeric-range 0 5)
              (iota-range 5)
              (vector-range '#(0 1 2 3 4)))
  @result{} #t
@end example
@end defun

@c EN
@subheading Accessors
@c JP
@subheading アクセサ
@c COMMON

@defun range-length range
[SRFI-196]
@c MOD data.range
@c EN
Returns the length of @var{range}.
@c JP
@var{range}の長さを返します。
@c COMMON
@end defun

@defun range-ref range i :optional fallback
[SRFI-196+]
@c MOD data.range
@c EN
Returns the @var{i}-th element of @var{range}.  The index
@var{i} must be an exact integer.

If @var{i} is negative, or greater than or equal to the length of @var{range},
@var{fallback} is returned if given, or an error is signaled.
The @var{fallback} argument is Gauche's extension and not in SRFI-196.
@c JP
@var{range}の@var{i}番目の要素を返します。@var{i}は正確な整数でなければなりません。

@var{i}が負、もしくは@var{range}の長さ以上だった場合、
@var{fallback}が与えられていればそれが返され、そうでなければエラーが投げられます。
@var{fallback}引数はSRFI-196に対するGauchenの拡張です。
@c COMMON
@end defun

@defun range-first range :optional fallback
@defunx range-last range :optional fallback
[SRFI-196+]
@c MOD data.range
@c EN
Returns the first or last element of @var{range}, respectively.

If the range is empty,
@var{fallback} is returned if given, or an error is signaled.
The @var{fallback} argument is Gauche's extension and not in SRFI-196.
@c JP
それぞれ、@var{range}の最初および最後の要素を返します。

@var{range}が空の場合、
@var{fallback}が与えられていればそれが返され、そうでなければエラーが投げられます。
@var{fallback}引数はSRFI-196に対するGaucheの拡張です。
@c COMMON
@end defun

@c EN
@subheading Iteration
@c JP
@subheading 繰り返し
@c COMMON

@defun range-split-at range k
[SRFI-196]
@c MOD data.range
@c EN
Returns two ranges, the first one with elements before @var{k}-th
elements of @var{range},
and the second one with @var{k}-th elements and after of @var{range}.
@c JP
元のレンジのうち、@var{k}番目より前の要素を含むレンジと、
@var{k}番目以降の要素を含むレンジを作って二つの値として返します。
@c COMMON
@end defun

@defun subrange range start end
[SRFI-196]
@c MOD data.range
@c E
Returns a new range that contains @var{start}-th (inclusive)
to @var{end}-th (exclusive) elements of @var{range}.
@c JP
元のレンジの@var{start}番目から@var{end}番目の手前の要素までを含む
レンジを作って返します。
@c COMMON
@end defun

@defun range-segment range len
[SRFI-196]
@c MOD data.range
@c EN
Split @var{range} into subranges of length @var{len} and returns
the result ranges.  The last range
may be shorter than @var{len}.
@c JP
@var{range}を、それぞれ長さ@var{len}のレンジに分割してそのリストを返します。
最後のレンジは@var{len}より短いかもしれません。
@c COMMON

@example
(map range->list (range-segment (numeric-range 0 11) 4))
 @result{} ((0 1 2 3) (4 5 6 7) (8 9 10))
@end example
@end defun

@defun range-take range count
@defunx range-take-right range count
[SRFI-196]
@c MOD data.range
@c EN
Returns a new range containing initial @var{count} elements or last @var{count}
elements from @var{range}, respectively
@c JP
それぞれ、@var{range}の最初もしくは最後の@var{count}個の要素を含むレンジを返します。
@c COMMON
@end defun

@defun range-drop range count
@defunx range-drop-range range count
[SRFI-196]
@c MOD data.range
@c EN
Returns a new range containing elements of @var{range}
except initial @var{count} elements or last @var{count} elements, respectively.
@c JP
それぞれ、@var{range}の最初もしくは最後から@var{count}個の要素を除いたレンジを返します。
@c COMMON
@end defun

@defun range-count pred range range2 @dots{}
[SRFI-196]
@c MOD data.range
@c EN
A procedure @var{pred} must take as many arguments as the given ranges.
It is called on each corresponding element of
@var{range}, @var{range2} @dots{}, and the procedure returns
the number of times @var{pred} returned true.

If more than one ranges are given and not all ranges are of the same length,
iteration terminates at the end of the shortest range.
@c JP
@var{pred}は引数のレンジの数と同じだけの引数を取る述語です。
各レンジの対応する要素を引数として@var{pred}が呼ばれ、
それが真の値を返した回数を返します。

複数のレンジが与えられ、それらの長さが異なっていた場合、
繰り返しは最も短いレンジで止まります。
@c COMMON
@end defun

@defun range-any pred range range2 @dots{}
[SRFI-196]
@c MOD data.range
@c EN
A procedure @var{pred} must take as many arguments as the given ranges.
It is called on each first element of
@var{range}, @var{range2} @dots{}, then each second element, and so on.
As soon as @var{pred} returns a true value, the iteration stops
and the value @var{pred} returns becomes the result of @code{range-any}.
If @var{pred} never returns a true value, @code{#f} is returned.

If more than one ranges are given and not all ranges are of the same length,
iteration terminates at the end of the shortest range.
@c JP
@var{pred}は引数のレンジの数と同じだけの引数を取る手続きです。
各レンジの対応する要素を引数として@var{pred}が順に呼ばれます。
@var{pred}が真の値を返したら、繰り返しは打ち切られ、その@var{pred}の戻り値が
返されます。@var{pred}が全て@code{#f}を返した場合は@code{#f}が返されます。

複数のレンジが与えられ、それらの長さが異なっていた場合、
繰り返しは最も短いレンジで止まります。
@c COMMON
@end defun

@defun range-every pred range range2 @dots{}
[SRFI-196]
@c MOD data.range
@c EN
A procedure @var{pred} must take as many arguments as the given ranges.
It is called on each first element of
@var{range}, @var{range2} @dots{}, then each second element, and so on.
As soon as @var{pred} returns a false value, the iteration stops
and @code{range-any} returns @code{#f}.
If all @var{pred} returns a true value, the last value is returned.

If more than one ranges are given and not all ranges are of the same length,
iteration terminates at the end of the shortest range.
@c JP
@var{pred}は引数のレンジの数と同じだけの引数を取る手続きです。
各レンジの対応する要素を引数として@var{pred}が順に呼ばれます。
@var{pred}が@code{#f}を返したら、繰り返しは打ち切られ、@code{#f}が返されます。
@var{pred}が全て真の値を返した場合は、最後の値が戻り値となります。

複数のレンジが与えられ、それらの長さが異なっていた場合、
繰り返しは最も短いレンジで止まります。
@c COMMON
@end defun


@defun range-map proc range range2 @dots{}
@defunx range-map->list proc range range2 @dots{}
@defunx range-map->vector proc range range2 @dots{}
[SRFI-196]
@c MOD data.range
@c EN
Mapping over ranges.
A procedure @var{proc} must take as many arguments as the given ranges,
and is called on each corresponding element of
@var{range}, @var{range2} @dots{}.  The results are collected and returned
as a range (@code{range-map}), a list (@code{range-map->list},
or a vector (@code{range-map->vector}.  The dynamic order of
in which @var{proc} is invoked is not specified.  Note that
@code{range-map} computes all elements before returning the result range.

If more than one ranges are given and not all ranges are of the same length,
iteration terminates at the end of the shortest range.
@c JP
レンジに対するmapです。
@var{proc}は引数のレンジの数と同じだけの引数を取る手続きで、
各レンジの対応する要素を引数として呼び出されます。
結果は集められ、
それぞれレンジ(@code{range-map})、リスト(@code{range-map->list})、
ベクタ(@code{range-map->vector}) として返されます。
@var{proc}が呼ばれる順番は規定されていません。
@code{range-map}は全ての要素を計算してから結果を返します。

複数のレンジが与えられ、それらの長さが異なっていた場合、
繰り返しは最も短いレンジで止まります。
@c COMMON
@end defun

@defun range-for-each proc range range2 @dots{}
[SRFI-196]
@c MOD data.range
@c EN
A procedure @var{proc} must take as many arguments as the given ranges.
It is invoked with the first elements of each range,
and then with the second elements of them, and so on,
until the shortest range is exhausted.  The result of @var{proc} is
discarded.

Returns an undefined value.
@c JP
@var{proc}は引数のレンジの数と同じだけの引数を取る手続きで、
各レンジの対応する要素を引数として順に呼び出されます。
繰り返しは最も短いレンジの末尾で止まります。@var{proc}の結果は捨てられます。

戻り値は未定義です。
@c COMMON
@end defun

@defun range-filter pred range
@defunx range-filter->list pred range
@defunx range-remove pred range
@defunx range-remove->list pred range
@defunx range-filter-map pred range range2 @dots{}
@defunx range-filter-map->list pred range range2 @dots{}
[SRFI-196]
@c MOD data.range
@c EN
A procedure @var{pred} must take as many arguments as the given ranges.
These are range version of @code{filter}, @code{remove}, and
@code{filter-map} (@pxref{Walking over lists}).
@c JP
@var{pred}は引数のレンジの数と同じだけの引数を取る手続きです。
これらの手続きは@code{filter}、@code{remove}、@code{filter-map}
のレンジ版です (@ref{Walking over lists}参照)。
@c COMMON

@c EN
The procedures without @code{->list} returns the result as a range,
while the ones with @code{->list} returns the result as a list.
@c JP
手続きに@code{->list}がついていないものは、結果をレンジで返します。
ついているものは結果をリストで返します。
@c COMMON

@c EN
The iteration stops when the shortest range is exhausted.
The result is eagerly computed.
@c JP
繰り返しは最も短いレンジを使い切ったところで止まります。
結果は返される前に全て計算されます。
@c COMMON

@example
(range->list (range-filter odd? (iota-range 10)))
  @result{} (1 3 5 7 9)
(range-remove->list odd? (iota-range 10))
  @result{} (0 2 4 6 8)
(range->list (range-filter-map (every-pred odd? square) (iota-range 10)))
  @result{} (1 9 25 49 81)
@end example
@end defun

@defun range-fold kons knil range range2 @dots{}
@defunx range-fold-right kons knil range range2 @dots{}
[SRFI-196]
@c MOD data.range
@c EN
These are range version of @code{fold} and @code{fold-right}
(@pxref{Walking over lists}).
The iteration stops when the shortest range is exhausted.
@c JP
@code{fold}、@code{fold-right}のレンジ版です
(@ref{Walking over lists}参照)。
繰り返しは最も短いレンジを使い切ったところで止まります。
@c COMMON
@end defun

@c EN
@subheading Searching
@c JP
@subheading 検索
@c COMMON

@defun range-index pred range range2 @dots{}
@defunx range-index-right pred range range2 @dots{}
[SRFI-196]
@c MOD data.range
@c EN
Returns the first or the last index of the element in the input range
that satisfies a predicate @var{pred}.  If there are more than one
ranges, @var{pred} must take as many arguments as the number of input
ranges, and applied on each corresponding elements of the input range.
@c JP
入力レンジの要素のうち、@var{pred}を満たす最初もしくは最後の要素のインデックスを
返します。複数のレンジが与えられた場合は@var{pred}はそのレンジの数と同じだけ
引数を取り、各レンジから取ってきた要素が渡されます。
@c COMMON

@example
(range-index > (vector-range '#(1 5 3 2 4))
               (vector-range '#(4 3 0 4 6)))
  @result{} 1
(range-index-right > (vector-range '#(1 5 3 2 4))
                     (vector-range '#(4 3 0 4 6)))
  @result{} 2
@end example
@end defun

@defun range-take-while pred range
@defunx range-take-while-right pred range
@defunx range-drop-while pred range
@defunx range-drop-while-right pred range
[SRFI-196]
@c MOD data.range
@c EN
Same as @code{take-while}, @code{take-while-right}, @code{drop-while},
and @code{drop-while-right}, except those operate on an range
and return an range, instead of a list (@pxref{R7RS lists}).
@c JP
@code{take-while}、@code{take-while-right}、@code{drop-while}、
@code{drop-while-right}のレンジ版です (@ref{R7RS lists}参照)。
@c COMMON
@end defun

@c EN
@subheading Conversion
@c JP
@subheading 変換
@c COMMON

@defun range->list range
@defunx range->vector range
@defunx range->string range
[SRFI-196]
@c MOD data.range
@c EN
Convert a range to a list, a vector ro a string, respectively.
For @code{range->string}, the argument must be a range consists solely
of characters.
@c JP
レンジをそれぞれリスト、ベクタ、文字列に変換します。
@code{range->string}に渡さえるレンジは文字だけで構成されていなければなりません。
@c COMMON
@end defun

@defun vector->range vec :optional start end
[SRFI-196]
@c MOD data.range
@c EN
Returns a range whose elements are those of a vector @var{vec}.
Unlike @code{vector-range}, the content of @var{vec} is copied into
the range, so mutating @var{vec} won't alter the resulting range.

The optional @var{start} and @var{end} arguments limit the portion
to be used for the result.
@c JP
ベクター@var{vec}の要素から構成されるレンジを返します。
@code{vector-range}と違って@var{vec}の内容はレンジにコピーされるので、
この呼び出しの後で@var{vec}の内容を変更してもレンジに影響はありません。

省略可能な@var{start}と@var{end}引数は入力ベクタのうち使われる範囲を制限します。
@c COMMON
@end defun

@defun range->generator range :optional start end
[SRFI-196]
@c MOD data.range
@c EN
Returns a generator that yields each element of @var{range},
between @var{start} (inclusive) and @var{end} (exclusive) indexes.
When omitted, @var{start} is 0 and @var{end} is the size of the range.
@c JP
レンジ@var{range}の、@var{start} (含む) から @var{end} (含まない) までの
要素をひとつづつ返すジェネレータを返します。
@var{start}、@var{end}が省略された場合はそれぞれ0とレンジのサイズが使われます。
@c COMMON
@end defun

@c ----------------------------------------------------------------------
@node Ring buffer, Skew binary random-access lists, Range, 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 initial-head-index initial-tail-index
@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
By default, the storage you pass as @var{initial-storage} is assumed to
be an empty buffer.  You can also pass a pre-filled storage, by
specifing valid range of existing data with
@var{initial-head-index} and @var{initial-tail-index} arguments
(both are defaulted to 0).  For example, the following code returns
a ring buffer of initial capacity 8, with the first 4 items are
already filled.
@c JP
デフォルトでは、@var{initial-storage}に渡されたストレージは空のバッファとみなされます。
しかし、あらかじめ一部に有効なデータを入れて渡すこともできます。その場合は、
@var{initial-head-index}と@var{initial-tail-index}引数で有効なデータの
インデックスの範囲を指定してください(これらの引数のデフォルトは0です)。
例えば次のコードは、初期容量8のリングバッファのうち、最初の4要素が既に埋められているような
リングバッファを作って返します。
@c COMMON

@example
(make-ring-buffer (vector 'a 'b 'c 'd #f #f #f #f)
                  :initial-tail-index 4)
@end example


@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
リングバッファ@var{rb}の現在のバッキングストレージの容量(格納可能な要素数)を返します。
@c COMMON
@end defun

@defun rinb-buffer-room rb
@c MOD data.ring-buffer
@c EN
Returns the remaining room in the current backing storage of the ring buffer
@var{rb}, before triggering the overflow handler.  It is the difference
of @code{ring-buffer-capacity} and @code{ring-buffer-num-entries}.
@c JP
リングバッファ@var{rb}の現在のバッキングストレージに追加で格納可能な
要素数を返します。この要素数を超えて要素を挿入しようとすると
オーバーフローハンドラが呼ばれます。
これは@code{ring-buffer-capacity}と@code{ring-buffer-num-entries}
の差に等しいです。
@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


@defun ring-buffer->xvector rb :optional start end
@c MOD data.ring-buffer
@c EN
Returns the current valid content of the ring buffer @var{rb}
as a fresh vector
of the same type as @var{rb}'s storage.  If the optional @var{start}/@var{end}
indexes are given, the content between those indexes are taken.
@c JP
リングバッファ@var{rb}の現在の有効な範囲の内容を、新たにアロケートされる
@var{rb}のストレージと同じ型のベクタとして返します。
@var{start}/@var{end}インデックスを指定した場合はそのインデックスの範囲内の
内容だけが取り出されます。
@c COMMON

@example
(define rb (make-ring-buffer (make-vector 4)))

(ring-buffer->xvector rb) @result{} #()

(ring-buffer-add-back! rb 'a)
(ring-buffer-add-back! rb 'b)
(ring-buffer-add-front! rb 'z)
(ring-buffer-add-front! rb 'y)

(ring-buffer->xvector rb) @result{} #(y z a b)
(ring-buffer->xvector rb 1 3) @result{} #(z a)
@end example
@end defun

@defun ring-buffer->xvector! target tstart rb :optional start end
@c MOD data.ring-buffer
@c EN
Like @code{ring-buffer->xvector} above, but store the result into
@var{target}, starting from index @var{tstart}.  @var{Target} must be
the same type of vector of the backing storage of @var{rb},
and must be large enough to hold the result.
If the optional @var{start}/@var{end}
indexes are given, the content between those indexes are taken.
@c JP
@code{ring-buffer->xvector}と似ていますが、結果を@var{target}の、
インデックス@var{tstart}からに格納します。
@var{target}は@var{rb}のバッキングストレージと同じ型で、
結果を保持するのに十分な容量がなければなりません。
@var{start}/@var{end}インデックスを指定した場合はそのインデックスの範囲内の
内容だけが取り出されます。
@c COMMON
@end defun


@defun ring-buffer->xsubvectors rb :optional start end
@c MOD data.ring-buffer
@c EN
Returns @code{(vec start1 end1)} or @code{(vec start1 end1 vec start2 end2)},
where @var{vec} is the backing storage of ring buffer @var{rb},
and @var{start1}, @var{end1}, @var{start2}, @var{end2} are integer index
into @var{vec}.  They represent the range(s) in the backing storage
where active ring buffer data is stored.  It may be contiguous,
or splitted to two parts when the buffer is wrapped around.

The optional @var{start} and @var{end} arguments are indexes of
the contents of ring buffer (@emph{not} the indexes to the backing
storage) to limit the range of the contents to be extracted.

The returned list can be passed as arguments to
@code{vector-append-subvectors} (@pxref{R7RS vectors}) or
@code{@@vector-append-subvector} (@pxref{Uvector basic operations}).

This procedure is lightweight, for it doesn't allocate.  However,
be aware that the content of @var{vec} may be changed and/or indexes
become invalid by operations on
@var{rb}.  I you want a snapshot of the ring buffer contents,
you can use @code{ring-buffer->xvector} above.
@c JP
@code{(vec start1 end1)}か@code{(vec start1 end1 vec start2 end2)}を返します。
ここで、@var{vec}はリングバッファ@var{rb}のバッキングストレージ、
@var{start1}、@var{end1}、@var{start2}、@var{end2}はバッキングストレージの
整数インデックスです。これは、バッキングストレージ中の、リングバッファの有効な
データが存在する範囲を示しています。
有効なデータはひとつづきであるか、バッファの末尾でラップアラウンドして
二つの部分に分かれて存在します。

省略可能な@var{start}と@var{end}引数はリングバッファの内容への整数インデックス
(バッキングストレージのインデックスではなく)で、取り出す範囲を制限します。

返されるリストは、それを引数として
@code{vector-append-subvectors} (@ref{R7RS vectors}参照) あるいは
@code{@@vector-append-subvector} (@ref{Uvector basic operations}参照)
を呼び出すことができる形になっています。

この手続きはアロケーションを行わないので軽いですが、この後でリングバッファに
対する操作を行うと@var{vec}の内容が上書きされたり返されたインデックスが無効
になることに注意してください。ある時点でのリングバッファの内容のスナップショットを
保存したい場合は、上の@code{ring-buffer->xvector}が使えます。
@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.skew-list} - Skew binary random-access lists

@deftp {Module} data.skew-list
@mdindex data.skew-list
@c EN
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.
@c JP
このモジュールは、Skew binary random-access list
(以降は短くskew-listと表記します)を提供します。
skew-listは変更不可なデータ構造で、リストとベクタの中間のような
性質を持っています:要素数をnとするとき
最初の要素を取り出したり(car)、最初に要素を追加する(cons)のはO(1)、
最初以外の要素を返す(cdr)のはO(log n)、
そして整数インデックスにより任意の要素にアクセスするのもO(log n)です。
@c COMMON

@c EN
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.
@c JP
skew-listは常に「properなリスト」です。すなわち、それは
空のskew-list (@code{skew-list-null})か、
skew-listの前に要素を付け足したもの、です。
@c COMMON
@end deftp

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

It inherits @code{<sequence>} and implements the sequence protocol
(@pxref{Sequence framework}).
@c JP
skew-listのクラスです。

@code{<sequence>}を継承していて、シーケンスプロトコルを実装しています
(@ref{Sequence framework}参照)。
@c COMMON
@end deftp

@defun skew-list? obj
@c MOD data.skew-list
@c EN
Returns @code{#t} iff @var{obj} is a skew-list.
@c JP
@var{obj}がskew-listなら@code{#t}を、そうでなければ@code{#f}を返します。
@c COMMON
@end defun

@defun skew-list-empty? sl
@c MOD data.skew-list
@c EN
The argument must be a skew list.  Returns @code{#t} iff @var{sl}
is an empty skew list.
@c JP
引数はskew listでなければなりません。
@var{sl}が空のskew listなら@code{#t}を、そうでなければ@code{#f}を返します。
@c COMMON
@end defun

@defvar skew-list-null
@c MOD data.skew-list
@c EN
An empty skew list.
@c JP
空のskew listに束縛されています。
@c COMMON
@end defvar

@defun skew-list-cons obj sl
@c MOD data.skew-list
@c EN
Returns a new skew-list which has @var{obj} prepended to
a skew-list @var{sl}.  O(1) operation.
@c JP
skew list @var{sl}の先頭に@var{obj}を追加した新たなskew listを作って返します。
O(1)の操作です。
@c COMMON
@end defun

@defun skew-list-car sl
@c MOD data.skew-list
@c EN
Returns the first element of a skew-list @var{sl}.   O(1) operation.
An error is raised when @var{sl} is empty.
@c JP
skew list @var{sl}の先頭要素を返します。O(1)の操作です。
@var{sl}が空であればエラーが投げられます。
@c COMMON
@end defun

@defun skew-list-cdr sl
@c MOD data.skew-list
@c EN
Returns a new skew-list that containts elements in @var{sl} but
the first one.  O(log n) operation.
An error is raised when @var{sl} is empty.
@c JP
skew list @var{sl}の、最初の要素を取り除いたskew listを返します。
O(log n)の操作です。
@var{sl}が空であればエラーが投げられます。
@c COMMON
@end defun

@defun skew-list-ref sl k :optional fallback
@c MOD data.skew-list
@c EN
Returns the @var{k}-th element of a skew-list @var{sl}.  O(log n) operation.
If @var{k}
points past the range of @var{sl}, @var{fallback} is returned if it
is given, or an error is signaled.
@c JP
skew list @var{sl}の@var{k}番目の要素を返します。O(log n)の操作です。
@var{k}が@var{sl}の範囲外を指している場合、@var{fallback}が与えられていればそれが
返され、与えられていなければエラーが投げられます。
@c COMMON

@c EN
Sicne a skew-list is also a sequence, you can use generic @code{ref} as well
(@pxref{Sequence framework}).
@c JP
skew listはシーケンスでもあるので、@code{ref}でアクセスすることもできます
(@ref{Sequence framework}参照)。

@c COMMON
@end defun

@defun skew-list-set sl k obj
@c MOD data.skew-list
@c EN
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.
O(log n) operation.
@c JP
skew list @var{sl}の、@var{k}番目の要素を@var{obj}に変えた新たなskew listを
作って返します。元の@var{sl}は変更されません。
O(log n)の操作です。
@c COMMON

@c EN
It is an error if @var{k} points beyond the last element of @var{sl}.
@c JP
@var{k}が@var{sl}の範囲外を指していた場合はエラーが投げられます。
@c COMMON
@end defun

@defun skew-list-length sl
@c MOD data.skew-list
@c EN
Returns an integer length of a skew-list @var{sl}.  O(log n) operation.
@c JP
skew list @var{sl}の長さを返します。O(log n)の操作です。
@c COMMON

@c EN
Sicne a skew-list is also a sequence, you can use generic @code{size-of} as well
(@pxref{Sequence framework}).
@c JP
skew listはシーケンスでもあるので、@code{size-of}も使えます
(@ref{Sequence framework}参照)。
@c COMMON
@end defun

@defun skew-list-length<=? sl n
@c MOD data.skew-list
@c EN
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}.
@c JP
skew list @var{sl}の長さが@var{n}以下であれば@code{#t}を、そうでなければ
@code{#f}を返します。@var{sl}の全長を求めて@var{n}と比較するより効率的です。
@c COMMON
@end defun

@defun list->skew-list lis
@c MOD data.skew-list
@c EN
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.
@c JP
リスト@var{lis}と同じ要素を同じ並びで持つskew listを作って返します。
@var{lis}が正式なリストでなければエラーが投げられます。
@c COMMON

@c EN
Sicne a skew-list is also a sequence, you can use generic @code{coerce-to}
as well (@pxref{Sequence framework}).
@c JP
skew listはシーケンスでもあるので、@code{coerce-to}を使うこともできます
(@ref{Sequence framework}参照)。
@c COMMON
@end defun

@defun list*->skew-list lis
@c MOD data.skew-list
@c EN
The argument @var{lis} may be a dotted 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}.
@c JP
@var{lis}は正式なリストまたはドットリストです (循環リストであってはいけません)。
二つの値を返します。@var{lis}の最後のcdrを除いた要素をその並びで持つ新たな
skew listと、@var{lis}の最後のcdrの値です。
@c COMMON
@end defun

@defun skew-list->list sl
@c MOD data.skew-list
@c EN
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}.
@c JP
skew list @var{sl}の各要素を同じ並びで持つリストを作って返します。

skew listはシーケンスでもあるので、@code{coerce-to}を使うこともできます
(@ref{Sequence framework}参照)。
@c COMMON
@end defun

@defun skew-list->generator sl
@c MOD data.skew-list
@c EN
Returns a new generator that traverses a skew-list @var{sl}.
@c JP
skew list @var{sl}の要素を順に生成するジェネレータを作って返します。
@c COMMON
@end defun

@defun skew-list->lseq sl
@c MOD data.skew-list
@c EN
Converts a skew-list @var{sl} to a lazy sequence.
@c JP
skew list @var{sl}を遅延シーケンスに変換します。
@c COMMON
@end defun

@defun skew-list-take sl k
@defunx skew-list-drop sl k
@c MOD data.skew-list
@c EN
Returns a new skew-list of the first @var{k} elements and the elements
except the first @var{k} elements, respectively.
@c JP
skew list @var{sl}の、最初の@var{k}要素だけのskew list、
あるいは最初の@var{k}要素を取り除いた残りのskew listを返します。
@c COMMON
@end defun

@defun skew-list-split-at sl k
@c MOD data.skew-list
@c EN
Returns two values, the result of @code{(skew-list-take sl k)}
and @code{(skew-list-drop sl k)}, but more efficiently.
@c JP
@code{(skew-list-take sl k)}と@code{(skew-list-drop sl k)}の結果を
2つの値として返しますが、より効率が良いです。
@c COMMON
@end defun

@defun skew-list-append sl sl2 @dots{}
@c MOD data.skew-list
@c EN
Returns a skew-list which is a concatenation of all the given skew-lists.
@c JP
2つのskew listをつなげたskew listを返します。
@c COMMON
@end defun

@defun skew-list-fold sl kons knil
@c MOD data.skew-list
@c EN
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}.
@c JP
skew list @var{sl}に対して、リストに対する@var{fold}と同じような動作をします。

skew listはシーケンスでもあるので、ジェネリックな@code{fold}を使うこともできます
(@ref{Sequence framework}参照)。
@c COMMON
@end defun

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

NB: If you want to 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.
@c JP
skew list @var{sl}の各要素に@var{proc}を適用した結果を集めた新たなskew listを
作って返します。@var{proc}が適用される順序は決められていません。

複数のskew listに対して@code{map}したい場合は、
ジェネリックの@code{map}が使えます (@ref{Sequence framework})。
@code{skew-list-map}は単一引数の場合に使える最適化を施してあります。
@c COMMON
@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
@clindex sparse-c32vector
@clindex sparse-c64vector
@clindex sparse-c128vector
@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}, @code{f64},
@code{c32}, @code{c64}, or @code{c128}.
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{c32}, @code{c64}, @code{c128}のいずれかで、
それぞれの疎なベクタの格納可能な値は、@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}, @code{f64},
@code{c32}, @code{c64}, or @code{c128}.

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},
@code{c32}, @code{c64}, @code{c128}のいずれかを指定できます。

@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
@c EN
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}.
@c JP
@var{sv}の各要素について、@var{proc}をインデックスと値を引数にして
@code{(proc k value)}のように呼び出します。

@code{sparse-vector-for-each}では@var{proc}の結果は捨てられ、
@code{sparse-vector-map}では結果がリストに集められて返されます。
@c COMMON
@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
@c EN
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.
@c JP
疎な行列の抽象ベースクラスです。@code{<collection>}を継承しています。

疎なベクタと同様に、疎な行列には任意のSchemeオブジェクトを格納できるものと、
特定の範囲の数値を格納できるものがあります。

全ての疎な行列のサブタイプへのアクセスには同じAPIが使えます。
@c COMMON
@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
@clindex sparse-c32matrix
@clindex sparse-c64matrix
@clindex sparse-c128matrix
@c MOD data.sparse
@c EN
The actual sparse matrix classes.  Inherits @code{<sparse-matrix-base>}.
An instance of @code{<sparse-matrix>} can contain any Scheme objects.
@c JP
疎な行列の具体クラスです。それぞれ@code{<sparse-matrix-base>}を継承します。
@code{<sparse-matrix>}のインスタンスは任意のSchemeオブジェクトを格納できます。
@c COMMON

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

@defun make-sparse-matrix :optional type :key default
@c MOD data.sparse
@c EN
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}, @code{f64},
@code{c32}, @code{c64}, or @code{c128}.
@c JP
空の疎な行列を作成して返します。@var{type}引数は@code{#f}(デフォルト)か、
@code{<sparse-matrix-base>}のサブクラスのどれか、
あるいはシンボル@code{s8}, @code{u8},
@code{s16}, @code{u16}, @code{s32}, @code{u32},
@code{s64}, @code{u64}, @code{f16}, @code{f32}, @code{f64},
@code{c32}, @code{c64}, @code{c128}のいずれかを指定できます。
@c COMMON

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

@c EN
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.
@c JP
キーワード引数@var{default}によって、作成する行列の要素既定値を指定できます。
この引数が与えられると、行列は全てあらかじめその値で埋められているかのように
振る舞います (ただしイテレータは陽にセットされた値のみ取り出します)。

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

@defun sparse-matrix-num-entries mat
@c MOD data.sparse
@c EN
Returns the number of entries explicitly set in a sparse matrix @var{mat}.
@c JP
疎な行列@var{mat}に明示的にセットされたエントリの数を返します。
@c COMMON
@end defun

@defun sparse-matrix-ref mat x y :optional fallback
@c MOD data.sparse
@c EN
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.
@c JP
疎な行列@var{mat}の(@var{x}, @var{y})で指される要素を返します。
その要素がセットされていなかった場合、@var{fallback}が与えられていれば
それが返され、そうでなければ、行列のデフォルト値が返されます。
行列がデフォルト値も持っていなければエラーが投げられます。
@c COMMON
@end defun

@defun sparse-matrix-set! mat x y value
@c MOD data.sparse
@c EN
Set @var{value} to the sparse matrix @var{mat} at the location
(@var{x}, @var{y}).
@c JP
疎な行列@var{mat}の(@var{x}, @var{y})に@var{value}をセットします。
@c COMMON
@end defun

@defun sparse-matrix-exists? mat x y
@c MOD data.sparse
@c EN
Returns @code{#t} iff the sparse matrix @var{mat} has a value at
(@var{x}, @var{y}).
@c JP
疎な行列@var{mat}の(@var{x}, @var{y})に明示的に値がセットされていれば@code{#t}を、
そうでなければ@code{#f}を返します。
@c COMMON
@end defun

@defun sparse-matrix-clear! mat
@c MOD data.sparse
@c EN
Empties the sparse matrix @var{mat}.
@c JP
疎な行列@var{mat}を空にします。
@c COMMON
@end defun

@defun sparse-matrix-delete! mat x y
@c MOD data.sparse
@c EN
Remove the value at (@var{x}, @var{y}) from the sparse matrix @var{mat}.
@c JP
疎な行列@var{mat}の(@var{x}, @var{y})の要素を取り除きます。
@c COMMON
@end defun

@defun sparse-matrix-copy mat
@c MOD data.sparse
@c EN
Returns a fresh copy of @var{mat}.
@c JP
@var{mat}のコピーを新たに作って返します。
@c COMMON
@end defun

@defun sparse-matrix-update! mat x y proc :optional fallback
@c MOD data.sparse
@c EN
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.
@c JP
疎な行列の(@var{x}, @var{y})の要素の値を引数にして@var{proc}を呼び出し、
その返り値を新たな値としてセットします。

省略可能な@var{fallback}は@code{sparse-matrix-ref}と同様です。
(@var{x}, @var{y})に要素がセットされていない時、
@var{fallback}が与えられていればそれがが@var{proc}に渡されます。
@var{fallback}が与えられず、しかし配列のデフォルト値が設定されていれば
そのデフォルト値が@var{proc}に渡されます。
デフォルト値も設定されていなければエラーが投げられます。
@c COMMON
@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
@c EN
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.
@c JP
疎な行列@var{mat}の要素についてループします。
@var{proc}は@var{mat}の各インデックス(@var{x}, @var{y})とその場所の値@var{val}
について、4つの引数 @var{x}、@var{y}、@var{val}、@var{seed}で呼ばれます。
最初の@var{seed}は@code{sparse-matrix-fold}に渡された@var{seed}であり、
@var{proc}の返り値が次の呼び出しの@var{seed}に渡されてゆきます。
最後の@var{proc}の返り値が@code{sparse-matrix-fold}の返り値となります。

@var{proc}は、明示的にセットされたエントリに対してのみ呼ばれます。
また、それが呼ばれる順序は不定です。
@c COMMON
@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
@c EN
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.)
@c JP
疎なテーブルのクラスです。@code{<dictionary>}と
@code{<collection>}を継承しています。

操作から見ると、疎なテーブルはハッシュテーブルと同じです。
ただ、アクセスが多少遅いかわりに、メモリ消費量が抑えられます。
(テーブルが小さいうちは、およそ1.5〜2倍アクセスが遅いですが、
デーブルが大きくなるにつれ差は縮まります。)
@c COMMON
@end deftp

@defun make-sparse-table comparator
@c MOD data.sparse
@c EN
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.
@c JP
空の疎なテーブルを作って返します。
@var{comparator}は、キーの比較とハッシュに使われる比較器
(@ref{Basic comparators}参照)、もしくはシンボル
@code{eq?}、@code{eqv?}、@code{equal?}、@code{string=?}のいずれかです
(これはハッシュテーブルと同じです。@ref{Hashtables}参照)。
シンボルの場合は、それぞれ
@code{eq-comparator}、@code{eqv-comparator}、@code{equal-comparator}、
@code{string-comparator}が使われます。
@c COMMON
@end defun

@defun sparse-table-comparator st
@c MOD data.sparse
@c EN
Returns the comparator used in the sparse table @var{st}.
@c JP
疎なテーブル@var{st}の比較器を返します。
@c COMMON
@end defun

@defun sparse-table-copy st
@c MOD data.sparse
@c EN
Returns a copy of a sparse table @var{st}.
@c JP
疎なテーブル@var{st}のコピーを作って返します。
@c COMMON
@end defun

@defun sparse-table-num-entries st
@c MOD data.sparse
@c EN
Returns the number of entries in a sparse table @var{st}.
@c JP
疎なテーブル@var{st}のエントリ数を返します。
@c COMMON
@end defun

@defun sparse-table-ref st key :optional fallback
@c MOD data.sparse
@c EN
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.
@c JP
疎なテーブル@var{st}中の、キー@var{key}に関連付けられた値を返します。
キーがテーブル中にない場合、@var{fallback}が与えられればそれが返され、
与えられなければエラーが投げられます。
@c COMMON
@end defun

@defun sparse-table-set! st key value
@c MOD data.sparse
@c EN
Sets @var{value} with @var{key} in @var{st}.
@c JP
疎なテーブル@var{st}に、キー@var{key}と値@var{value}の関連づけを格納します。
@c COMMON
@end defun

@defun sparse-table-exists? st key
@c MOD data.sparse
@c EN
Returns @code{#t} if an entry with @var{key} exists in @var{st},
@code{#f} otherwise.
@c JP
疎なテーブル@var{st}に、キー@var{key}を持つエントリがあれば
@code{#t}を、なければ@code{#f}を返します。
@c COMMON
@end defun

@defun sparse-table-delete! st key
@c MOD data.sparse
@c EN
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}.
@c JP
疎なテーブル@var{st}から、キー@var{key}を持つエントリを削除します。
エントリが実際に削除されたら@code{#t}お、エントリがもともと存在しなければ
@code{#f}を返します。
@c COMMON
@end defun

@defun sparse-table-clear! st
@c MOD data.sparse
@c EN
Empties @var{st}.
@c JP
疎なテーブル@var{st}を空にします。
@c COMMON
@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
@c EN
These are sparse-table version of @code{hash-table-update!},
@code{hash-table-push!}, and @code{hash-table-pop!}, respectively.
@xref{Hashtables}, for the details.
@c JP
これらはそれぞれ@code{hash-table-update!}、
@code{hash-table-push!}、@code{hash-table-pop!}の疎なテーブル版です。
詳しくは@ref{Hashtables}を参照してください。
@c COMMON
@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
@c EN
These are sparse-table version of @code{hash-table-fold},
@code{hash-table-for-each}, and @code{hash-table-map}, respectively.
@xref{Hashtables}, for the details.
@c JP
これらはそれぞれ@code{hash-table-fold}、
@code{hash-table-for-each}、@code{hash-table-map}の疎なテーブル版です。
詳しくは@ref{Hashtables}を参照してください。
@c COMMON
@end defun

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

@c ----------------------------------------------------------------------
@node Trie, Universally unique lexicographically sortable identifier, 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 alist-ref <> <> char-ci=? #f)
           (^[t k v]
             (if v
               (alist-set! t k v char-ci=?)
               (alist-delete! k t char-ci=?)))
           (^[t f s]
             (fold (^[e s] (f (car e) (cdr e) s)) 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 Universally unique lexicographically sortable identifier, Database independent access layer, Trie, Library modules - Utilities
@section @code{data.ulid} - Universally unique lexicographically sortable identifier
@c NODE 一意で辞書順ソート可能な識別子, @code{data.ulid} - 一意で辞書順ソート可能な識別子

@deftp {Module} data.ulid
@mdindex data.ulid
@c EN
This module implements ULID (@url{https://github.com/ulid/spec}), a UUID-like
unique identifier that can be sortable in chronological order and
has slightly more compact string representation.
@c JP
このモジュールは、@url{https://github.com/ulid/spec}
で定義されているULIDを実装します。
これはUUIDに似た一位な識別子ですが、生成順序と辞書順序が一致します。
また、UUIDよりもコンパクトな文字列表現を持ちます。
@c COMMON

@example
(define gen-ulid (make-ulid-generator))

(gen-ulid) @result{} #<ulid 01G70P3EWJT28VPQ12NTFFDSZ1>

(ulid->string (gen-ulid)) @result{} "01G70P3Y72TQ1HYY90G8TJSY07"
@end example

@c EN
NB: The new version of UUID RFC (RFC9562) contains a UUID version 7 which
has similar monotonic property of ULID, except the compact notation.
@xref{UUID}, for the details.
@c JP
註: 新しいUUID RFC (RFC9562)には、ULIDと同様の単調増加属性を持つUUID version 7
が含まれています。詳しくは@ref{UUID}を参照のこと。
@c COMMON
@end deftp

@defun make-ulid-generator :optional random-source
@mdindex data.ulid
@c EN
Creates and returns a generator that yields a fresh ULID object
every time it is called.  The optional @var{random-source} argument
is a SRFI-27 random source (@pxref{Sources of random bits})
to be used for the random part of ULID.  When omitted,
an internal random source is used.
@c JP
呼ばれるたびに新たなULIDオブジェクトを返すジェネレータを作って返します。
省略可能な@var{random-source}引数はSRFI-27の乱数源で、ULIDの乱数部を生成するのに
使われます (@ref{Sources of random bits}参照)。
省略された場合は内部の乱数源が使われます。
@c COMMON

@c EN
To guarantee uniqueness and monotonicity, a ULID generator needs to
keep internal state.  If you want to share the generator among multiple threads,
you need to manage your own lock.  Keeping the generator private in one
thread eliminates the need of mutex (however, monotonicity is only guaranteed
within each generator).
@c JP
一意性と単調増加特性を保証するために、ULIDジェネレータは内部に状態を保持しています。
作られたジェネレータを複数のスレッドで共有する場合は、呼び出し側で排他制御してください。
ジェネレータをひとつのスレッド内で使う限りにおいては排他制御のオーバヘッドを避けることができます
(ただ、単調増加特性はジェネレータごとにしか保証されません)。
@c COMMON

@c EN
A ULID consists of 48bit timestamp field (milliseconds since Unix epoch)
and 80bit randomness field.  The randomness field are generated randomly if
it is the first ULID within the timestamp.  If more than one ULID needs
to be generated in a millisecond window, the subsequent ULID gets randomness
field incremented from the previous ULID, so that the chronological order
is maintained.
@c JP
ULIDは48ビットのタイムスタンプ(Unixエポックからのミリ秒)と、80ビットのランダムネスフィールド
から成ります。ランダムネスフィールドはそのミリ秒の時刻で初めてULIDが生成される場合は
ランダムに埋められ、同じミリ秒内で2個め以降のULIDが生成される場合は前回の
ランダムネスフィールドをインクリメントしたものが使われます。
これによって生成順序と辞書順序が一致します。
@c COMMON

@c EN
The ULID spec says if the randomness field overflows because so many
ULIDs are generated within a millisecond, it is an error.  Such scenario
is very unlikely but can occur.  In our implementation, however, we wait for the
next millisecond boundary in case we ran out randomness field, so the generator
never yields an error.
@c JP
ULID仕様では、同じミリ秒内で多数のULIDが生成されたためにランダムネスフィールドがオーバーフロー
した場合はエラーとしています。それが起きる可能性は極めて小さいですが、起き得ることです。
Gaucheの実装では、ランダムネスフィールドがオーバーフローした場合は次のミリ秒まで待つことで、
エラーにならないようにしています。
@c COMMON
@end defun

@defun ulid? obj
@mdindex data.ulid
@c EN
Returns @code{#t} iff @var{obj} is an ULID object.
@c JP
@var{obj}がULIDオブジェクトなら@code{#t}を、そうでなければ@code{#f}を返します。
@c COMMON
@end defun

@defun ulid-timestamp ulid
@mdindex data.ulid
@c EN
Returns the timestamp part of @var{ulid} (48bits) as an exact integer.
@c JP
@var{ulid}のタイムスタンプ部(48bit)を正確な整数で返します。
@c COMMON
@end defun

@defun ulid-randomness ulid
@mdindex data.ulid
@c EN
Returns the randomess part of @var{ulid} (80bits) as an exact integer.
@c JP
@var{ulid}のランダムネス部(80bit)を正確な整数で返します。
@c COMMON
@end defun

@defun ulid=? ulid1 ulid2
@mdindex data.ulid
@c EN
Returns true if two ULIDs are equivalent.
@c JP
二つのULIDが等価であれば@code{#t}を、そうでなければ@code{#f}を返します。
@c COMMON
@end defun

@defun ulid<? ulid1 ulid2
@mdindex data.ulid
@c EN
Returns true if @var{ulid1} precedes @var{ulid2}.  If both ULIDs are
created from the same generator, this means @var{ulid1} is created
chronologically before @var{ulid2}.  If they are created from different
generators, the chronological order is not guaranteed, but the discrepancy
only occurs when two ULIDs are created at the same timestamp in
millisecond resolution.
@c JP
辞書順比較で@var{ulid1}が@var{ulid2}よりも小さければ@code{#t}を、
そうでなければ@code{#f}を返します。二つのULIDが同じジェネレータで
生成されていたなら、これは@var{ulid1}が@var{ulid2}より前に生成されたことを意味します。
二つが異なるジェネレータで生成されていた場合は、ミリ秒より小さな間隔において
生成順が辞書順とは異なっている可能性があります。
@c COMMON
@end defun

@defun ulid-hash ulid
@mdindex data.ulid
@c EN
Returns a hash value of @var{ulid} in a nonnegative exact integer.
@c JP
@var{ulid}のハッシュ値を非負の正確な整数で返します。
@c COMMON
@end defun

@defvar ulid-comparator
@mdindex data.ulid
@c EN
Bound to a comparator suitable to compare and hash ULIDs.
@c JP
ULIDの比較およびハッシュに使える比較器です。
@c COMMON
@end defvar

@defun ulid->bytevector ulid
@defunx bytevector->ulid uv
@mdindex data.ulid
@c EN
Covvert between @var{ulid} and a u8vector of length 16.  Bits are packed
in big-endian order (first 8 bits of timestamp to first byte, and
so on).
@c JP
@var{ulid}と長さ16のu8vector間の変換手続きです。
ビットはビッグエンディアンで格納されます(タイムスタンプの先頭8ビットが最初のバイト、等)。
@c COMMON
@end defun

@defun ulid->integer ulid
@defunx integer->ulid n
@mdindex data.ulid
@c EN
Convert between @var{ulid} and an exact nonnegative integer up to 128bit.
@c JP
@var{ulid}と非負の正確な128ビット整数との間の変換手続きです。
@c COMMON
@end defun

@defun ulid->string ulid
@defunx string->ulid str
@mdindex data.ulid
@c EN
Convert @var{ulid} to a string of Base32 representation; the
digits are @code{0123456789ABCDEFGHJKMNPQRSTVWXYZ} (@code{I}, @code{L},
@code{O}, and @code{U} are excluded to avoid confusion).  Length of
the string is always 26.
@c JP
@var{ulid}とそのBase32文字列表現との間の変換手続きです。
エンコードディジットには@code{0123456789ABCDEFGHJKMNPQRSTVWXYZ}が使われます
(@code{I}、@code{L}、@code{O}、@code{U}は混乱を避けるために使われません)。
文字列の長さは常に26です。
@c COMMON

@c EN
@code{ulid->string} always use uppercase characters; on the other hand,
@code{string->ulid} allows both lowercase and uppercase characters.
@c JP
@code{ulid->string}は常に大文字を使います。
一方、@code{string->ulid}は小文字も大文字も受け付けます。
@c COMMON
@end defun

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

@node Database independent access layer, Generic DBM interface, Universally unique lexicographically sortable identifier, 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-filter-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, Mathematical 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 :key if-does-not-exist
@defunx delete-directory* name :key if-does-not-exist
@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

@c EN
The keyword argument @var{if-does-not-exist} must be either
@code{:error} (default) or @code{#f}.  If it is @code{:error},
an error is signaled if @var{name} does not exist.
If it is @code{#f}, the procedure just returns in such a case.
@c JP
キーワード引数@var{if-does-not-exist}は、@code{:error} (デフォルト) か
@code{#f} でなければなりません。
@code{:error}の場合、@var{name}が存在しなければエラーが投げられます。
@code{#f}の場合、@var{name}が存在しなければ手続きは何もせずに返ります。
@c COMMON

@c EN
An error is thrown when @var{name} exists but is not a directory.
You can use @code{remove-files} to remove both files and directories.
@c JP
@var{name}が存在し、ディレクトリでない場合はエラーが投げられます。
ディレクトリでもファイルでも削除したい場合は@code{remove-files}が使えます。
@c COMMON
@end defun

@defun remove-empty-directory* path
@c EN
If @var{path} is a directory, recursively walk down and remove any
empty directories.  If removing subdirectories caused a directory to be
empty, the directory is also removed; i.e. if @var{path} is a directory
tree which contains no regular files, the entire tree, including @var{path},
is removed.

If @var{path} contains regular files, those files and the directories to
get to them are retained.

If @var{path} isn't a directory or does not exist, no-op.
@c JP
@var{path}がディレクトリなら、それを再帰的に下降し、空のディレクトリを消去します。
その結果として空になったディレクトリがあればそれも消去します。すなわち、@var{path}
が通常のファイルを全く含まないディレクトリツリーを指していたなら、@var{path}自身を含め
全てのディレクトリが消去されます。

@var{path}の指すディレクトリツリーの中に通常のファイルがあった場合、
そのファイルとそこに至るまでのディレクトリは残されます。

@var{path}が存在しない、あるいはディレクトリでなかった場合は何もしません。
@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} @dots{} to the @var{base-path}.
This takes care of platform-specific pathname separators.
@c JP
パス名のコンポーネント@var{component} @dots{}を@var{base-path}に追加します。
パスの区切り文字は、プラットフォームに合ったものが選択されます。
@c COMMON

@c EN
@var{Base-path} can be a directory name, @code{#f}, or a symbol @code{cwd} or
@code{cld}.  If it is @code{#f}, @code{"."} is used.
If it is @code{cwd}, the current working directory
is used.  If it is @code{cld}, the directory of the current loading
file is used
(@code{current-load-path}, @pxref{Loading Scheme file}).
If there's no current loading file (e.g. calling
from REPL), the current working directory is used instead.
@c JP
@var{base-path}には、ディレクトリ名か、@code{#f}、
あるいはシンボル@code{cwd}もしくは@code{cld}を渡すことができます。
@code{#f}は@code{"."}と同じです。
@code{cwd}の場合は現在のディレクトリ(current working directory)
が使われます。@code{cld}の場合は現在のファイルをロードしているディレクトリ
(current loading directory)が使われます。
(@code{current-load-path}, @ref{Loading Scheme file}参照)。
但し、コードがファイルからロードされてたので
ない場合(REPLから呼び出した場合など)は、現在のディレクトリが代わりに使われます。
@c COMMON

@c EN
Note that the current loading directory is looked up at the time
@code{build-path} is called.  It may not the directory where the
actual source file is in, if @code{build-path} is called after loading
is completed.
@c JP
現在のロードディレクトリは@code{build-path}が呼ばれた時に調べられることに注意して下さい。
@code{build-path}がロード終了後に呼ばれる場合は、それはそのソースが置かれた
ディレクトリではないかもしれません。
@c COMMON

@c EN
@var{Component} can be a string, @code{#f}, or
a symbol @code{same} or @code{up}.  The latter three
are interpreted as @code{"."}, @code{"."}, and @code{".."}, respectively.
They are appended to @var{base-path}.
(The symbol @code{same} and @code{up} are taken from MzScheme).
@c JP
パス名のコンポーネント@var{component}は、文字列、
@code{#f}、あるいはシンボル@code{same}または@code{up}です。
後3者はそれぞれ@code{"."}、@code{"."}、@code{".."}と解釈されます。
@var{components}は@var{base-path}の後に追加されます。
(@code{same}と@code{up}は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.
If you anticipate your code runs on Windows as well, make sure to close
the output port before renaming.  Windows does not allow you to rename
an opened file.

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}引数を指定するのを忘れないように。
ファイルシステムをまたぐリネームはうまくいかない場合があります。
また、コードがWindows上でも使われる可能性がある場合は、
リネームする前に出力ポートを閉じてください。
Windowsではオープンされているファイルはリネームできません。

内部的に、この手続きは@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 Mathematical constants, Mersenne-Twister random number generator, Filesystem utilities, Library modules - Utilities
@section @code{math.const} - Mathematical 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} π
@defvrx {Constant} 2pi
@defvrx {Constant} 2π
@defvrx {Constant} pi/2
@defvrx {Constant} π/2
@defvrx {Constant} pi/4
@defvrx {Constant} π/4
@defvrx {Constant} pi/180
@defvrx {Constant} π/180
@defvrx {Constant} 1/pi
@defvrx {Constant} 1/π
@defvrx {Constant} 180/pi
@defvrx {Constant} 180/π
@c MOD math.const
@c EN
Bound to constants computed with π.
@c JP
πから計算される定数値に束縛されています。
@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, Mathematical 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
(@pxref{Sources of random bits}).
You should use this module directly only when you need
functions that aren't available through @code{srfi.27}.
@c JP
乱数発生器の通常の用途には、@code{srfi.27}を使うことをお勧めします
(@ref{Sources of random bits}参照)。
@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.
@c JP
Mersenne Twister RNGの状態をカプセル化するクラスです。
このクラスのそれぞれのインスタンスは独自の状態を持ち、
個別のシードで初期化されていれば、それぞれがランダムビットの
独立したソースになり得ます。
@c COMMON
@end deftp

@defun make-mersenne-twister :optional seed private?
@c MOD math.mt-random
@c EN
Creates and returns a new @code{<mersenne-twister>} RNG instance.

If @var{seed} argument is given, it must be either nonnegative exact
integer, u32vector, or @code{#f}.  The key can be any length.

If @var{seed} is omitted or @code{#f}, the RNG is initialized to the fixed value,
so that it generates the same sequences of random numbers.  If you want
different sequence for each instance, you have to give different seeds
explicitly, or initialize each instance with different seeds using
@code{mt-random-set-seed!} below.
@c JP
新たな@code{<mersenne-twister>}のインスタンスを作って返します。

@var{seed}引数が与えられたなら、それは任意の正確な非負整数か、
@code{u32vctor}でなければなりません。キーの長さに制限はありません。

@var{seed}が省略されるか@code{#f}の場合、RNGは固定の種で初期化されるので、
そのままだと常に同じ乱数列を生成します。
インスタンス毎に異なる乱数列が必要なら、明示的に異なる種を渡すか、
下の@code{mt-random-set-seed!}で種を設定してください。
@c COMMON

@c EN
By default, the created RNG is thread-safe; you can call the generator
from multiple thread without worrying to break its internal state.

However, if you know you only use it in a single thread, or you use
separate mutex and know the generator call is alyways protected, then
you can give a true value to @var{private?} optional argument to avoid
overhead of locking.
@c JP
デフォルトでは、作られるRNGはスレッドセーフです。
すなわち、複数のスレッドからジェネレータを呼んでも内部状態を壊してしまうことはありません。

ただ、RNGを一つのスレッドからしか使わないとか、他のロックで常に排他された環境でしか
呼ばないということがわかっているなら、@var{private?}引数に真の値を渡すことができます。
その場合、RNGはロックを省略します。
@c COMMON

@example
(define m (make-mersenne-twister (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 defun

@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}).
@c JP
メルセンヌツイスターRNG @var{mt}にランダムシードの値@var{seed}をセットします。
@var{seed}は任意の正の正確整数か、任意長のu32vector
(@ref{Homogeneous vectors}参照)が使えます。
@c COMMON

@c EN
Internally, MTRNG keeps its state in an array of 624 32-bit integers.
If the given seed is small (e.g. fixnum), it can't create enough
variations.  Particularly, if the seed is within 32bits, it can be
computed by sampling a couple of result from MTRNG.  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ビット整数624個の配列を内部状態として持っています。
シード値が小さい場合(例: fixnum)、充分なバリエーションを作ることができません。
特に、シード値が32ビットに収まる場合、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-seed mt
@c MOD math.mt-random
@c EN
Returns the last seed value used to initialize Mersenne Twister RNG @var{mt}.
It is either an exact integer or u32vector.
If @var{mt} has never been initialized, @code{#<undef>} is returned.
@c JP
Mersenne Twister RNG @var{mt}を初期化するのに使われたシード値を返します。
複数回初期化されている場合は、最後に初期化されたものを返します。
シード値は正確な整数かu32vectorです。
初期化されたことがなければ、@code{#<undef>}が返されます。
@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, Simplex solver, 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 remain 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.   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法を用いて判定します。
このアルゴリズムは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}.
@c JP
この方法は極めてナイーブなものですが、目安としてどの素因数も@code{1e7}程度以下であれば
それなりに使えます。
@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{https://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{https://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 take very long time, and possibly give
up factorization and the result may contain a possibly composite numbers.
@c JP
この手続きは@code{naive-factorize}よりも大きな数に使えます
(目安としては1e20程度まで)。

アルゴリズムは確率的なので、同じ@var{n}に対しても実行時間はばらつきますが、
@var{n}の素因数が全て2^64より小さければ、かならず確定的な答えを返します。

今のところ、@var{n}が2^64以上の素因数を含んでいる場合、この手続きは
非常に長くかかり、また結果には合成数かもしれない要素が含まれます。
@c COMMON
@end defun

@defun grouped-factorize n :optional factorizer
@c EN
Factorize @var{n}, and returns
@code{((p_1 . k_1) ... (p_n . k_n))}, where
@code{n = p_1^@{k_1@} * ... * p_n^@{k_n@}}.
The actual factorization is done by @var{factorizer}, whose
default is @code{mc-factorize}.
@c JP
@var{n}を素因数分解し、結果を@code{((p_1 . k_1) ... (p_n . k_n))}の
形で返します。ここで@code{n = p_1^@{k_1@} * ... * p_n^@{k_n@}}です。
実際の素因数分解は@var{factorizer}が行います。省略時には
@code{mc-factorize}が使われます。
@c COMMON

@example
(grouped-factorize 636787224)
 @result{} ((2 . 3) (3 . 3) (17 . 2) (101 . 2))
@end example
@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{https://en.wikipedia.org/wiki/Jacobi_symbol}).
@c JP
Jacobi symbol @code{(@var{a}/@var{n})} を計算します
(@url{https://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}.
@code{(totient n)} returns a number of positive integers upto @var{n}
that are relatively prime to @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{(totient n)}は、0以上@var{n}以下の整数で@var{n}と互いに素な
整数の数を返します。

現在の実装は上の@code{mc-factorize}を使っており、
@var{n}が大きな素因数を持っている場合は非常に長い時間がかかります。
@c COMMON
@end defun

@defun reduced-totient n
@c MOD math.prime
@c EN
A reduced totient function, a.k.a. Carmichael function,
returns the smallest positive integer @var{m} such that
@code{(expt-mod a m n)} equals to 1 for every @var{a}
relatively prime to a positive integer @var{n}.

When @var{n} is 1 or prime numbers, it is the same as @code{(totient 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}と互いに素なあらゆる@var{a}について
@code{(expt-mod a m n)}が1となるような最小の正の整数@var{m}を返します。

@var{n}が1か素数の場合は@code{(totient n)}と同じ数になります。

現在の実装は上の@code{mc-factorize}を使っており、
@var{n}が大きな素因数を持っている場合は非常に長い時間がかかります。
@c COMMON
@end defun


@c ----------------------------------------------------------------------
@node Simplex solver, Windows support, Prime numbers, Library modules - Utilities
@section @code{math.simplex} - Simplex solver
@c NODE シンプレックスソルバー, @code{math.simplex} - シンプレックスソルバー

@deftp {Module} math.simplex
@mdindex math.simplex
@c EN
Implements the simplex algorithm to solve linear programming problems.
@c JP
線形計画問題をシンプレックス法で解く実装です。
@c COMMON
@end deftp

@defun simplex-solve A b goal c
@c MOD math.simplex
@c EN
@var{A} is an m x n array of numbers, @var{b} is a sequence of
m numbers, @var{c} is a sequence of n numbers,
and @var{goal} is either @code{:maximize} or @code{:minimize}.
Returns an f64vector @var{x} of length n,
such that it maximizes or minimizes
the inner product @var{c} . @var{x}, while satisfying
the constraint @code{A}@var{x} <= @var{b} and @var{x} >= 0.
@c JP
@var{A}は m x n の数値配列、@var{b}は @var{m}個の数値のシーケンス、
@var{c}は@var{n}個の数値のシーケンスで、また@var{goal}は
@code{:maximize}か@code{:minimize}です。
この手続きは次の制約を満たす長さnのf64vectorである@var{x}を返します:
制約条件 @code{A}@var{x} <= @var{b} および @var{x} >= 0 のもとで、
内積 @var{c} . @var{x} が最大値もしくは最小値を取る@var{x}。
@c COMMON

@c EN
The array can be any type of arrays (@pxref{Arrays}) and the
two sequences can be any type of sequence, as far as they only
contain real numbers.  Internally it uses @code{f64vector} and
@code{f64array} for calculation.
The arguments aren't mutated during computation.
@c JP
配列と2つのシーケンスは、全ての要素が数値でさえあればどんな型でも渡せます
(配列については@ref{Arrays}参照)。内部的には、@code{f64vector}と
@code{f64array}が計算に使われます。
引数に渡した配列とシーケンスは変更されません。
@c COMMON

@c EN
You can have negative entries in @var{b}; the procedure uses two-phase
simplex method in that case.
@c JP
@var{b}の要素は負であっても構いません。負の数がある場合、この手続きは
2-phaseシンプレックス法を使います。
@c COMMON

@c EN
If you have a '>=' constraint, you can negate both sides to make it a '<='
constraint.  If you have an equality in the constraint, you can either
use it to reduce one variable, or add both '>=' and '<=' constraints.
@c JP
制約が「定数項以上」である場合は、両辺の符号を反転して「定数項以下」の制約にしてください。
等しい制約がある場合は、あらかじめその関係を使って変数を減らすか、
「定数項以上」と「定数項以下」の制約を同時に与えることで解けます。
@c COMMON

@c EN
If there can be multiple solutions, the procedure returns one of them.
If there's no solutions, it returns @code{#f}.
@c JP
複数の解がある場合はどれか一つが返されます。
解が無い場合は@code{#f}が返されます。
@c COMMON

@example
;; Maximize x1 + x2 under constraints of
;;     x1 + 0.5*x2 <= 2.0   and
;;   3*x1 +   2*x2 <= 12.0

(simplex-solve '#2a((1 0.5) (3 2))
               '#f64(2.0 12.0)
               :maximize '#(1 1))

  @result{} #f64(0.0 4.0)
@end example
@end defun

@c ----------------------------------------------------------------------
@node Windows support, PEG parser combinators, Simplex solver, Library modules - Utilities
@section @code{os.windows} - Windows support
@c NODE Windowsのサポート, @code{os.windows} - Windowsのサポート

@deftp {Module} os.windows
@mdindex os.windows
@c EN
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.
@c JP
このモジュールはWindowsネイティブのGaucheにのみあり、
Windows特有の機能を提供します。
@code{cond-expand}マクロで@code{gauche.os.windows}機能特定子を使うことにより、
Windows特有の機能をコードに含めることができます
(@ref{Feature conditional}参照)。
@c COMMON

@example
(cond-expand
  [gauche.os.windows
   (use os.windows)
   ... Windows-specific code ...]
  [else
   ... Unix code ...])
@end example

@c EN
Unless otherwise noted,
when Windows API returns an error value, a @code{<system-error>} condition
is thrown.
@c JP
特に記述のない場合、Windows APIがエラーを返した場合には
@code{<system-error>}コンディションが投げられます。
@c COMMON
@end deftp

@menu
* Windows dialogs::
* Windows console API::
@end menu

@node Windows dialogs, Windows console API, Windows support, Windows support
@subsection Windows dialogs
@c NODE Windowsアイアログ

@c EN
Currenly we only have MessageBox API.
@c JP
今のところ、MessageBoxが使えます。
@c COMMON

@defun sys-message-box window message :optional caption flags
@c MOD os.windows
@c EN
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.
@c JP
WindowsのMessageBox APIを呼びます。
@var{window}はウィンドウハンドルか@code{#f}でなければなりませが、
今のところウィンドウハンドルを得るAPIがないので、常に@code{#f}を渡してください。
@var{message}引数はメッセージボックスに表示する文字列です。
省略可能な@var{caption}引数はウィンドウタイトルに使われる文字列です。

@var{flags}引数は以下に挙げる定数を@code{logior}で組み合わせた整数です。
詳しくはWindowsのリファレンスマニュアルを参照してください。
@c COMMON

@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
@c EN
Default is no icon.  Possible values:
@c JP
デフォルトはアイコン無し。指定可能な値は:
@c COMMON
@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

@c EN
Return value is one of the following integer constants,
indicating which button is pressed:
@c JP
戻り値は、どのボタンが押されたかを示す次の整数値のいずれかです。
@c COMMON
@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
@c NODE WindowsコンソールAPI

@c EN
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.
@c JP
以下のほとんどの手続きはWindowsコンソールAPIと1対1対応しています。
詳しくはWindows APIの対応するドキュメントを参照してください。
@c COMMON

@c EN
@subsubheading Attaching and detaching
@c JP
@subsubheading アタッチとデタッチ
@c COMMON

@defun sys-alloc-console
@defunx sys-free-console
[Windows]
@c MOD os.windows
@c EN
Calls @code{AllocConsole} and @code{FreeConsole}, respectively.
Returns an undefined value.
@c JP
それぞれ、@code{AllocConsole}と@code{FreeConsole}を呼びます。
未定義値を返します。
@c COMMON
@end defun

@defun sys-generate-console-ctrl-event event pgid
[Windows]
@c MOD os.windows
@c EN
Calls @code{GenerateConsoleCtrlEvent}.  For @var{event} argument,
the constants @code{CTRL_C_EVENT} and @code{CTRL_BREAK_EVENT} are available.
@c JP
@code{GenerateConsoleCtrlEvent}を呼びます。
@var{event}引数には@code{CTRL_C_EVENT}か@code{CTRL_BREAK_EVENT}を指定できます。
@c COMMON
@end defun

@defvr {Constant} CTRL_C_EVENT
@defvrx {Constant} CTRL_BREAK_EVENT
[Windows]
@c MOD os.windows
@c EN
Constants to be used for @var{event} argument of
@code{sys-generate-console-ctl-event} above.
@c JP
@code{sys-generate-console-ctl-event}の@var{event}引数に渡せる定数です。
@c COMMON
@end defvr

@c EN
@subsubheading Console codepage
@c JP
@subsubheading コンソールコードページ
@c COMMON

@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
@c EN
Call @code{GetConsoleCP}, @code{GetConsoleOutputCP},
@code{SetConsoleCP}, and @code{SetConsoleOutputCP}, respectively.
Setter procedures returns an undefined value.
@c JP
それぞれ、@code{GetConsoleCP}、@code{GetConsoleOutputCP}、
@code{SetConsoleCP}、@code{SetConsoleOutputCP}を呼びます。
値をセットする手続きは未定義値を返します。
@c COMMON
@end defun

@c EN
@subsubheading Console cursor
@c JP
@subsubheading コンソールカーソル
@c COMMON

@defun sys-get-console-cursor-info handle
@defunx sys-set-console-cursor-info handle size visible
[Windows]
@c MOD os.windows
@c EN
Call @code{GetConsoleCursorInfo} and @code{SetConsoleCursorInfo},
respectively.  @var{Handle} is a handle to the console screen buffer
(see @code{sys-create-console-screen-buffer} blow).
The getter returns two values, size (the integer
percentage of the character cell that is filled by the cursor,
between 1 and 100), and a boolean visible flag.
The setter takes a handle to the console screen buffer,
integer size percentage, and boolean visible flag.  It returns
an undefined value.
@c JP
それぞれ、@code{GetConsoleCursorInfo}と@code{SetConsoleCursorInfo}を呼びます。
@var{handle}はコンソールスクリーンバッファのハンドルです
(下の@code{sys-create-console-screen-buffer}を参照)。
@code{sys-get-console-cursor-info}はカーソルのサイズ
(カーソルがどのくらいセルを覆うかのパーセンテージ、1から100)および
カーソルが見えているかどうかの真偽値を2つの値として返します。
@code{sys-set-console-cursor-info}はカーソルのサイズパーセンテージと
可視かどうかの真偽値を取ってセットし、未定義値を返します。
@c COMMON
@end defun

@defun sys-set-console-cursor-position handle x y
[Windows]
@c MOD os.windows
@c EN
Calls @code{SetConsoleCursorPosition}.
@var{Handle} is a handle to the console screen buffer
(see @code{sys-create-console-screen-buffer} blow).
@var{X} and @var{y} are cursor coordinates in character position,
where (0, 0) is the upper-left corner of the console screen buffer.
It returns an undefined value.

To get the current cursor position, you can use
@code{sys-get-console-screen-buffer-info}.
@c JP
@code{SetConsoleCursorPosition}を呼びます。
@var{handle}はコンソールスクリーンバッファのハンドルです
(下の@code{sys-create-console-screen-buffer}を参照)。
@var{x}と@var{y}は文字単位のカーソル位置で、スクリーンバッファ左上端が(0, 0)です。
未定義値を返します。

現在のカーソル位置を得るには
@code{sys-get-console-screen-buffer-info}が使えます。
@c COMMON
@end defun

@c EN
@subsubheading Console mode
@c JP
@subsubheading コンソールモード
@c COMMON

@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

@c EN
@subsubheading Screen buffer
@c JP
@subsubheading スクリーンバッファ
@c COMMON

@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

@c EN
@subsubheading Console input/output
@c JP
@subsubheading コンソール入出力
@c COMMON

@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

@c EN
@subsubheading Standard handles
@c JP
@subsubheading 標準ハンドル
@c COMMON

@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 it is just an ordinary procedure
and not like a control-transfer syntax as 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 doesn'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 to @var{cont}.
@c JP
@var{cont}にそれ以外の値を渡すのはエラーです。
@c COMMON
@end defun

@defun peg-parser->generator parser list
@c MOD parser.peg
@c EN
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.
@c JP
パーザ@var{parser}を入力@var{list}に繰り返し適用したい場合に便利です。
マッチした入力をひとつづつ返すジェネレータを作って返します。
@c COMMON

@c EN
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.  On the other hand,
@c JP
@code{(peg-run-parser ($many parser) list)}としても同じ入力が受容されますが、
こうした場合は全ての入力が消費されるまで戻ってきません。
@c COMMON
@end defun

@deftp {Condition type} <parse-error>
@c MOD parser.peg
@c EN
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.)
@c JP
パーザが最終的に失敗した場合にパーザドライバが投げるコンディション型です。
@code{<error>}を継承します。
(各パーザがこのコンディションを投げることはありません。
一つのパーザが失敗したとしても、他の選択肢が成功するかもしれないからです。
最終的な失敗を認識してこのコンディションを投げるのはドライバの仕事です。)
@c COMMON

@c EN
The following slots are available:
@c JP
以下のスロットを持ちます。
@c COMMON

@defivar <parse-error> message
@c EN
This slot is inherited from @code{<error>}.  Contains string error message.
@c JP
@code{<error>}から継承されたスロットで、エラーメッセージを保持しています。
@c COMMON
@end defivar

@defivar <parse-error> position
@c EN
The position the failure occured.
@c JP
失敗が起きた入力の場所です。
@c COMMON

@c EN
The exact meaning of this value depends on how you call the parser driver.
@c JP
この値の正確な意味は、パーザドライバがどう呼ばれたかに依存します。
@c COMMON

@c EN
At minimum, when you call it on a bare list or a string/port (using
@code{peg-parse-string}/@code{peg-parse-port}), the parser driver
counts the number of elements took from the input and put it here,
for it is the only available information.  Note that the number
may not be what you want, e.g. if you start parsing in the middle of
the stream.
@c JP
パーザドライバに普通のリストや、@code{peg-parse-string}/@code{peg-parse-port}を
使って文字列/ポートを渡した場合、パーザドライバは入力の先頭から失敗箇所までの
入力要素の数を数えてそれをこの値とします。それしか情報が無いからです。
入力の途中からパーズを始めた場合などでは、この数値はあなたが必要としているものとは
異なるかもしれません。
@c COMMON

@c EN
If you're parsing from a sequence with positions,
this slot contains an instance of @code{<sequence-position>}, which
may have line & column numbers or a source file name.
@xref{Lazy sequence with positions}, for the details.
@c JP
位置情報つきシーケンスを入力として渡していれば、このスロットは@code{<sequence-position>}
のインスタンスを保持し、そこから行番号、カラム番号、ソースファイル名などを
取り出すことができます。
詳しくは@xref{Lazy sequence with positions}を参照してください。
@c COMMON

@c EN
The user code should expect both cases.
@c JP
ユーザコードはどちらの場合にも対応できるようにしておかねばなりません。
@c COMMON
@end defivar

@defivar <parse-error> type
@c EN
The type of failure.  It's either one of the follownig symbols:
@c JP
失敗のタイプ。次のいずれかのシンボルです。
@c COMMON
@table @code
@item fail-expect
@c EN
The parser expects one of the objects in @var{objects} slot, but
got a different one (stored in @var{token}).
@c JP
パーザは@var{objects}スロットに格納されたオブジェクトのどれかを期待していたが、
入力はそうでないオブジェクトであった (入力オブジェクトは@var{token}スロットに格納される)。
@c COMMON
@item fail-unexpect
@c EN
The parser isn't expecting any of the objects in @var{objects} slot,
but got the one in @var{token}.
@c JP
パーザは@var{object}スロットに格納されたオブジェクトのいずれも期待していなかったが、
入力はそのいずれかであった (入力オブジェクトは@var{token}スロットに格納される)。
@c COMMON
@item fail-compound
@c EN
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.
@c JP
パーザは複数の選択肢を試しいずれも失敗した。@var{objects}スロットは
@code{(type . msg)}のリストを保持している。ここで@var{type}は一つの選択肢の
失敗の@code{<parse-error>}タイプ、@var{msg}はその選択肢の失敗メッセージ。
@c COMMON
@item fail-message
@c EN
Other miscellaneous failure.  The @var{objects} slot contains
a mmessage.
@c JP
その他の失敗。@var{message}スロットにメッセージがある。
@c COMMON
@item fail-error
@c EN
Non-recoverable failure.  Once this failure is generated, parser
conbinators don't backtrack and let the entire parsing fail.
This type of failure can be generated by @code{$rause} parser constructor
and @code{$cut} combinator.  The @var{objects} slot contains a cons
whose car is a symbol (@emph{error tag}) and whose cdr is
a list of @code{(type . msg)}. The cdr part is the same as
@code{fail-compound}.
@c JP
回復不能な失敗。この失敗が生成されると、パーザコンビネータは巻き戻して
別の選択肢を試すことをせず、全体のパージングを失敗させます。
このタイプの失敗は@code{$raise}パーザコンストラクタや@code{$cut}パーザコンビネータで
生成されます。@var{object}スロットはコンスセルで、carにはシンボル (エラータグ) が、
cdrには@code{(type . msg)}のリストが入っています。cdr部分は
@code{fail-compound}の@var{object}スロットと同じです。
@c COMMON
@end table
@end defivar

@defivar <parse-error> objects
@c EN
Value of this slot depends on the value of @var{type} slot.
@c JP
このスロットの値の意味は@var{type}スロットの値に依存します。
@c COMMON
@end defivar

@defivar <parse-error> rest
@c EN
The remaining input token stream, beginning from the point when
the failure occur.
@c JP
失敗が起きた箇所から先の入力トークンストリーム。
@c COMMON
@end defivar

@defivar <parse-error> token
@c EN
The token at the head of input when failure occur.  If input already
reached at the end, this slot is set to @code{#<eof>}.

This is the same as the car of @code{rest} slot when there's more input.
@c JP
失敗が起きた時の入力トークン。もし入力が終端に達していた場合は@code{#<eof>}。

入力の残りがある場合、これは@code{rest}スロットのcarと同じです。
@c COMMON
@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?
@c NODE PEGパーザの正体

@c EN
A PEG parser is a Scheme procedure that takes a list of items as an input,
and returns three values:
@c JP
PEGパーザは、入力にリストを取り、以下の3つの値を返す手続きです。
@c COMMON

@itemize
@item
@c EN
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.
@c JP
失敗のタイプ。パーザが入力を受理することに成功した場合、この値は@code{#f}です。
失敗した場合は、この値は次のシンボルのうちのいずれかです:
@code{fail-expect}、@code{fail-unexpect}、@code{fail-compound}、
@code{fail-message}。これは@code{<parse-error>}オブジェクトの
@code{type}スロットの値に対応します。二番目の戻り値の意味はこの値に依存します。
@c COMMON
@item
@c EN
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}).
@c JP
値。パーザが入力の受理に成功した場合は、これはパーザの「結果」、
しばしばセマンティックバリューと呼ばれるものです。
パーザが失敗した場合は、この値は失敗の原因のヒントとなるものです。
@code{<parse-error>}オブジェクトの@code{objects}スロットの値に対応します。
詳しくは@code{<parse-error>}のドキュメントを見てください
(@ref{PEG parser drivers}参照)。
@c COMMON
@item
@c EN
The rest of the input list.
@c JP
入力の残り。
@c COMMON
@end itemize

@c EN
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.
@c JP
通常、パーザを手続きとして書くことはあまりありません。
以降の節で説明するパーザビルダやコンビネータを使ってパーザを作ります。
@c COMMON

@c EN
We do provide a few utilities to write a parser from scratch, in case
you need to do so.
@c JP
しかし、パーザ手続きを一から書く必要が出てきた時のために、
いくつかのユーティリティ手続きが用意してあります。
@c COMMON

@defun return-result value rest
@c MOD parser.peg
@c EN
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.
@c JP
パーザが入力の受理に成功した時は、この手続きを末尾位置で呼んでください。
@var{value}はパーザが返すセマンティックバリュー、
@var{rest}は入力の残りです。これは@code{(values #f value rest)}と同じですが、
意図をより明確に示すことができます。
@c COMMON
@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
@c EN
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>}.
The second argument should be a list of input, with the first element
being a token that can't be accepted.
@c JP
パーザが入力を受理できなかった場合は、この手続きのいずれかを末尾位置で呼んでください。
最初の引数は@var{<parse-error>}の@code{objects}スロットの値となります。
2番目の引数は、受理できなかったトークンを先頭とする入力リストです。
@c COMMON

@itemize
@item
@c EN
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.
@c JP
限られた種類のオブジェクト (@var{objs}) を期待していて、それ以外の入力に
出会った場合は、@code{return-failure/expect}を呼んでください。これは
@code{fail-expect}タイプの失敗となります。
@c COMMON
@item
@c EN
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
@c JP
限られた種類のオブジェクト (@var{objs}) 以外のものを期待していたのに、
それに出会ってしまった場合は、@code{return-failure/unexpect}を呼んでください。
これは@code{fail-unexpect}タイプの失敗となります。
@c COMMON
@item
@c EN
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.
@c JP
複数の選択肢があってそのいずれにも失敗した場合は、
全ての失敗を@code{((fail-type . objs) @dots{})}の形の連想リストにして、
それを@var{fails}引数として@code{return-failure/compound}を呼んでください。
これは@code{fail-compound}タイプの失敗となります。
@c COMMON
@item
@c EN
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.
@c JP
失敗が上記いずれにもあてはまらない場合は、失敗の理由を文字列のメッセージにして
@code{return-failure/message}を呼んでください。
@c COMMON
@end itemize
@end defun

@defun return-failure type objs rest
@c MOD parser.peg
@c EN
This should only be used to pass down the failure form other parser.
See the example in @code{parse-success?} entry below.
@c JP
これは他のパーザからの失敗をそのまま失敗として返す場合にのみ使ってください。
下の@code{parse-success?}の説明を参照のこと。
@c COMMON
@end defun


@defun parse-success? r
@c MOD parser.peg
@c EN
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:
@c JP
パーザの最初の戻り値が成功であるかどうかを調べます。
典型的な使い方は、他のパーザの結果によって分岐する場合です:
@c COMMON

@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

@c EN
This is simply checking if @var{r} is @code{#f}, but using this
procedure indicates your intention clearly.
@c JP
この手続きは単に@var{r}が@code{#f}かどうか見ているだけですが、
これを使うことにより意図を明確に示すことができます。
@c COMMON
@end defun


@node PEG primitive parser builders, PEG ropes, What is a PEG parser, PEG parser combinators
@subsection Primitive parser builders
@c NODE 基本的なパーザビルダー

@c EN
Procedures and macros that create parsers.
@c JP
パーザを作り出す手続きとマクロです。
@c COMMON

@defun $return val
@c MOD parser.peg
@c EN
Returns a parser that always succeeds, without consuming
input, and yields @var{val} as the result of parser.
@c JP
入力を消費せず、常に成功して@var{val}を結果として返すパーザを作って返します。
@c COMMON

@c EN
Frequently used in @code{$let} and @code{$let*}'s body, but can be
used anywhere where a parser is expected.
@c JP
@code{$let}や@code{$let*}の本体で使われることが多いですが、
パーザを期待するところではどこでも使えます。
@c COMMON
@end defun

@defun $fail msg-string
@c MOD parser.peg
@c EN
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.
See also @code{$expect} below.
@c JP
入力を消費せず、常に失敗して、@var{msg-string}を失敗メッセージとするパーザを
作って返します。

ユーザフレンドリなエラーメッセージを出すためによく使われます。
下の@code{$expect}も参照してください。
@c COMMON
@end defun

@defun $raise msg-string
@c MOD parser.peg
@c EN
Returns a parser that raises a non-recoverable failure.
with @var{msg-string} as the failure message.

The difference from @code{$fail} is that, if @code{$or} sees
a failure created by @code{$fail}, it may try the remaining
branches, while if it sees a failure created by @code{$raise},
no more branches are tried.

This can be used for better error reporting.
If you detect the case that can't be a valid input in deep in the
parse tree, a normal failure would try other alternatives exhaustively
and generate an error message itemizing all the failed possibilities.
It is often difficult to see the real cause from such a message.
With @code{$raise}, you can let the parser give up immediately.

See also @code{$cut} combinator below, to convert a normal failure to
non-recoverable failure.
@c JP
回復不可能な失敗を生成するパーザを作って返します。
@var{msg-string}は失敗のメッセージに使われます。

@code{$fail}との違いは、@code{$or}が@code{$fail}で生成された失敗を見た場合は
他の選択肢を試すことがあるのに対し、@code{$raise}で生成された失敗を見たら
他の選択肢はもう試されないことです。

これはより良いエラー報告をするのに役立ちます。
パーズツリーの深いところで、有効になり得ない入力を検出したとします。
通常の失敗とした場合、パーザはツリーの上の方で他の選択肢も全部試し、
失敗の理由をすべて列挙したエラーメッセージを生成するかもしれません。
しかし多くの場合、そのメッセージから本当の失敗の原因を知るのは難しいです。
@code{$raise}を使えば、パーザに即座に諦めさせることができます。

通常の失敗を回復不可能な失敗に変換する、下の@code{$cut}コンビネータも参照してください。
@c COMMON
@end defun

@defun $satisfy pred expect :optional result
@c MOD parser.peg
@c EN
This corresponds to ``semantic predicate'' in PEG; a parser
that can apply an arbitrary predicate on input.
@c JP
これはPEGでいう「先読み述語」、つまり
入力トークンに任意の述語@var{pred}を適用するパーザを作って返します。
@c COMMON

@c EN
Returns a parser that works as follows:
@c JP
返されるパーザは次のように動作します。
@c COMMON
@itemize @bullet
@item
@c EN
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.
@c JP
入力の先頭headが述語@var{pred}を満たした場合、@var{result}を
@code{(@var{result} head (@var{pred} head))} のように呼び出し、
その戻り値をパーザ成功の結果とします。
@var{result}が省略された場合は、入力の先頭が結果になります。
@c COMMON
@item
@c EN
Otherwise, the parsing fails with @var{expect} as the expected input.
@c JP
そうでなければ、@var{expect}を期待していた結果としてパーズは失敗します。
@c COMMON
@end itemize

@c EN
If you just need a lookahead parser, you can use @code{$assert}.
@c JP
必要なのが先読みするパーザであれば、@code{$assert}も使えます。
@c COMMON
@end defun

@defun $. obj
@c MOD parser.peg
@c EN
Creates a parser that matches a Scheme object @var{obj},
which may be a character, a string, a char-set, or a symbol.
If @var{obj} is a char-set, the parser matches any character in the set.
Specifying a symbol can be used when you're parsing a token stream
instead of a character stream.

On success, the value of the parser is the matched input.

The resulting parser is atomic, that is, it doesn't consume
input when it fails.
@c JP
Schemebオブジェクト@var{obj}にマッチするパーザを作ります。
@var{obj}には、文字、文字列、文字集合、およびシンボルを指定できます。
@var{obj}が文字集合の場合は、パーザはその中のいずれか文字にマッチします。
シンボルは、文字ストリームでなくトークンストリームをパーズしている時に使えます。

成功した場合はマッチした入力がパーザの値となります。

返されるパーザはアトミック、つまり失敗した場合には入力を消費しません。
@c COMMON
@end defun

@defun $char c
@defunx $char-ci c
@c MOD parser.peg
@c EN
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.

When @var{c} is a character, @code{($char @var{c}}
is the same as @code{($. @var{c})};
you can use @code{$char} to emphasize you're matching a character.
@c JP
文字@var{c}とマッチするパーザを返します。@code{$char-ci}では大文字小文字を区別しません。
成功した場合は入力文字が値となります。
返されるパーザはアトミック、つまり失敗した場合には入力を消費しません。

@var{c}が文字の時、@code{($char @var{c}}は@code{($. @var{c})}と同じです。
文字とのマッチを強調したい場合に@code{$char}を使うと良いでしょう。
@c COMMON
@end defun

@defun $string str
@defunx $string-ci str
@c MOD parser.peg
@c EN
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)))}.
@c JP
文字列@var{str}とマッチするパーザを返します。
@code{$string-ci}では大文字小文字を区別しません。
成功した場合はマッチした入力文字列が値となります。

返されるパーザはアトミック、つまり失敗した場合には入力を消費しません。
つまり、@code{($string "ab")}は
@code{($let ([a ($char #\a)] [b ($char #\b)]) ($return (string a b)))}
と同じ@emph{ではありません}。
@c COMMON
@end defun

@defun $one-of cset
@defunx $one-of obj-list
@c MOD parser.peg
@c EN
The first form returns a parser that accepts any character in
the character set @var{cset}.
In the second form, @var{obj-list} must be a list of either
a character, a string, a character set or a symbol, and each one
is matched with the same way as @code{$.}.

On success, the parser yields the accepted object.
On failure, the parser doesn't consume input.
@c JP
最初のフォームは、文字集合@var{cset}中のいずれかの文字にマッチするパーザーを返します。
二番目のフォームでは、@var{obj-list}は文字、文字列、文字集合、シンボルからなる
リストでなければならず、それぞれの要素が@code{$.}で順に試されます。

成功した場合はマッチしたオブジェクトをパーザの値とします。
失敗した場合に入力を消費しません。
@c COMMON
@end defun

@defun $none-of cset
@c MOD parser.peg
@c EN
Returns a parser that accepts any character not in the character set @var{cset}.
On success, the parser yields the accepted character.
@c JP
文字集合@var{cset}に含まれない文字とマッチするパーザを返します。
成功した場合にはマッチした文字をパーザの値とします。
@c COMMON
@end defun

@defun $any
@c MOD parser.peg
@c EN
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.
@c JP
任意の1要素とマッチし、それをパーザの値とします。
このパーザが失敗するのは、入力が末尾に達していた場合だけです。
@c COMMON
@end defun

@defun $eos
@c MOD parser.peg
@c EN
Stands for ``end of stream''.  Returns a parser that matches
the end of input.  The value of parser is @code{#<eof>} in that case.
It never consumes input.
@c JP
EOSとはストリーム末尾(end of stream)です。入力が既に末尾に達していた場合に
マッチが成功し、@code{#<eof>}を値とします。
このパーザは入力を消費しません。
@c COMMON
@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
@c EN
The pattern matcher macro @code{match-let1} lifted to the parser.
@xref{Pattern matching}, for the details of supported @var{pattern}.
@c JP
これは、パターンマッチを行う@code{match-let1}マクロをパーザ領域に持ち上げたものです。
@var{pattern}部分は@code{match-let1}と同じです。
@ref{Pattern matching}を参照してください。
@c COMMON

@c EN
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.
@c JP
マクロ@code{$match1}は入力ストリームから1要素を取り出し、@var{pattern}とマッチするかどうか
調べます。マッチすれば、パターン変数が束縛された環境で@var{result}を評価し、
その値をパーザの値とします。入力要素がマッチしないか、入力が既に末尾に達していた
場合は、入力を消費することなくパーザは失敗します。
@c COMMON

@c EN
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.
@c JP
3番めの形式では、@code{=>}はリテラルの識別子、@var{fail}は任意の識別子です。
@var{result}の評価環境で、@var{fail}は一つの文字列を取る手続きに束縛されます。
@var{result}の末尾位置で@var{fail}を呼び出すとパーザは失敗し、@var{fail}に渡した
文字列がメッセージとなります。@var{fail}が呼ばれた場合、入力は消費されません。
@c COMMON

@c EN
(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.  So you can invoke @var{fail}
anywhere in the dynamic extent of the clause.
In @code{$match1}, @var{fail} is simply a procedure, so
you have to call it at the tail position to make it work.)
@c JP
(註: @code{util.match}の@code{match}マクロも似た機能を持っていますが、
@code{match}で@var{fail}が束縛されるのは現在のマッチ節を放棄して次のマッチ節を
試す継続です。従ってマッチ節の動的スコープの中ならどこでも呼ぶことができます。
@code{$match1}の@var{fail}は単なる手続きであり、
@var{result}の末尾位置で呼ばないとマッチを失敗させることはできません。)
@c COMMON

@c EN
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.
@c JP
@code{$match1*}マクロは@code{$match1}と似ていますが、
入力ストリーム全てが@var{pattern}とのマッチの対象になります。
入力の要素を2つ以上見たい場合に便利です。
任意個の要素を消費するパターンを与えた場合(例: @code{($match1* (a ...))})、
このパーザは入力を最後まで消費することに注意してください。
@c COMMON

@c EN
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}.
@c JP
これらのマクロは、別の字句解析を使って生成されるトークンストリームをパーズする時に
特に役に立つでしょう。各トークンは単なる文字ではなく構造を持つことができ、
@code{match}の力を活用することができます。
@c COMMON
@end defmac

@node PEG ropes, PEG choice, PEG primitive parser builders, PEG parser combinators
@c EN
@subsection Ropes
@c JP
@subsection ロープ
@c COMMON

@c EN
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.
@c JP
パーザの値として、文字列を返したいことはよくあります。
しかし常に文字列を作るようにすると、後でより大きな文字列に取り込まれる中間結果の
文字列を大量に作っては捨てることになり、効率が悪いです。
ロープは、文字列構築を遅延させる軽量な仕組みです。
@c COMMON

@c EN
A rope represents text with a tree of characters, strings, and 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.
@c JP
ロープはテキストを、文字、文字列、そしてロープの木で表現し、
O(1)での連結を可能にします。ロープは@emph{ファイナライズ}することで文字列になります。
@code{peg-run-parser}のようなパーザドライバは最終的な結果がロープであればそれを
自動的にファイナライズします。
@c COMMON

@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{}
@defunx $or p1 p2 @dots{} :else plast
@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.

If all of the parsers p1 p2 @dots{} fail without consuming input,
@code{$or} returns a compound failure of all the failures.  You may
wish to produce better error message than that.  Putting @code{$fail}
parser at the last doesn't cut it, for @code{$fail} doesn't consume
input so all the previous failures would compound.   In such cases,
you can use the second form---if the argument before the last parser
is a keyword @code{:else}, then @code{$or} discards the previous failures.

@example
(peg-parse-string ($or ($. "ab")
                       ($. "cd")
                       :else ($fail "we want 'ab' or 'cd'"))
                  "ef")
 @result{} PARSE-ERROR: 'ab' or 'cd' required at 0
@end example
@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.

@example
(define digits4
  ($expect ($->string ($repeat ($. #[\d]) 4))
           "4 consecutive digits"))

(peg-parse-string digits4 "123a")
  @result{} @r{error with}
  *** PARSE-ERROR: expecting 4 consecutive digits at 3, but got #\a
@end example
@end defun

@defun $cut p
@c MOD parser.peg
If @var{p} fails, make the failure non-recoverable.  It prevents the
upstream @code{$or} and @code{$try} from backtracking and trying other choices,
and makes the entire parsing fail immediately.

See also @code{$raise} above.
@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
Returns a parser that atches
@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
Returns a parser that matches
@var{p1}, @var{p2} and @var{p3} sequentially, and returns
the result of @var{p2}.
@end defun

@defun $list p @dots{}
@defunx $list* p @dots{}
@c MOD parser.peg
Returns a parser that matches @var{p} @dots{},
and returns the list of the results.
@code{$list*} uses the last parser's result as the last cdr.

They are the same as @code{($lift list p @dots{})} and
@code{($lift list* p @dots{})}, but we encounter this pattern
frequent enough to have these.
@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 construct 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 ([r0 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 succeed, 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

@defmac $binding parser-bind-form @dots{} [(=> fail)] expr
@defmacx $lbinding parser-bind-form @dots{} [(=> fail)] expr
@c MOD parser.peg
Each @var{parser-bind-form} may be a parser-yielding expression, except
that you can insert a form @code{($: var parser-expression)} anywherer in it,
where @var{parser-expression} is an expression that yields a parser.
The @code{$:} form is equivalent to just the @var{parser-expression}, except
that its semantic value is bound to a variable @var{var}.

Each parser created by @var{parser-bind-form} is applied to the input
in sequence.  One of @var{parser-bind-form} fails, the entire parser
immediately fails.  If all of @var{parser-bind-form} succeeds, @var{expr}
is evaluated in the environment where all the @var{var}s are
bound to the corresponding parser expression.

Since @code{$binding} walks entire @var{parser-bind-form} to look for
@code{$:} forms, you can't have nested @code{$binding} form inside
@var{parser-bind-form}.

If the parser expression associated with @var{var} fails, or never
executed, the @var{var} is bound to @code{#<undef>}.
If the parser expression succeeds multiple times, @var{var} holds
the last value.  Also, @var{var} can appear more than one places;
it holds the last bound value.

The value of @var{expr} form becomes the semantic value of the
entire parser.

@code{$lbinding} is a shorthand of @code{($lazy ($binding ...))}.

The optional @code{(=> fail)} form before @var{expr} is similar to the
one with @code{$match}.   If given, @var{fail}, which must be an identifier,
is bound to a procedure that returns failure.  You should call it in the
tail position of @var{expr} to indicate failure.  It can be

@itemize @bullet
@item
@code{(@var{fail} @var{message})} : Returns @code{fail-message} type
failure, with a string @var{message} as the message.
@item
@code{(@var{fail} @var{tag} @var{message})} : Returns @code{fail-error} type
(non-recoverable) failure, where @var{tag} must be a symobl @code{error}
(in future, differtent tags will be supported).
@end itemize

@end defmac


@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 @code{$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 DEPRECATED
@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.

If there are more than one header with the same field name, value of
the first one is returned.  To get all values of multiple header fields,
use @code{rfc822-header-ref*} below.

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-header-ref*}を使ってください。

この手続きは@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

@defun rfc822-header-ref* header-list field-name
@c EN
Like @code{rfc822-header-ref}, looks up header entries in
@var{header-list} with the name @var{field-name}, however,
this procedure returns all values of matching headers
in a list.  If there's no matching headers, an empty list
is returned.
@c JP
@code{rfc822-header-ref}のように@var{header-list}から
@var{field-name}を持つヘッダを探しますが、最初に見つかったものだけでなく
@var{field-name}を持つ全てのヘッダの値をリストにして返します。
指定の名前を持つヘッダが無ければ空リストが返されます。
@c COMMON
@end defun

@defun rfc822-header-put header-list field-name field-value
@c EN
Returns an rfc822 header list which is the same as @var{header-list}
except that a header with @var{field-name} and @var{field-value}
is added.  @var{Field-name} is converted to lowercase letters.
If @var{header-list} already contains headers with
@var{field-name}, such headers are excluded from the output.
The @var{header-list} won't be modified.
@c JP
RFC822ヘッダリスト@var{header-list}に、名前@var{field-name}と値
@var{field-value}を持つヘッダを追加したヘッダリストを返します。
@var{field-name}は全て小文字に変換されます。
@var{header-list}が既に同名のヘッダを持っていた場合、それらは全て出力から除かれます。
引数に渡した@var{header-list}自体は変更されません。
@c COMMON
@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
@c EN
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.
@c JP
これは@code{rfc822-read-headers}の一種の逆関数と言えます。
各ヘッダデータが@code{(<name> <body>)}の形になっているリストを受け取り、
@var{output}キーワード引数で指定されるポートにRFC822形式で書き出します。
@var{output}が省略された場合は現在の出力ポートが使われます。
@c COMMON

@c EN
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.
@c JP
デフォルトでは、この手続きは@var{header}で全てのヘッダが完結するものと
みなし、最後にヘッダ部分の終了を示す空行を出力します。
ただし@var{continue}キーワード引数に真の値を渡すとこの動作は抑制され、
後からヘッダを追加で出力することができます。
@c COMMON

@c EN
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).  If the line length of header data exceeds
that, the caller should insert newline (@code{\r\n}) and one or
more whitespaces as needed.
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.
@c JP
上で「一種の」と書きましたが、それはこの手続きが完全な逆関数ではないからです
特に、ヘッダ行が長い場合の「行の折り返し」は呼び出し側でやっておかねばなりません。
RFC2822ではヘッダ行の絶対的な長さを998オクテットに制限しています。
データがそれを越える場合は適宜改行(@code{\r\n})+空白文字を挿入してください。
これは自動ではできません。ヘッダデータのどこに改行を挿入できるかは
各ヘッダのセマンティクスに依存するからです。
@c COMMON

@c EN
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.
@c JP
また、ヘッダフィールドボディはNUL文字以外のASCII文字のみで構成されている
必要があります。それ以外の文字を含めたい場合は、MIME等適切なプロトコルを
使ってあらかじめエンコードしておいてください。
@code{rfc.mime}モジュールの@code{mime-encode-text}が便利でしょう
(@ref{MIME message handling})。
これもまた、ヘッダフィールド毎のセマンティクスに依存するため、
自動で行うことができません。
@c COMMON

@c EN
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:
@c JP
しかしこの手続きは、渡されたデータがRFC2822に沿っているかどうかをチェック
できます。デフォルトではRFC2822に違反していればエラーが投げられます。
@var{check}キーワード引数でこの振る舞いを変えられます。
可能な値は次のとおりです。
@c COMMON

@table @code
@item :error
@c EN
Default.  Signals an error if a violation is found.
@c JP
デフォルト。違反があればエラーを投げます。
@c COMMON
@item #f, :ignore
@c EN
Doesn't perform any check.  Trust the caller.
@c JP
呼び出し側を信頼し、チェックを行いません。
@c COMMON
@item @var{procedure}
@c EN
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.
@c JP
@code{rfc822-write-headers}が違反を検出したら、
この手続きを3つの引数で呼び出します。
ヘッダフィールド名、ヘッダフィールドボディ、
そして違反の種類を示す以下のシンボルです。
この手続きは、修正されたヘッダフィールド名とヘッダフィールドボディの
ふたつの値を返さなければなりません。
もしこの手続きがヘッダフィールド名とヘッダフィールドボディを修正せずに
返したら、@code{:error}を指定したときのようにエラーが投げられます。
@c COMMON
@end table

@c EN
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.
@c JP
@var{check}引数に手続きを渡した際に、第3引数に渡されるシンボルは以下のとおりです。
将来のバージョンでは新たなシンボルが追加されるかもしれません。
@c COMMON

@table @code
@item incomplete-string
@c EN
Incomplete string is passed.
@c JP
不完全な文字列が渡された
@c COMMON
@item bad-character
@c EN
Header field contains characters outside of US-ASCII or NUL.
@c JP
NUL文字または非ASCII文字が含まれている
@c COMMON
@item line-too-long
@c EN
Line length exceeds 998 octet limit.
@c JP
1行が998オクテットの制限を越えている
@c COMMON
@item stray-crlf
@c EN
The string contains CR and/or LF character that doesn't consist of
proper line folding.
@c JP
CRLFの組み合わせでない、CRのみまたはLFのみが含まれている。
@c COMMON
@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 4648 (@uref{https://www.ietf.org/rfc/rfc4648.txt}).
It also supports Base32 and Base16 formats defined in it as well.
@c JP
このモジュールでは、RFC 4648 (@uref{https://www.ietf.org/rfc/rfc4648.txt})
で定義されている Base64フォーマットへエンコード/デコードするいくつかの
手続きを定義しています。同RFCで定義されている
Base32フォーマット、Base16フォーマットもサポートしています。
@c COMMON

@c EN
The common naming convention is as follows.
@c JP
共通の名前付け規則は次のとおりです。
@c COMMON

@table @code
@item @var{encoding}-encode, @var{encoding}-decode
@c EN
Port-based encoder/decoder.  It reads
input from the current input port, and emits encoded/decoded output
to the current output port.
@c JP
ポートを使うストリームエンコーダー/デコーダー。
入力を現在の入力ポートから取り、結果を現在の出力ポートに出力します。
@c COMMON
@item @var{encoding}-encode-message
@c EN
Takes the input as either a string or a u8vector, and returns
the encoded result as a string.  Note that BaseN encoding always
results readable strings.
@c JP
入力を文字列かu8vectorで受け取り、エンコード結果を文字列で返します。
BaseNエンコーディングの結果は常に可読文字列になります。
@c COMMON
@item @var{encoding}-decode-string-to
@c EN
Takes the encoded string, and returns the result in either
a u8vector or a string, as specified by the @var{target} argument.
Note that the decoded result is a byte sequence in general,
so a string may be incomplete.
@c JP
エンコードされた文字列を取り、結果をu8vectorもしくは文字列で返します。
どちらを返すからは@var{target}引数で指定されます。
デコード結果は一般にはバイトシーケンスになるので、文字列の場合は
不完全な文字列が返ることに注意してください。
@c COMMON
@end table
@end deftp

@subheading Base64

@defun base64-encode :key line-width digits url-safe omit-padding
@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
Base64 can have different mappings in the digit of 62 and 63; the ``standard''
encoding uses @code{+} and @code{/}, and the ``url-safe'' encoding
uses @code{-} and @code{_}.  You can specify which to use by either
@var{url-safe} or @var{digits}.
@c JP
Base64は62と63を表現するのにいくつかの異なるマッピングがあります。
「標準の」エンコーディングでは@code{+}と@code{/}が、
「URL安全」なエンコーディングでは@code{-}と@code{_}がそれぞれ使われます。
どちらを使うかは@var{url-safe}または@var{digits}引数で制御できます。
@c COMMON

@c EN
If a true value is given to @var{url-safe},
the input bytes will be encoded with ``url-safe'' encoding.
Otherwise, you can give a two-letter string to @var{digits} argument,
in which case the first character is used for digit 62 and the
second character is used for digit 63.  The @var{digits} argument
is added to support SRFI-207 (@pxref{String-notated bytevectors}).
@c JP
@var{url-safe}に真の値を与えると、URL安全なエンコーディングが使われます。
そうでない場合、@var{digits}に2文字からなる文字列を渡すことができ、
1文字目が62を、2文字目が63を現す文字として使われます。
@var{digits}引数はSRFI-207をサポートするために追加されました
(@ref{String-notated bytevectors}参照)。
@c COMMON

@c EN
If a true value is given to @var{omit-padding}, the trailing
padding characters (@code{#\=}) are omitted.
(See RFC4648 Section 3.2 (@url{https://www.rfc-editor.org/rfc/rfc4648#section-3.2})).  The default is not omitting padding characters.
@c JP
@var{omit-padding}引数に真の値が与えられると、
パディング文字(@code{#\=})が省略されます
(RFC4648 Section 3.2参照 (@url{https://www.rfc-editor.org/rfc/rfc4648#section-3.2}))。
デフォルトではパディング文字は省略されません。
@c COMMON
@end defun

@defun base64-encode-message message :key line-width digits url-safe omit-padding
@c MOD rfc.base64
@c EN
Encodes @var{message}, which must be either a string or a u8vector,
with Base64 encoding and returns the result as a string.
The meaning of keyword arguments are the same as @code{base64-encode} above.
@c JP
文字列かu8vectorの@var{message}をBase64エンコードして、結果を文字列で返します。
キーワード引数の意味は上の@code{base64-encode}と同じです。
@c COMMON

@example
(base64-encode-message "Hau'oli makahiki hou")
 @result{} "SGF1J29saSBtYWthaGlraSBob3U="
@end example

@c EN
For the portable code, you may want to use @code{bytestring->base64}
in @code{srfi.207} (@pxref{String-notated bytevectors}).
@c JP
ポータブルなコードでは、@code{srfi.207}の@code{bytestring->base64}を使うことができます
(@ref{String-notated bytevectors}参照)。
@c COMMON
@end defun


@defun base64-decode :key digits url-safe strict
@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{=}).
@c JP
現在の入力ポートから文字ストリームを読み込み、それを Base64 フォーマットとして
デコードし、現在の出力ポートにバイトストリームとして書き出します。
変換は EOF か、終端文字 (@code{=}) を読み込むと終了します。
@c COMMON

@c EN
The characters which does not in legal Base64 encoded character set are
silently ignored by default.  If a true value is given to the
@var{strict} keyword argument, however, non-whitespace out-of-set characters
in the input raises an error.
@c JP
Base64 でエンコードされた文字として適当でない文字は、デフォルトでは黙って無視されます。
ただし、@var{strict}キーワード引数に真の値が与えられた場合は、
空白文字以外の不適切な文字が入力にあったらそこでエラーが投げられます。
@c COMMON

@c EN
The input can lack the trailing padding character by default.  However,
if @var{strict} argument is true, an error is thrown unless
the input has a proper number of padding characters.
@c JP
入力が必要なパディング文字を欠いていても、デフォルトでは許容されます。
@var{strict}引数が真の場合は、入力に正しい数のパディング文字がないとエラーが投げられます。
@c COMMON


@c EN
The @var{digits} and @var{url-safe} keyword arguments can be used
to choose different mappings of digit 62 and 63.  See @code{base64-encode}
above for the details.
@c JP
@var{digits}と@var{url-safe}キーワード引数は62と63の異なるエンコーディングを
指定するのに使えます。詳しくは上の@code{base64-encod}のエントリを参照してください。
@c COMMON
@end defun

@defun base64-decode-string-to target string :key line-width digits url-safe omit-padding
@c MOD rfc.base64
@c EN
The @var{target} argument must be a class object @code{<string>} or @code{<u8vector>}.
This procedure takes Base64-encoded input @var{string}, and returns the
decoded result as an instance of @var{target}.

The meaning of keyword arguments are the same as @code{base64-decode} above.
@c JP
@var{target}引数はクラスオブジェクト@code{<string>}か@code{<u8vector>}でなければなりません。
Base64エンコードされた入力@var{string}を取り、結果を@var{target}のインスタンスで
返します。

キーワード引数の意味は上の@code{base64-decode}と同じです。
@c COMMON

@example
(base64-decode-string-to <string> "SGF1J29saSBtYWthaGlraSBob3U=")
 @result{} "Hau'oli makahiki hou"
(base64-decode-string-to <u8vector> "SGF1J29saSBtYWthaGlraSBob3U=")
 @result{} #u8(72 97 117 39 111 108 105 32 109 97 107 97 104 105
    107 105 32 104 111 117)
@end example

@c EN
Note that if you ask a string to be returned, the result may be
an incomplete string.
@c JP
結果を文字列で得る場合、不完全文字列が返される可能性があることに注意してください。
@c COMMON

@example
(base64-decode-string-to <string> "8PHy8w==")
 @result{} #**"\xf0;\xf1;\xf2;\xf3;"
@end example

@c EN
For the portable code, you may want to use @code{base64->bytestring}
in @code{srfi.207} (@pxref{String-notated bytevectors}).
@c JP
ポータブルなコードでは、@code{srfi.207}の@code{base64->bytestring}を使うことができます
(@ref{String-notated bytevectors}参照)。
@c COMMON
@end defun


@subheading Base32

@c EN
RFC4648 defines two completely different encodings as base-32;
The standard Base32 uses @code{A-Z} for 0 to 25, and @code{2-7}
for 26 to 31.  The ``base32hex'' variant uses
@code{0-9} for 0 to 9, and @code{A-V} for 10 to 31.
Since RFC states the latter should not be referred to as base32,
we provide separate procedures for those encodings.
@c JP
RFC4648は基数32のエンコーディングとして2つの全く異なるアルファベットを規定しています。
標準のBase32は@code{A-Z}を0から25に、@code{2-7}を26から31に使います。
``base32hex'' は@code{0-9}を0から9に、@code{A-V}を10から31に使います。
RFCでは後者をbase32と呼ばないように言っているので、
二つのエンコーディングに対応する別々の手続きを用意しました。
@c COMMON

@defun base32-encode :key omit-padding line-width
@defunx base32hex-encode :key omit-padding line-width
@c MOD rfc.base64
@c EN
The procedures are port-based; they read input from the
current standard port, and emits the base32 or base32hex
encoded result to the current output port.
@c JP
これらの手続きは現在の入力ポートからデータを読み、
Base32またはBase32hexでエンコードされた結果を現在の出力ポートに書き出します。
@c COMMON

@c EN
The keyword arguments @var{omit-padding} and @var{line-width} are
the same as @code{base64-encode}.
@c JP
キーワード引数@var{omit-padding}と@var{line-width}は
@code{base64-encode}と同じです。
@c COMMON
@end defun

@defun base32-encode-message message :key omit-padding line-width
@defunx base32hex-encode-message message :key omit-padding line-width
@c MOD rfc.base64
@c EN
Base32 or Base32hex encode @var{message}, which should be a string or a u8vector,
and returns the result in a string.
@c JP
文字列もしくはu8vectorの@var{message}をBase32/Base32hexでエンコードして、
結果を文字列として返します。
@c COMMON

@c EN
The keyword arguments @var{omit-padding} and @var{line-width} are
the same as @code{base64-encode}.
@c JP
キーワード引数@var{omit-padding}と@var{line-width}は
@code{base64-encode}と同じです。
@c COMMON

@example
(base32-encode-message "Hau'oli makahiki hou!")
 @result{} "JBQXKJ3PNRUSA3LBNNQWQ2LLNEQGQ33VEE======"
(base32hex-encode-message "Hau'oli makahiki hou!")
 @result{} "91GNA9RFDHKI0RB1DDGMGQBBD4G6GRRL44======"
@end example
@end defun

@defun base32-decode :key strict
@defunx base32hex-decode :key strict
@c MOD rfc.base64
@c EN
Read Base32/Base32hex encoded string from the current input port,
and emits the decoded result to the current output port.
@c JP
Base32/Base32hexエンコードされた文字列を現在の入力ポートから読み、
デコード結果を現在の出力ポートに書き出します。
@c COMMON

@c EN
If a true value is given to the @var{strict} argument,
an error is thrown if non-whitespace illegal characters exist
in the input, or the proper padding characters are missing.
The default of @var{strict} is @code{#f} and illegal characters
are just ignored.
@c JP
@var{strict}引数に真の値が与えられると、
入力に空白文字でもエンコードに使われる文字でもない文字が現れたり、
必要なパディング文字が無かったりした場合にエラーが投げられます。
@var{strict}のデフォルト値は@code{#f}で、不正な文字は単に無視されます。
@c COMMON
@end defun

@defun base32-decode-string-to target string :key strict
@defunx base32hex-decode-string-to target string :key strict
@c MOD rfc.base64
@c EN
Decode a Base32/Base32hex encoded string @var{string}, and
returns the result as an instance of class @var{target}, which
must be either @code{<u8vector>} or @code{<string>}.
@c JP
Base32/Base32hexエンコードされた文字列@var{string}をデコードして、
結果を@var{target}クラスのインスタンスとして返します。
@var{target}はクラスオブジェクト@code{<u8vector>}か@code{<string>}
でなければなりません。
@c COMMON

@c EN
The meaning of @var{strict} argument is the same as
in @code{base32-decode}.
@c JP
@var{strict}引数の意味は@code{base32-decode}と同じです。
@c COMMON

@example
(base32-decode-string-to <string>
   "JBQXKJ3PNRUSA3LBNNQWQ2LLNEQGQ33VEE======")
 @result{} "Hau'oli makahiki hou!"
@end example

@end defun

@subheading Base16

@c EN
Base16 is simply the hexadecimal encoding of input octets.
RFC4648 defines to use uppercase letters @code{A-F} for digits
10 to 15.  In practice, lowercase letters are also used
for hexadecimal encoding, so we provide that option, too.
@c JP
Base16は入力オクテットの単純な16進数エンコーディングです。
RFC4648では10から15の数字に大文字の@code{A-F}を当てていますが、
16進数エンコーディングに小文字を使う場合も良くあるので、
このライブラリではそのオプションも用意しています。
@c COMMON

@defun base16-encode :key lowercase
@c MOD rfc.base64
@c EN
Read data from the current input port, and emits Base16 encoded
result to the current output port.

By default, @code{A-F} are used for digit 10 to 15, as specified
in RFC4648.  If @var{lowercase} argument is given and true,
@code{a-f} are used instead.

Note that no padding character is ever generated in Base16 encoding.
@c JP
現在の入力ポートからデータを読み込み、Base16エンコードした結果を
現在の出力ポートに書き出します。

デフォルトでは、RFC4648の規定により、10から15に大文字の@code{A-F}を使います。
@var{lowercase}引数が与えられて真ならば、小文字の@code{a-f}を使います。

Base16エンコーディングではパディング文字は出力されません。
@c COMMON
@end defun

@defun base16-encode-message message :key lowercase
@c MOD rfc.base64
@c EN
Base16 encode @var{message}, which should be a string or a u8vector,
and returns the result in a string.  The @var{lowercase} argument
is the same as @code{base16-encode}.
@c JP
文字列もしくはu8vectorの@var{message}をBase16エンコードして、
結果を文字列として返します。@var{lowercase}引数は@code{base16-encode}と同じです。
@c COMMON

@example
(base16-encode-message "Aloha")
 @result{} "416C6F6861"
(base16-encode-message "Aloha" :lowercase #t)
 @result{} "416c6f6861"
@end example
@end defun

@defun base16-decode :key strict
@c MOD rfc.base64
@c EN
Read Base16 encoded string from the current input port,
and emits the decoded result to the current output port.
@c JP
Base16エンコードされた文字列を現在の入力ポートから読み、
デコード結果を現在の出力ポートに書き出します。
@c COMMON

@c EN
By default, characters other than Base16 digits are ignored,
and both upperase and lowercase alphabets are recognized.
If @var{strict} argument is given and true, however,
characters other than @code{#[0-9A-F]} throws an error.
@c JP
デフォルトでは、Base16アルファベット以外の文字は無視され、
また大文字も小文字も認識されます。
@var{strict}引数が与えられて真ならば、
@code{#[0-9A-F]}以外の文字が見つかるとエラーが投げられます。
@c COMMON
@end defun

@defun base16-decode-string-to target string :key strict
@c MOD rfc.base64
@c EN
Decode Base16-encoded string @var{string}, and returns
the result as an instance of class @var{target}, which must
be either @code{<u8vector>} or @code{<string>}.

The @var{strict} argument is the same as @code{base16-decode}.
@c JP
Base16エンコードされた文字列@var{string}をデコードして、
結果をクラス@var{target}のインスタンスで返します。
@var{target}は@code{<u8vector>}か@code{<string>}でなければなりません。

@var{strict}引数は@code{base16-decode}と同じです。
@c COMMON

@example
(base16-decode-string-to <u8vector> "416c6f6861")
 @result{} #u8(65 108 111 104 97)
(base16-decode-string-to <string> "416c6f6861")
 @result{} "Aloha"
@end example
@end defun

@c EN
@subheading Deprecated API
@c JP
@subheading 非推奨API
@c COMMON

@c EN
The following API is deprecated.  Avoid using them in new code.
@c JP
以下のAPIは非推奨となりました。新規コードでは使わないでください。
@c COMMON


@defun base64-encode-string string :key line-width digits url-safe
@defunx base64-encode-bytevector u8vector :key line-width digits url-safe
@c MOD rfc.base64
@c DEPRECATED
@c EN
Converts contents of @var{string}/@var{u8vector} to Base64 encoded format.
For @code{base64-encode-string},
input string can be either complete or incomplete string;
it is always interpreted as a byte sequence.
The @var{digits} and @var{url-safe} arguments are the same as
@code{base64-encode}.
@c JP
@var{string}/@var{u8vector} の内容を Base64 でエンコードされたフォーマットに変換します。
@code{base64-encode-string}の入力となる文字列は、
完全文字列でも不完全文字列でも良いです。常にバイト・シーケンスとして扱われます。
@var{digits}と@var{url-safe}引数は@code{base64-encode}と同じです。
@c COMMON
@end defun

@defun base64-decode-string string :key url-safe strict
@defunx base64-decode-bytevector u8vector :key url-safe strict
@c MOD rfc.base64
@c DEPRECATED
@c EN
Decodes a Base64 encoded string @var{string} and returns
the result as a string or a u8vector, respectively.
The conversion terminates at the end of @var{string} or
the termination character (@code{=}).
@c JP
Base64 でエンコードされた文字列 @var{string} をデコードしてそれぞれ文字列
あるいはu8vectorとして返します。
変換は @var{string} の終わりか、終端文字 (@code{=}) で終了します。
@c COMMON

@c EN
The characters which are not in legal Base64 encoded character set are
silently ignored by default.  If a true value is given to the
@var{strict} keyword argument, however, non-whitespace out-of-set characters
in the input raises an error.
@c JP
Base64 でエンコードされた文字として適当でない文字は、デフォルトでは黙って無視されます。
ただし、@var{strict}キーワード引数に真の値が与えられた場合は、
空白文字以外の不適切な文字が入力にあったらそこでエラーが投げられます。
@c COMMON

@c EN
The @var{digits} and @var{url-safe} arguments are the same as
@code{base64-encode}.
@c JP
@var{digits}と@var{url-safe}引数は@code{base64-encode}と同じです。
@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 is accepted but ignored; it's for the backward
compatibility.

Each cookie spec has the following format.
@c JP
与えられたクッキーの仕様のリストから、@code{Set-cookie2} か
@code{Set-cookie} ヘッダに適切なクッキー文字列を作ります。

オプションの @var{version} 引数は、互換性のために受容されますが無視されます。

クッキーの仕様は以下のフォーマットを持ちます。
@c COMMON
@example
(<name> <value> [:expires <data/time>] [:max-age <age>]
                [:domain <domain>] [:path <path>]
                [:secure <boolean>] [:http-only <boolean>]
@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 <domain> <path>
Strings.
@item <boolean>
Boolean value
@item <age>
Non-negative exact integers
@item <date/time>
Either an integer (seconds since Epoch), a formatted date string,
@code{<time>} or @code{<date>} objects
(@pxref{Time}, @pxref{Time data types and procedures}).
@end table
@c JP
@table @code
@item <name>
文字列。クッキーの名前。
@item <value>
クッキーの値。文字列か、値が必要なければ @code{#f} 。
@item <domain> <path>
文字列。
@item <boolean>
真偽値。
@item <age>
非負の正確な整数。
@item <date/time>
整数(エポックからの秒数)か、Netscape のクッキー仕様に従うフォーマットされた
日付文字列か、@code{<time>}もしくは@code{<date>}オブジェクト
(@ref{Time},および @ref{Time data types and procedures}参照)。
@end table
@c COMMON

@c EN
The order of attributes does not matter.
The attribute values are quoted appropriately.

For the backward compatibility to the older specification
(RFC2965, RFC2109, and old Netscape cookie specification), it
recognizes a few more attributes (@code{comment}, @code{comment-url},
@code{discard}, @code{port}, and @code{version}).  They are rendered
to the output, but the new code should not use them.

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.

Example:
@c JP
属性の指定は順不同です。属性値は適切にクォートされます。

互換性のために、古い規格(RFC2965, RFC2109, 古のNetscape cookie specificaiton)
で指定されていたいくつかの属性も認識され出力に含められます
(@code{comment}, @code{comment-url}, @code{discard}, @code{port},
@code{version})。が、新規のコードではこれらの属性を使うべきではありません。

戻り値はそれぞれのクッキー文字列のリストです。(@code{Set-cookie} を使う)
古いスタイルのプロトコルでは、それぞれを独立したヘッダとして送らなければ
なりません。(@code{Set-cookie2} ヘッダを使う)新しいプロトコルでは、
それらをカンマで繋ぎ、一度に送ることができます。詳細は RFC6265 を見て下さい。

例:
@c COMMON
@example
(construct-cookie-string
   `(("name" "foo" :domain "foo.com" :path "/" :max-age 86400)))
 @result{} ("name=foo;Domain=foo.com;Path=/;Max-age=86400")
@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 client, 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

@c EN
Following is a typical way to digest a given string.
@c JP
以下は典型的なHMACハッシュを計算する例です。
@c COMMON

@example
(use rfc.sha)  ; import desired digest algorithm
(use rfc.hmac)

(hmac-message <sha256> "secret-key" "payload")
 @result{} #u8(16 170 46 28 37 56 70 79 247 95 6 71 39 30 59 167 70 188 163
    252 222 175 50 44 88 27 245 133 30 140 221 183)

(hmac-message-to 'hex <sha256> "secret-key" "payload")
 @result{} "10aa2e1c2538464ff75f0647271e3ba746bca3fcdeaf322c581bf5851e8cddb7"
@end example
@end deftp

@c EN
@subheading High-level API
@c JP
@subheading 高レベルAPI
@c COMMON

@defun hmac-to target algorithm key
@c MOD rfc.hmac
@c EN
Read input data from the current input port, and compute HMAC digest
with a hash algorithm @var{hash-class} and a key @var{key}.

The result is returned as an instance of class @var{target}, which
can be @code{<u8vector>} or @code{<string>}.  Some symbols is also
allowed to specify encoding: @code{base64}, @code{base64url},
@code{base64url-nopad}, @code{base32}, @code{base32hex}, @code{base16},
and @code{hex}.  @xref{Message digester framework} for the details
of those encodings.

The @var{hash-class} argument must be a class implementing
@code{<message-digest-algorithm>}, such as @code{<sha256>}
of @code{rfc.sha} (@pxref{SHA message digest}).

The key @var{key} may be a string or a u8vector.
@c JP
現在の入力ポートから読んだデータの鍵つきHMACダイジェストを計算します。
@var{hash-class}はダイジェストアルゴリズムを指定するクラス、
@var{key}はダイジェストに使う鍵です。

@var{target}は結果の返し方を指定します。クラスオブジェクト@code{<u8vector>}
もしくは@code{<string>}の場合はそのインスタンスが返ります。
@var{target}にはまた、エンコーディングを表す以下のシンボルを渡すこともできます:
@code{base64}, @code{base64url},
@code{base64url-nopad}, @code{base32}, @code{base32hex}, @code{base16},
@code{hex}。詳しくは@ref{Message digester framework}を参照してください。

@var{hash-class}引数には@code{<message-digest-algorithm>}を実装している
クラスを渡します。例えば@code{rfc.sha}モジュールの@code{<sha256>}です。
(@ref{SHA message digest}参照)。

@var{key}は文字列かu8vectorでなければなりません。
@c COMMON
@end defun

@defun hmac-message-to target hash-class key message
@c MOD rfc.hmac
@c EN
Returns an HMAC digest of @var{message},
computed with a hash algorithm @var{hash-class},
with a key @var{key}.
@c JP
@var{message}のHMACダイジェストを、
@var{hash-class}をアルゴリズム、@var{key}を鍵として計算して返します。
@c COMMON

@c EN
The @var{hash-class} argument must be a class inheriting
@code{<message-digest-algorithm>}, e.g. @code{<sha256>} class
from @code{rfc.sha} (@pxref{SHA message digest}).
@c JP
@var{hash-class}引数は@code{<message-digest-algorithm>}を実装している
クラスでなければなりません。例えば@code{rfc.sha}モジュールの@code{<sha256>}です。
(@ref{SHA message digest}参照)。
@c COMMON

@c EN
You can pass both a stirng and a u8vector
to @var{key}/@var{message}.
@c JP
@var{key}、@var{message}には文字列かu8vectorを渡せます。
@c COMMON

@c EN
The @var{target} can be a class in which the result is returned,
either @code{<u8vector>} or @var{<string>}, or a symbol specifying
the encoding: @code{base64}, @code{base64url},
@code{base64url-nopad}, @var{base32}, @var{base32hex}, @code{base16},
and @code{hex}.  @xref{Message digester framework} for the details
of those encodings.
@c JP
@var{target}は結果のを返すオブジェクトのクラスを指定します。
@code{<u8vector>}と@code{<string>}がサポートされています。
@var{target}にはまた、エンコーディングを表す以下のシンボルを渡すこともできます:
@code{base64}, @code{base64url},
@code{base64url-nopad}, @var{base32}, @var{base32hex}, @code{base16},
@code{hex}。詳しくは@ref{Message digester framework}を参照してください。
@c COMMON
@end defun

@defun hmac-message hash-class key message
@c MOD rfc.hmac
@c EN
A shortcut of @code{(hmac-message-to <u8vector> hash-class key message)}.
@c JP
@code{(hmac-message-to <u8vector> hash-class key message)}
の短縮形です。
@c COMMON

@example
(hmac-message <sha256> "secret" "Aloha, honua")
 @result{} #u8(78 232 135 13 246 139 36 242 133 33 99 185 4 249 244
    22 243 46 120 130 192 235 60 187 172 180 223 169 179 247 186 185)
@end example
@end defun

@defun hmac-verify hash-class digest key message
@c MOD rfc.hmac
@c EN
Verify @var{message} by comparing its digest with the given @var{digest}.
Functionally it is @code{(equal? digest (hmac-message hash-class key message))},
but the digests are compared in a way that can avoid timing attack.

@var{Hash-class} is a class inherits @code{<message-digest-algorithm>}
such as @code{<sha256>}.
@var{Digest} must be a u8vector.  Either a string or a u8vector
is allowed for each of @var{key} and @var{message}.

Returns @code{#t} if @var{digest} is valid digest for the message,
@code{#f} if not.
@c JP
@var{message}の鍵つきダイジェストが@var{digest}と一致するかどうか調べます。
機能的には@code{(equal? digest (hmac-message hash-class key message))}
と同じですが、タイミングアタックを防ぐ比較が使われます。

@var{hash-class}は@code{<message-digest-algorithm>}を継承したクラス、
例えば@code{<sha256>}です。@var{digest}はu8vectorでなければなりません。
@var{key}と@var{message}には文字列edもu8vectorでも渡せます。
@c COMMON

@example
(hmac-verify <sha256>
             '#u8(78 232 135 13 246 139 36 242 133 33 99 185 4 249 244 22 243 46
                  120 130 192 235 60 187 172 180 223 169 179 247 186 185)
             "secret"
             "Aloha, honua")
 @result{} #t
@end example
@end defun

@c EN
@subheading Low-level API
@c JP
@subheading 低レベルAPI
@c COMMON


@deftp {Class} <hmac>
@clindex hmac
@c MOD rfc.hmac
@c EN
Keeps state information of HMAC algorithm.  This should not be
directly instantiated; use @code{make-hmac} below.
@c JP
HMACアルゴリズムの状態情報を保持します。インスタンスを作るには、
このクラスを@code{make}するのではなく、下に示す@code{make-hmac}を使ってください。
@c COMMON
@end deftp

@defun make-hmac algorithm key
@c MOD rfc.hmac
@c EN
Creates and returns a new @code{<hmac>} object.  The @var{algorithm}
argument is a class inheriting @code{<message-digest-algorithm>} to
specify digest algorithm, for example, @code{<sha256>}
(@pxref{SHA message digest}, for the details).
The @var{key} argument is a key, either a string or a u8vector.
@c JP
新たな@code{<hmac>}オブジェクトを作って返します。
@var{algorithm}引数は@code{<message-digest-algorithm>}を継承する
クラスで、ダイジェストアルゴリズムを指定します。
例えば@code{<sha256>}が使えます。詳しくは@ref{SHA message digest}参照。
@var{key}引数は文字列かu8vectorで鍵を指定します。
@c COMMON

@c EN
When you use high-level APIs such as @code{hmac-message}, you don't
need to make an @code{<hmac>} object since it is implicitly created.
You only need to create it explicitly to use the following
streaming update procedures.
@c JP
@code{hmac-message}などの高レベルAPIを使う場合、
@code{<hmac>}オブジェクトは内部で自動的に作られるので明示的にmakeする必要はありません。
下のストリーム更新手続きを使う場合だけ、@code{<hmac>}オブジェクトを
明示的に作る必要があります。
@c COMMON
@end defun

@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>) :optional target
@c MOD rfc.hmac
@c EN
Finalizes the internal state of @var{hmac} and returns the
digest in an instance of @var{target}, which must be
a @code{<string>} or @code{<u8vector>} class metaobject,
or a symbol to specify encoding.  See @code{hmac-to} above for the
details of @var{target}.  The default is @code{<string>}, for a
historical reason.

Once finalized, you can't call @code{hmac-update!} or @code{hmac-final!}
on @var{hmac}.
@c JP
@var{hmac}の内部状態を終了させ、ダイジェストを@var{target}で指定される
インスタンスで返します。@var{target}はクラスオブジェクト@code{<string>}
または@code{<u8vector>}、あるいはエンコーディングを示すシンボルでなければ
なりません。@var{target}について詳しくは上の@code{hmac-to}の項を参照してください。
@var{target}が省略された場合は、歴史的な理由から@code{<string>}が使われます。

一旦終了されると、@var{hmac}に対しては@code{hmac-update!}や
@code{hmac-final!}を呼ぶことはできません。
@c COMMON
@end deffn

@c EN
@subheading Deprecated API
@c JP
@subheading 非推奨API
@c COMMON

@c EN
The following procedures are deprecated.  You can use @code{hmac-to}
and @code{hmac-message} instead.
@c JP
以下の手続きは非推奨になりました。@code{hmac-to}や@code{hmac-message}が
かわりに使えます。
@c COMMON

@defun hmac-digest :key key hasher
@c MOD rfc.hmac
@c DEPRECATED
@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 defun

@defun hmac-digest-string string :key key hasher
@c MOD rfc.hmac
@c DEPRECATED
@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 defun

@c ----------------------------------------------------------------------
@node HTTP client, ICMP packets, HMAC keyed-hashing, Library modules - Utilities
@section @code{rfc.http} - HTTP client
@c NODE HTTPクライアント, @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 HTTP/1.1 protocol.
Support for some advanced features such as persistent connection
may be added in the future versions.
@c JP
現在のAPIは、HTTP/1.1のプロトコルの一部のみ実装されています。
より先進的な機能、例えば永続的接続などは将来のバージョンで追加されるでしょう。
@c COMMON

@c EN
If you're looking a library to write HTTP @emph{server}, see
Gauche-makiki (@url{https://github.com/shirok/Gauche-makiki}).
@c JP
HTTPサーバを書くためのライブラリを探しているなら、
Gauche-makikiを見てください (@url{https://github.com/shirok/Gauche-makiki})。
@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

@menu
* Http client mid-level API::
* Http client utilities::
* Secure http connection::
@end menu

@node Http client mid-level API, Http client utilities, HTTP client, HTTP client
@subsection Http client mid-level API
@c NODE HTTPクライアント中間レベルAPI

@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

@node Http client utilities, Secure http connection, Http client mid-level API, HTTP client
@subsection Http client utilities
@c NODE HTTPクライアントユーティリティ

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

@c EN
This is built on top of @code{uri-compose-query} in @code{rfc.uri}
(@pxref{URI parsing and construction}).
@c JP
これは@code{rfc.uri}モジュールの@code{uri-compose-query}手続きの上に
作られています (@ref{URI parsing and construction}参照)。
@c COMMON
@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

@node Secure http connection,  , Http client utilities, HTTP client
@subsection Secure http connection
@c NODE セキュアhttpコネクション

@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 client, 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

@c EN
@subheading Parsing JSON
@c JP
@subheading JSONのパーズ
@c COMMON

@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

@c EN
@subheading Constructing JSON
@c JP
@subheading JSONの構築
@c COMMON

@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

@deftp {Class} <json-mixin>
@c MOD rfc.json
@c EN
A Gauche object of a class inheriting this mixin class is automatically
serialized to JSON object with the following rule:
@c JP
このmixinクラスを継承しているクラスのインスタンスは、以下の規則を使って
自動的にJSONオブジェクトにシリアライズされます。
@c COMMON

@itemize @bullet
@item
@c EN
Each slot of the object is examined. Only the slots
with its slot definition has a true value in @code{:json-name}
option are the subject to be serialized.
@c JP
オブジェクトのスロットのうち、@code{:json-name}がそのスロット定義オプション
に含まれていて偽でないもののみがシリアライズの対象となります。
@c COMMON
@item
@c EN
If @code{:json-name} option is @code{#t}, the slot name is used
as the key; otherwise, string representation (@code{x->string})
of the option's value is used as the key.
@c JP
@code{:json-name}スロット定義オプションが@code{#t}ならばスロット名が
キーとして使われ、そうでなければその値を@code{x->string}で文字列化したものがキー
として使われます。
@c COMMON
@item
@c EN
Then the slot value is serialized recursively.
@c JP
スロットの値が再帰的にシリアライズされます。
@c COMMON
@end itemize

@example
(define-class <foo> (<json-mixin>)
  ((slot-1 :init-keyword :slot-1 :json-name "Slot1")
   (slot-2 :init-keyword :slot-2 :json-name #t)
   (slot-3 :init-keyword :slot-3)))

(construct-json
  (make <foo> :slot-1 "xyz" :slot-2 123 :slot-3 'abc))
 @result{} @r{prints}
 @{"Slot1":"xyz","slot-2":123@}
@end example
@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

@c EN
Typically, all you need to do is to pass the class object @code{<md5>}
to the message
digester; @pxref{Message digester framework}, and also
@pxref{HMAC keyed-hashing}.
@c JP
通常、メッセージダイジェストを行う手続きにクラスオブジェクト@code{<md5>}
を渡すだけで使うことができます。
詳しくは@ref{Message digester framework}および
@ref{HMAC keyed-hashing}を参照してください。
@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,
so you can pass this class to message digest procedures such as
@code{digest-message-to} (@pxref{Message digester framework}).
@c JP
このクラスのインスタンスは、MD5ダイジェストアルゴリズムの内部状態を
保持しています。
このクラスは、@code{util.digest}フレームワークのインターフェース、
を実装しており、
メッセージダイジェストを行う@code{digest-message-to}などの手続きに
このクラスオブジェクトを渡すことができます(@ref{Message digester framework}参照)。
@c COMMON
@end deftp

@c EN
The following procedures are deprecated.  Use generic
message digester (@pxref{Message digester framework}) or
HMAC keyed digester (@pxref{HMAC keyed-hashing}).
@c JP
以下の手続きは非推奨です。
ジェネリックなメッセージダイジェスター(@ref{Message digester framework}参照)や、
HMAC鍵つきダイジェスター(@ref{HMAC keyed-hashing}参照)を使ってください。
@c COMMON

@defun md5-digest
@c MOD rfc.md5
@c DEPRECATED
@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 DEPRECATED
@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 client}).
@c JP
このモジュールは主としてビルディングブロックとなる低レベルの手続きに
フォーカスしており、アプリケーション特有のモジュールがこの上に
構築されることを意図しています。例えば@code{rfc.http}はPOSTリクエストの
ボディを@code{multipart/form-data}として構築する際にこのモジュールを
利用します(@ref{HTTP client}参照)。
@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

@c EN
@subheading Utilities for header fields
@c JP
@subheading ヘッダフィールドのユーティリティ
@c COMMON

@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

@example
(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 example
@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} is other
than @code{utf-8} 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}の指定が@code{utf-8}以外で、
@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

@c EN
@subheading Streaming parser
@c JP
@subheading ストリーミングパーザ
@c COMMON

@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

@c EN
@subheading Message composer
@c JP
@subheading メッセージの構築
@c COMMON

@defun mime-compose-message parts :optional port :key boundary
@defunx mime-compose-message-string parts :key boundary
@c MOD rfc.mime
@c EN
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.
@c JP
MIMEマルチパートメッセージを構築します。
@code{mime-compose-message}は結果を@var{port}(省略時は現在の出力ポート)
に書き出します。@code{mime-compose-message-string}は結果を文字列で返します。
バウンダリ文字列を@var{boundary}引数で渡すことができます。省略された場合は
新しいバウンダリ文字列が下の@code{mime-make-boundary}によって作られます。
@c COMMON

@c EN
@code{Mime-compose-message} returns the boundary string.
@code{Mime-compose-message-string} returns two values, the result
string and the boundary string.
@c JP
@code{mime-compose-message}はバウンダリ文字列を、
@code{mime-compose-message-string}は構築されたメッセージ文字列と
バウンダリ文字列の二つの値を返します。
@c COMMON

@c EN
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.
@c JP
メッセージの内容は@var{parts}引数で与えます。これは
上で説明した@code{<mime-part>}のインスタンスのリストか、
もしくはパートを記述するリストのリストです。後者は簡便のためにサポートされていて、
内部的には@code{<mime-part>}のリストに変換されます。
@c COMMON

@c EN
The syntax of each part element in @var{parts} are defined as follow.
@c JP
@var{part}のリストの各要素は以下の形式を取ります。
@c COMMON

@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

@c EN
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.
@c JP
@code{<header>}の最初の形式において、
@code{<encoded-header-value>}は、元の値がASCII以外の文字を含んでいる場合、
呼び出し側でRFC2047やRFC2231であらかじめエンコードしておかなければなりません。
二番目の形式では、自動的にRFC2231によるエンコードを行う予定がありますが、
今はまだ実装されていません。二番目の形式でエンコード済みの値を渡してしまうと、
将来のバージョンで二重にエンコードされる可能性があるので、
二番目の形式ではASCII文字のみを使ってください。
@c COMMON

@c EN
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.
@c JP
@code{<body>}が文字列の場合はそれがそのままパートの内容として使われます。
@code{<body>}が@code{(file @var{filename})}の場合は、
指定されたファイルが読み込まれてその内容が使われます。
@code{<body>}が@code{(subparts @var{part} @dots{})}の場合は、
ネストされたMIMEパートになります。
@c COMMON

@c EN
It is the caller's responsibility to match the content type and the content.
For example, if @code{<body>} is in the third form, the
part must have @code{multipart} content type.
@c JP
パートのcontent-typeと内容を一致させるのは呼び出し側の責任です。
例えば@code{<body>}がネストしたMIMEパートである場合は、
content-typeは@code{multipart}でなければなりません。
@c COMMON

@c EN
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.
@c JP
アプリケーションによっては、@code{content-transfer-encoding}ヘッダを適切に
与えることも重要です。@code{content-transfer-encoding}ヘッダが与えられない場合、
内容はそのままMIMEメッセージ中に挿入されます。
アプリケーションによってはそれでも良いのですが、
例えばemailで送る場合は、バイナリの内容はbase64でエンコードするなどの配慮が必要です。
@c COMMON
@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-message message :key line-width binary
@c MOD rfc.quoted-printable
@c EN
Converts content of @var{message}, which can be either a string
or a u8vector, to a string of Quoted-printable encoded format.

The keyword arguments are the same as @code{quoted-printable-encode}.
@c JP
文字列かu8vectorの@var{message}の内容を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-to target string
@c MOD rfc.quoted-printable
@c EN
Decodes a Quoted-printable encoded string @var{string}, and returns
the result as an instance of @var{target}, which must be
either @code{<string>} or @code{<u8vector>}.
@c JP
Quoted-printableエンコードされた文字列@var{string}をデコードし、
その結果を@var{target}のインスタンスで返します。
@var{target}は@code{<string>}か@code{<u8vector>}でなければなりません。
@c COMMON
@end defun


@defun quoted-printable-encode-string string :key line-width binary
@c MOD rfc.quoted-printable
@c DEPRECATED
@c EN
This is for the backward compatibility.
Use @code{quoted-printable-encode-message} instead.
@c JP
これは互換性のために残してある手続きです。
@code{quoted-printable-encode-message}を使うようにしてください。
@c COMMON
@end defun

@defun quoted-printable-decode-string string
@c MOD rfc.quoted-printable
@c DEPRECATED
@c EN
This is for the backward compatibility.  It is same as
@code{(quoted-printable-decode-string-to <string> string)}.
@c JP
これは互換性のために残してある手続きです。
@code{(quoted-printable-decode-string-to <string> 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 Algorithms.
It provides SHA-1, SHA-2, and SHA-3.

The module extends util.digest
(@pxref{Message digester framework}).
@c JP
このモジュールは、RFC 4634で定義されている
US Secure Hash Algorithmを実装しています。
提供されるアルゴリズムはSHA-1, SHA-2, SHA-3を実装しています。

このモジュールは、util.digest (@ref{Message digester framework}参照)
を拡張しています。
@c COMMON

@c EN
Typically, all you need to do is to pass the class object @code{<sha256>} etc.
to the message
digester; @pxref{Message digester framework}, and also
@pxref{HMAC keyed-hashing}.
@c JP
通常、メッセージダイジェストを行う手続きにクラスオブジェクト@code{<sha256>
}等を渡すだけで使うことができます。
詳しくは@ref{Message digester framework}および
@ref{HMAC keyed-hashing}を参照してください。
@c COMMON

@end deftp

@deftp {Module} rfc.sha1
@mdindex rfc.sha1
@c DEPRECATED
@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>
@deftpx {Class} <sha3-224>
@deftpx {Class} <sha3-256>
@deftpx {Class} <sha3-384>
@deftpx {Class} <sha3-512>
@clindex sha1
@clindex sha224
@clindex sha256
@clindex sha384
@clindex sha512
@clindex sha3-224
@clindex sha3-256
@clindex sha3-384
@clindex sha3-512
@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,
so you can pass this class to message digest procedures such as
@code{digest-message-to} (@pxref{Message digester framework}).
@c JP
これらのクラスのインスタンスは、SHAダイジェストアルゴリズムの内部状態を
保持しています。
このクラスは、@code{util.digest}フレームワークのインターフェース、
を実装しており、
メッセージダイジェストを行う@code{digest-message-to}などの手続きに
このクラスオブジェクトを渡すことができます(@ref{Message digester framework}参照)。
@c COMMON

@c EN
Classes @code{<sha224>}, @code{<sha256>}, @code{<sha384>}, and @code{<sha512>}
implement SHA-2.  Classes @code{<sha3-256>}, @code{<sha3-384>}, and
@code{<sha3-512>} implement SHA-3.
@c JP
@code{<sha224>}、@code{<sha256>}、@code{<sha384>}、@code{<sha512>}の
各クラスはSHA-2を実装しています。
@code{<sha3-256>}、@code{<sha3-384>}、@code{<sha3-512>}の各クラスは
SHA-3を実装しています。
@c COMMON
@end deftp

@c EN
The following procedures are deprecated.  Use generic
message digester (@pxref{Message digester framework}) or
HMAC keyed digester (@pxref{HMAC keyed-hashing}).
@c JP
以下の手続きは非推奨です。
ジェネリックなメッセージダイジェスター(@ref{Message digester framework}参照)や、
HMAC鍵つきダイジェスター(@ref{HMAC keyed-hashing}参照)を使ってください。
@c COMMON

@defun sha1-digest
@defunx sha224-digest
@defunx sha256-digest
@defunx sha384-digest
@defunx sha512-digest
@defunx sha3-224-digest
@defunx sha3-256-digest
@defunx sha3-384-digest
@defunx sha3-512-digest
@c MOD rfc.sha
@c DEPRECATED
@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
@defunx sha3-224-digest-string string
@defunx sha3-256-digest-string string
@defunx sha3-384-digest-string string
@defunx sha3-512-digest-string string
@c MOD rfc.sha
@c DEPRECATED
@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 client}).
@c JP
このモジュールはTCPソケット上のセキュアな接続を処理します。
@code{rfc.http}で、https接続を実現するのに使われています
(@ref{HTTP client}参照)。
@c COMMON
@end deftp

@subheading TLS subsystems

@c EN
Whether the running Gauche has TLS support depends on the build
options, and can be checked with
a feature identifier @code{gauche.net.tls}.
@xref{Feature conditional}, for more about feature identifiers.
@c JP
実行中のGaucheがTLSをサポートしているかどうかは機能識別子
@code{gauche.net.tls}で判別できます。
機能識別子については@ref{Feature conditional}を参照してください。
@c COMMON

@c EN
Gauche uses MbedTLS (@url{https://tls.mbed.org/}) as TLS implementation.
We used to support alternative subsystems, so the library is designed
to handle multiple subsystems.  In future we may support additional subsystems.
@c JP
GaucheはTLS実装としてMbedTLS(@url{https://tls.mbed.org/})を使っています。
以前は複数のTLSサブシステムをサポートしていたので、ライブラリは複数のサブシステムを
切り替えて使えるようになっています。将来また別のTLSサブシステムをサポートするかもしれません。
@c COMMON

@deftp {Class} <tls>
@clindex tls
@c MOD rfc.tls
@c EN
An abstract base class of a TLS implementation.
You can use its instance to communicate with peer over secure connection.
You usually don't need to care the concrete subclass; just treat
their instances as @code{<tls>} instance.

This inherits @code{<connection>} (@pxref{Connection framework}).
@c JP
TLS実装のベースクラスです。このクラスのインスタンスを使って、
セキュアなコネクションを張って通信ができます。
通常、具体的なサブクラスを気にする必要はありません。

このクラスは@code{<connection>}を継承します (@ref{Connection framework}参照)。
@c COMMON
@end deftp

@deftp {Class} <mbed-tls>
@clindex mbed-tls
@c MOD rfc.tls
@c EN
A class that implements MbedTLS subsystem interface.
@c JP
MbedTLSサブシステムを実装しているクラスです。
@c COMMON
@end deftp

@deffn {Parameter} default-tls-class
@c MOD rfc.tls
@c EN
The default TLS subsystem to be used.  In the current version,
it may just be @code{<mbed-tls>}, or @code{#f} if the system is not
compiled with TLS support.
@c JP
デフォルトのTLSサブシステムです。現在のバージョンでは、
これは@code{<mbed-tls>}クラスか@code{#f}です。
@code{#f}は、GaucheがTLSをサポートしていないことを示します。
@c COMMON
@end deffn

@c EN
@subheading TLS common operations
@c JP
@subheading TLS共通の操作
@c COMMON

@defun make-tls initargs @dots{}
@c MOD rfc.tls
@c EN
Creates and returns a new TLS instance of the class @code{default-tls-class}.
The returned TLS instance can be used either as a client, by passing it
to @code{tls-connect}, or as a server, by passing it to @code{tls-bind}
and @code{tls-accept}.  See the following subsections for each usage.
@c JP
新たなTLSインスタンスを作って返します。インスタンスの具体的なクラスは
@code{default-tls-class}の値が使われます。
TLSインスタンスは@code{tls-connect}に渡すことでクライアントとして使ったり、
@code{tls-bind}と@code{tls-accept}に渡すことでサーバーとして使うことができます。
以下のそれぞれのサブセクションを参照してください。
@c COMMON

@c EN
The arguments must be a keyword-value list, and passed to the constructor
of the TLS class.
The following keyword arguments are recognized.
@c JP
引数はTLSクラスに渡されるキーワード-値リストでなければなりません。
以下のキーワード引数が認識されます。
@c COMMON

@table @code
@item :server-name
@c EN
Server name to be used for TLS Server Name Indication extension.
In general, if you use the created TLS object as a client,
you want to specify the server name.  If you use the create TLS object
as a server, you can omit this option.
@c JP
TLS Server Name Indication拡張に使うサーバー名を指定します。
一般的には、TLSオブジェクトをクライアントとして使う場合に接続先サーバ名を渡します。
サーバとして使う場合は必要ありません。
@c COMMON
@item :skip-verification
@c EN
Client only.  If the argument is true, skip server certificate
verification upon connection.
This is unsafe and should not be used except experimental purposes.
@c JP
クライアントのみ。この引数が真の値の場合、接続時の証明書の認証を省略します。
これは危険な動作なので、実験目的以外では使わないでください。
@c COMMON
@end table
@end defun

@defun tls-close tls
@c MOD rfc.tls
@c EN
Shuts down the underling connection.  The peer will notified
the connection is closed.
Once @var{tls} is closed, it can no longer be used.

You can also call @code{connection-close} on @var{tls} to get the same effect
(@pxref{Connection framework}).
@c JP
TLSコネクションを閉じます。通信相手は接続が閉じられたことを知ります。
@var{tls}がひとたびクローズされるとそれはもう使うことができません。

@var{tls}に対し@code{connection-close}を呼び出すことでも同じ動作になります
(@ref{Connection framework}参照)。
@c COMMON
@end defun

@defun tls-input-port tls
@defunx tls-output-port tls
@c MOD rfc.tls
@c EN
If @var{tls} is connected, they return input and output port to communicate
with the peer, respectively.

If @var{tls} is not connected, @code{#f} is returned.

You can also call @code{connection-input-port} and @code{connection-output-port}
on @var{tls} got get the same efffect
(@pxref{Connection framework}).
@c JP
@var{tls}が接続状態にある時、これらは相手と通信するための入力ポートと出力ポートを
それぞれ返します。

@var{tls}が接続状態に無い時にこれらを呼ぶと@code{#f}が返されます。

@var{tls}に対し@code{connection-input-port}および
@code{connection-output-port}を呼び出すことでも同じ動作になります
(@ref{Connection framework}参照)。
@c COMMON
@end defun

@defun tls-poll tls rw :optional timeout
@c MOD rfc.tls
@c EN
Wait for @var{tls} to be ready for reading or writing.  The tls object must
be already bound or connected; otherwise, it immediately returns @code{()}.

The @var{rw} argument is a list of symbols @code{read} and/or @code{write},
to specify what condition(s) to be checked.  The @var{timeout} argument
is either a @code{<time>} object to specify an absolute time point,
a real number to specify the number of seconds from the current time,
or @code{#f} to wait indefinitely.  If omitted, @code{#f} is assumed.

The return value is a list of symbols that are satisfied.  That is,
if you pass @code{(read)} or @code{(read write)} in @var{rw} and the
tls communication is ready to read, @code{(read)} is returned.
If timeout reaches before any condition is met, @code{()} is returned.
@c JP
@var{tls}が読み込みもしくは書き込み可能になるまで待ちます。@var{tls}は既に
bindされているか接続されていなければなりません。そうでない場合は直ちに@code{()}が
返されます。

@var{rw}はシンボル@code{read}、@code{write}の組み合わせのリストで、
待つべき条件を指定します。@var{timeout}引数は、
時刻を指定する@code{<time>}オブジェクトか、
現在からの経過時間を秒で指定する実数値か、
タイムアウトしないことを指示する@code{#f}です。省略時は@code{#f}が使われます。

戻り値は満たされた条件のリストです。例えば@var{rw}引数に
@code{(read)}もしくは@code{(read write)}を指定して、tlsが読み込み可能になったら
@code{(read)}が返されます。条件が満たされる前にタイムアウトした場合は@code{()}が
返されます。
@c COMMON
@end defun

@defun tls-debug-level-set! level
@c MOD rfc.tls
@c EN
This is for troubleshooting.  Set the global debug log level of
the TLS subsystem to @var{level}, which is an exact integer between
0 (no debug logging, default) to 9 (maximum debug logging).

The actual granularity of log levels depends on the TLS subsystem,
and 0-9 scale is mapped to each subsystem's logging mechanism.
You want some experiment to find appropriate value.
@c JP
これはトラブルシューティング用のAPIです。
TLSサブシステムのグローバルなデバッグログレベルを@var{level}に設定します。@var{level}
は0(ログなし、デフォルト)から9(ログ最大)までの正確な整数です。

実際のログ段階の細かさは各TLSサブシステムにより、0-9のレベルがサブシステムのサポートする
段階へとマップされます。いくらか試行して適切な値を見つけてください。
@c COMMON
@end defun

@c EN
@subheading TLS client
@c JP
@subheading TLSクライアント
@c COMMON

@c EN
When your code is a client to connect to a server over TLS,
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
クライアントとしてサーバにTLS接続する場合、
サーバの認証を適切に行うために、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 tools/get-cacert
@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

@defun tls-connect tls host port :optional proto
@c MOD rfc.tls
@c EN
Establishes TLS connection as a client.

The @var{tls} argument must be an unconnected TLS object.  The
@var{host} and @var{port} arguments are strings to specify
server's hostname and port.  Besides the common hostname, IP notation
(e.g. @code{"127.0.0.1"} or @code{"[::1]"}) are allowed in @var{host}.
Integre port number or a service name (e.g. @code{"https"})
are allowed in @var{port}.
The @var{proto} argument must be either one of the symbols
@code{tcp} or @code{udp}.  If omitted, @code{tcp} is assumed.
(If it is @code{udp}, DTLS is used instead of TLS.  However, we still
lack some additional API support to make DTLS usable.)
@c JP
クライアントとして、指定されたサーバにTLSで接続します。

@var{tls}引数はまだ接続されていないTLSオブジェクトでなければなりません。
@var{host}と@var{port}は文字列で、それぞれサーバのホスト名とポートを指定します。
ホスト名についてはドメイン名のほか、IP表記が使えます
(例: @code{"127.0.0.1"}、@code{"[::1]"})。
ポートについては整数のポート番号も名前による指定(例: @code{"https"})も使えます。
@var{proto}引数はシンボル@code{tcp}か@code{udp}のどちらかでなければならず、
省略時は@code{tcp}とみなされます
(@var{udp}を指定した場合はTLSのかわりにDTLSが使われることになりますが、
今はDTLSを実用的に使うために必要なAPIがいくつか未実装です。)
@c COMMON

@c EN
Once the procedure contacted to the server,
it obtains its server certificate and tries to validate it
against the known CA certificates.  If the server can't be validated,
an error is signaled.  To establish a proper connection,
a CA certificate storage must be specified
by the parameter @code{tls-ca-bundle-path}.
@c JP
サーバにコンタクトできたら、この手続きはサーバ証明書を入手して
CA証明書を使ってバリデーションを試みます。
バリデーションが失敗したらエラーが投げられます。正しく接続を確立するには、
有効なCA証明書ストアがパラメータ@code{tls-ca-bundle-path}で指定されていなければ
なりません。
@c COMMON

@c EN
Once the connection is established and TLS handshake is succeeded,
the passed @var{tls} becomes 'connected' state and
can be used to read/write data from/to the connected peer.
@c JP
接続が確立してTLSハンドシェイクが成功したら、
引数に渡した@var{tls}オブジェクトはconnected状態になり、
相手とデータをやりとりすることができます。
@c COMMON
@end defun

@c EN
@subheading TLS server
@c JP
@subheading TLSサーバー
@c COMMON

@c EN
To open a TLS connection as a server, you have to prepare
a private key, a server certificate, and
intermediate certificates.  Those must be loaded before accepting
TLS connections from clients.
@c JP
TLSコネクションをサーバとして使うには、秘密鍵、サーバ証明書、および中間証明書を
用意する必要があります。これらはクライアントからのTLS接続を受け付ける前に
読み込まれている必要があります。
@c COMMON

@defun tls-load-certificate tls path
@c MOD rfc.tls
@c EN
Read and register server certifcate(s) stored in a file named by @var{path}.
The given file may contain multiple certificates.  You can call this
multiple times to add intermediate certifictes.
@c JP
@var{path}で示されるファイルに格納されたサーバ証明書を読み込みます。
ファイル中に複数の証明書を含めることができます。また、この関数は複数回呼び出せて、
@var{tls}に中間証明書を追加してゆくことができます。
@c COMMON
@end defun

@defun tls-load-private-key tls path password
@c MOD rfc.tls
@c EN
Read and register server private key storead in a file named by @var{path},
with the @var{password}.  If the private key file is not encrypted,
you can pass @code{#f} to @var{password}.
@c JP
@var{path}で示されるファイルに格納されたサーバの秘密鍵を読み出して登録します。
秘密鍵が暗号化されている場合は@var{password}にパスワードを指定します。
秘密鍵が暗号されていない場合は@var{password}に@code{#f}を渡します。
@c COMMON
@end defun

@defun tls-bind tls host port :optional proto
@c MOD rfc.tls
@c EN
Creates a server endpoint of tls connection.

The @var{tls} argument must be an unconnected, unbound TLS object.
The @var{host} argument may be a string hostname or @code{#f}.
The @var{port} argument is an integer or a string to specify the port.
The @var{proto} argument must be either one of the symbols
@code{tcp} or @code{udp}, and assumed @code{tcp} if omitted.
(NB: @var{udp} server (DTLS) needs some more API support, so
it is not very usable now.)
@c JP
TLS接続のサーバー側エンドポイントを作ります。

@var{tls}引数はまだ接続もbindもされていないTLSオブジェクトでなければなりません。
@var{host}引数は文字列のホスト名か@code{#f}です。
@var{port}引数は整数のポート番号か文字列によるポート名です。
@var{proto}にはシンボル@code{tcp}か@code{udp}を渡します。
省略時は@code{tcp}が仮定されます。
(NB: @var{udp}サーバー (DTLS) を使うにはいくつか追加のAPIサポートが
必要なので、今のところDTLSは使えません)。
@c COMMON

@c EN
Like @code{socket-bind}, you can give 0 to @var{port} to let the
system choose an available port number.  The actual port number
can be obtained by
@code{(sockaddr-port (connection-self-address @var{tls}))}.
@c JP
@code{socket-bind}と同じように、@var{port}に0を指定することで、
空いているポート番号をシステムに選んでもらうことができます。
実際にどのポートにバインドされたかは
@code{(sockaddr-port (connection-self-address @var{tls}))}
でわかります。
@c COMMON
@end defun

@defun tls-accept tls
@c MOD rfc.tls
@c EN
The passed tls object must already be bound by @code{tls-bind}.
Server certificates and private key must be already loaded to @var{tls}
by @code{tls-load-certificate} and @code{tls-load-private-key}.

This waits for a client to connect to the bound endpoint.  Once
a client tries to connect, it present the server certificate
and performs TLS handshake.  If everything succeeds,
returns a fresh @var{tls} object that can be used
to read/write dat from/to the connected peer.
@c JP
引数の@var{tls}は、@code{tls-bind}でバインドされたTLSオブジェクトでなければなりません。
サーバ証明書と秘密鍵は@code{tls-load-certificate}および@code{tls-load-private-key}
によって@var{tls}にロードされていなければなりません。

この手続きはクライアントの接続要求を待ちます。接続要求が来たら、
サーバ証明書をクライアントに提示し、TLSハンドシェークを行います。
全てが成功すれば、クライアントに接続された新たな@var{tls}オブジェクトを作って返します。
@c COMMON
@end defun

@c EN
@subheading Connection methods
@c JP
@subheading コネクションメソッド
@c COMMON

@c EN
Since @code{<tls>} class implements connection framework
(@pxref{Connection framework}), the following methods
can be called on a tls object.  Notably, the first two
can be used to obtain IP address of the underlying connection.
@c JP
@code{<tls>}クラスはコネクションフレームワークを実装しているので、
以下のメソッドがtlsオブジェクトに対して使えます。特に最初の2つは
下位にあるコネクションのIPアドレスを得るのに使えます。
@c COMMON

@example
connection-self-address (c <tls)
connection-peer-address (c <tls>)
connection-input-port (c <tls>)
connection-output-port (c <tls>)
connection-close (c <tls>)
@end example

@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

@c EN
First, lets review the structure of URI briefly.
The following graph shows how the URI is constructed:
@c JP
はじめに、URIの構造をざっとみておきましょう。次のグラフはURIがどのように構築されるかを
示しています。
@c COMMON

@example
URI-+-scheme
    |
    +-specific--+--authority-+--userinfo
                |            +--host
                |            +--port
                +--path
                +--query
                +--fragment
@end example

@c EN
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.
@c JP
全てのURIがここに示される完全な木構造を備えているわけではありません。
例えば@code{mailto:admin@@example.com}は@emph{scheme} (@code{mailto})
と @emph{specific} (@code{admin@@example.com}) だけから構成されます。
@c COMMON

@c EN
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/}.
@c JP
しかし、良く使われるURIのほとんどはリソースを木構造で管理するので、
@emph{authority} (通常はサーバ)と階層的な@var{path}を持ちます。
@code{http://example.com:8080/search?q=key#results}では、
authorityは@code{example.com:8080}、pathは@code{/search}、
queryは@code{key}で、fragmentが@code{results}です。
userinfoはあればホスト名の前に付加されます。例えば
@code{ftp://anonymous@@example.com/pub/}における@code{anonymous}です。
@c COMMON

@c EN
We have procedures that decompose a URI into those parts,
and that compose a URI from those parts.
@c JP
URIをこれらの部分に分解する手続きと、
部分からURIを組み立てる手続きが提供されます。
@c COMMON

@c EN
@subheading Parsing URI
@c JP
@subheading URIのパーズ
@c COMMON

@defun uri-ref uri parts
@c MOD rfc.uri
@c EN
Extract specific part(s) from the given URI.  This module offers
a set of procedures to fully decompose URI, but in actual
applications, you often need only some of the parts.  This procedure
comes handy for it.
@c JP
与えられたURIから、指定部分を抜き出します。
このモジュールはURIを完全に分解する手続きも提供していますが、
現実のアプリケーションでは特定部分のみを取り出したい場合も多く、
この手続きはそういう場合に便利に使えます。
@c COMMON

@c EN
The @var{parts} argument may be a symbol, or a list of symbols,
to name the desired parts.  The recognized symbos are as follows.
@c JP
@var{parts}引数はシンボルもしくはシンボルのリストで、
抜き出したい部分を指定します。指定可能なシンボルは以下の通りです。
@c COMMON

@table @code
@item scheme
@c EN
The scheme part, as string.
@c JP
schemeパートを文字列で抜き出します。
@c COMMON
@item authority
@c EN
The authority part, as string.
If URI doesn't have the part, @code{#f}.
@c JP
authorityパートを文字列で抜き出します。
URIにauthorityパートが無ければ@code{#f}が返されます。
@c COMMON
@item userinfo
@c EN
The userinfo part, as string.  If URI doesn't have the part, @code{#f}.
@c JP
userinfoパートを文字列で抜き出します。
URIにuserinfoパートが無ければ@code{#f}が返されます。
@c COMMON
@item host
@c EN
The host part, as string.  If URI doesn't have the part, @code{#f}.
@c JP
hostパートを文字列で抜き出します。
URIにhostパートが無ければ@code{#f}が返されます。
@c COMMON
@item port
@c EN
The port part, as integer.  If URI doesn't have the part, @code{#f}.
@c JP
portパートを文字列で抜き出します。
URIにportパートが無ければ@code{#f}が返されます。
@c COMMON
@item path
@c EN
The path part, as string.  If URI isn't hierarchical, this returns
the specific part.
@c JP
pathパートを文字列で抜き出します。
URIが階層的でない場合は、specificパートが返されます。
@c COMMON
@item query
@c EN
The query part, as string. If URI doesn't have the part, @code{#f}.
@c JP
queryパートを文字列で抜き出します。
URIにqueryパートが無ければ@code{#f}が返されます。
@c COMMON
@item fragment
@c EN
The fragment part, as string.  If URI doesn't have the part, @code{#f}.
@c JP
fragmentパートを文字列で抜き出します。
URIにfragmentパートが無ければ@code{#f}が返されます。
@c COMMON
@item scheme+authority
@c EN
The scheme and authority part, as string
@c JP
schemeパートとauthorityパートの部分を文字列で。
@c COMMON
@item host+port
@c EN
The host and port part, as string.
@c JP
hostパートとportパートの部分を文字列で。
@c COMMON
@item userinfo+host+port
@c EN
The userinfo, host and port part, as string.
@c JP
usertinfoパート、hostパート、portパートの部分を文字列で。
@c COMMON
@item path+query
@c EN
The path and query part.
@c JP
pathパートとqueryパートの部分を文字列で。
@c COMMON
@item path+query+fragment
@c EN
The path, query and fragment part.
@c JP
pathパートとqueryパートとfragmentパートの部分を文字列で。
@c COMMON
@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

@c EN
You can extract multiple parts at once by specifying a list of parts.
A list of parts is returned.
@c JP
@var{parts}に抜き出したい部分を指定するリストを渡すと、
それぞの部分のリストが返されます。
@c COMMON

@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-query query-string :key separators
@c MOD rfc.uri
@c EN
Decompose query string such as @code{"foo=abc&bar"} into
a list of parameters @code{(("foo" ""abc") ("bar" #t)},
where each parameter is represented by a list of its name (string) and
value (string or @code{#t}).

If you're writing a CGI script, @code{cgi-parse-parameters}
in @code{www.cgi} is handier, for it
integrates handling of query string, form parameters,
and cookies, on top of this procedure (@pxref{CGI utility}).
@c JP
クエリ文字列(例: @code{"foo=abc&bar"}) を、
パラメータのリスト(例: @code{(("foo" ""abc") ("bar" #t)})へと分解します。
各パラメータは名前(文字列)と値(文字列または@code{#t})のリストで表されます。

CGIスクリプトを書いているなら、@code{www.cgi}モジュールの
@code{cgi-parse-parameters}の方が便利でしょう。この手続きの上に、
フォームパラメータやクッキーの取扱いなどを統合的に扱えるからです
(@ref{CGI utility}参照)。
@c COMMON

@itemize @bullet
@item
Each parameter name and value is urldecoded.
@item
If there are multiple parameters with the same name, they are
@emph{not} merged.
@example
(uri-decompose-query "a=b&a=c") @result{} (("a" "b") ("a" "c"))
@end example
@item
If the parameter isn't given a value, its value in the output is @code{#t}.
@example
(uri-decompose-query "a&b") @result{} (("a" #t) ("b" #t))
@end example
@item
The order of input parameters is preserved.
@end itemize
@c JP
@itemize @bullet
@item
各パラメータ名と値はそれぞれurldecodeされます。
@item
同名のパラメータが複数ある場合、それらは統合されず、別々の要素として出力に現れます。
@example
(uri-decompose-query "a=b&a=c") @result{} (("a" "b") ("a" "c"))
@end example
@item
値を持たないパラメータについては、出力の値は@code{#t}となります。
@example
(uri-decompose-query "a&b") @result{} (("a" #t) ("b" #t))
@end example
@item
パラメータの順序は保存されます。
@end itemize
@c COMMON

@c EN
The optional @var{separators} argument takes a char-set object
to be used to separate each parameters.  The default is
@code{#[&;]}, for historically both @code{&} and @code{;} can be used.
However, some application only allows @code{&}.
@c JP
省略可能引数@var{separators}には、パラメータの区切りに使われる文字集合を指定します。
デフォルトは@code{#[&;]}です。歴史的に@code{&}と@code{;}の両方が区切りに使われてきたので。
ただ、アプリケーションによっては@code{&}しか受け付けない場合があります。
@c COMMON

@c EN
See also @code{url-compose-query} below, for the inverse of this procedure.
@c JP
この手続きの逆関数については下の@code{url-compose-query}を見てください。
@c COMMON
@end defun


@defun uri-decompose-data uri
@c MOD rfc.uri
@c EN
Parse a Data schemed @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 scheme形式の@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
 "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-query params :optional encoding
@c MOD rfc.uri
@c EN
The argument @var{params} is a list of parameter specs.  Each parameter
spec must be in the form of @code{(@var{name} @var{value})}, where @var{name}
is a string and @var{value} is either a string or @code{#t}
(see @code{url-decompose-query} above).

Each parameter's name and value is urlencoded and concatenated
as a url query string.  If a parameter's value is @code{#t},
the output only includes parameter's name but not value.
@c JP
@var{params}はパラーメータ指定のリストです。各パラメータ指定は
@code{(@var{name} @var{value})}の形式で、@var{name}は文字列、
@var{value}は文字列もしくは@code{#t}です
(上の@code{url-decompose-query}も参照)。

各パラメータの名前と値はurlencodeされてから、URLのクエリパラメータとして結合されます。
パラメータの値が@code{#t}の場合は、名前だけのパラメータとなります。
@c COMMON

@example
(uri-compose-query '(("foo" "abc") ("bar" #t)))
  @result{} "foo=abc&bar"
@end example

@c EN
The optional @var{encoding} argument specifies character encoding
of the output.  The default is @code{utf-8}.  If it is other than that,
the strings are converted to the specified encoding before urlencoding.
@c JP
省略可能な@var{encoding}引数はパラメータの文字エンコーディングを指定します。
デフォルトは@code{utf-8}です。それ以外の場合は、各文字列はその文字エンコーディングに
変換された後でurlencodeされます。
@c COMMON

@c EN
A higher-level utility, @code{http-compose-query} in @code{rfc.http},
is build on top of this
(@pxref{Http client utilities}).
@c JP
@code{rfc.http}の@code{http-compose-query}はこの手続きの上に作られた
ユーティリティです(@ref{Http client utilities}参照)。
@c COMMON
@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
@c EN
This module implements UUID defined in RFC9562.

It provides generators of UUID version 1, 4, 6 and 7, and writer/parser
of the string represenation of UUIDs.
@c JP
RFC9562で定義されたUUIDを実装しています。

UUIDバージョン1、4、6、7を生成する機能、及びUUIDの文字列表記をパーズしたり
バイナリから文字列表記を生成する機能が提供されます。
@c COMMON
@end deftp

@deftp {Class} <uuid>
@c MOD rfc.uuid
@c EN
Class of UUID instances.  UUID instances are immutable.
@c JP
UUIDクラスです。UUIDインスタンスは変更不可なオブジェクトです。
@c COMMON
@end deftp

@c EN
@subheading Common uuid operations
@c JP
@subheading uuid共通の操作
@c COMMON

@defun uuid-value uuid
@c MOD rfc.uuid
@c EN
Returns the raw value of @var{uuid} as 16-element @code{u8vector}.
You shouldn't mutate the returned u8vector.
@c JP
UUID @var{uuid}の「生の」値を、16要素の@code{u8vector}として返します。
返されたベクタを変更してはいけません。
@c COMMON
@end defun

@defun uuid-version uuid
@c MOD rfc.uuid
@c EN
Returns the version number of @var{uuid}.
@c JP
@var{uuid}のバージョン番号を返します。
@c COMMON
@end defun

@defvar uuid-comparator
@c MOD rfc.uuid
@c EN
A comparator to compare and hash uuids.  @xref{Basic comparators}.

Note: Equality of uuids can be tested with @code{equal?},
and uuids can be sorted using generic @code{compare}.
@c JP
UUID同士を比較したりハッシュ値を取れる比較器です。
比較器については@ref{Basic comparators}参照。

註: 二つのUUIDが等しいかどうかは@code{equal?}で、
また、ジェネリックな@code{compare}でUUIDのソートができます。
@c COMMON
@end defvar

@c EN
@subheading Read/write UUIDs
@c JP
@subheading UUIDの読み書き
@c COMMON

@defun parse-uuid string :key if-invalid
@c MOD rfc.uuid
@c EN
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 if the @var{if-invalid} keyword argument is omitted
or @code{:error}, and @code{#f} is returned if @var{if-invalid} is @code{#f}.
@c JP
UUIDの文字列表現をパーズし、UUIDインスタンスにして返します。
文字列が有効なUUID表現でない場合、@var{if-invalid}キーワード引数が
省略されるか@code{:error}であればエラーが投げられ、
@var{if-invalid}が@code{#f}であれば@code{#f}が返されます。
@c COMMON

@c EN
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.
@c JP
典型的な@code{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}という形式に加え、
@code{urn:uuid:}プレフィクスがついた形、前後がカーリーブレイスで囲まれた形、
そしてハイフンを持たない形が認識されます。
@c COMMON
@end defun

@defun write-uuid uuid :optional port
@c MOD rfc.uuid
@c EN
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.
@c JP
@var{uuid}の文字列表現を@code{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}形式で
@var{port}に書き出します。@var{port}が省略された場合は現在の出力ポートが使われます。
@c COMMON
@end defun

@defun uuid->string uuid
@c MOD rfc.uuid
@c EN
Returns a string representation of @var{uuid},
in @code{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} format.
@c JP
@var{uuid}の文字列表現を@code{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}形式で
返します。
@c COMMON
@end defun


@c EN
@subheading UUID generator makers
@c JP
@subheading UUIDジェネレータ作成
@c COMMON

@deffn {Parameter} uuid-random-source
@c MOD rfc.uuid
@c EN
We use PRNG to generate UUIDs.  By default, we internally creates
a random source and randomize it.  You can alter the random source
using @code{parameterize}.  The value must be a SRFI-27 random source
(@pxref{Sources of random bits}).
@c JP
UUIDを生成するのに乱数発生器を使います。
デフォルトでは、内部的に乱数源を作って乱数化したものを使いますが、
このパラメータを@code{parameterize}することで独自の乱数源を使うことができます。
パラメータの値はSRFI-27の規定する乱数源でなければなりません
(@ref{Sources of random bits}参照)。
@c COMMON

@c EN
The value of this parameter is taken when a uuid generator
is created by one of @code{make-uuid*-generator}.  Once a
generator is created, the random source is kept in the generator
and won't be affected by changing the value of this parameter.
@c JP
このパラメータの値は、@code{make-uuid*-generator}でUUIDのジェネレータが
作られる時に参照され、その乱数源がジェネレータの中に保持されます。
このパラメータの値の変更は、既に作られたジェネレータには影響を与えません。
@c COMMON
@end deffn

@defun make-uuid1-generator :optional node-id
@defunx make-uuid6-generator :optional node-id
@c MOD rfc.uuid
@c EN
Returns new generators of uuid v1 and uuis v6
(timestamp and node id based), respectively.

The difference between version 1 and version 6 is the order of timestamp field;
version 1 stores lower bits of timestamp first, while version 6
stores higher bits first.  That makes v6 uuids created around
the same time cluster together when sorted, making it favorable
choice over v1 for database index.  (However, if you need
chronologically orderable uuids, you should use v7 uuids.)

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).
@c JP
それぞれ、バージョン1およびバージョン6アルゴリズム(タイムスタンプとノードID)による
UUIDのジェネレータを生成して返します。二つのバージョンの違いは、
バージョン1ではタイムスタンプをいくつかに分けたうちの下位ビットから順に格納する
のに対し、バージョン6では上位ビットから格納することです。
これにより、近い時間に作られたv6 uuidはソートした時に固まることになり、
データベースのインデックスとして使う場合にv1より有利になります。
(但し、完全に時間的に整列可能なuuidが必要な場合はv7 uuidを使ってください)。

省略可能な@var{node-id}引数はノードIDを指定する48ビットの正確な整数でなければ
なりません (IEEE802 MACアドレスが通常使われます)。
省略された場合は、プロセス内でひとつのランダムノードIDを生成して使います
(この場合、生成されるノードIDはマルチキャストビットが立てられるので、
現実に存在するMACアドレスとかぶることはありません)。
@c COMMON

@c EN
The generators created by these procedures are thread-safe.
@c JP
これらの手続きで作られるジェネレータはスレッドセーフです。
@c COMMON
@end defun

@defun make-uuid4-generator
@c MOD rfc.uuid
@c EN
Returns a new generator that yields uuids with
version 4 algorithm (random numbers).
@c JP
バージョン4アルゴリズム(乱数)によるUUIDを生成するジェネレータを作って返します。
@c COMMON

@c EN
The generators created by this procedures are thread-safe.
@c JP
この手続きで作られるジェネレータはスレッドセーフです。
@c COMMON
@end defun

@defun make-uuid7-generator :optional increment-bits
@c MOD rfc.uuid
@c EN
Returns a new generator that yields uuids with version 7 algorithm
(time-ordered).
The uuid consists of timestamp part, and monotonically increasing
random bits.  Overall, it is ordered chronologically.
@c JP
バージョン7アルゴリズム(時間順列可能)でuuidを作るジェネレータを作って返します。
uuidは、タイムスタンプ部分と、時間的に単調増加するランダムビット部分からなります。
全体として、uuidをソートすると生成順になります。
@c COMMON

@c EN
The random bit part is splitted to 12bit @code{rand_a} field
and 62bit @code{rand_b} field in UUID RFC.  The RFC doesn't
precisely specify how to fill them.  In our implementation,
we treat it as 74bit unsigned integer, and use the following
strategy:
@c JP
ランダムビット部分はUUID RFCの仕様では12ビットの@code{rand_a}フィールドと
62bitの@code{rand_b}フィールドに分かれています。
RFCではどのようにそれらを埋めるかは具体的に指定されていません。
Gaucheの実装では、それを74ビットの非負整数とみなし、
次の戦略を取ります。
@c COMMON

@c EN
@itemize @bullet
@item
It is initialized with random integer per process.
@item
When a v7 uuid is asked, we increment the field with a
random unsigned integer up to 2^@var{increment-bits}.
If it does not overflow, we use it as is.
@item
If it does overflow, if the timestamp is already incremented
from the previous generation, we use the wraparound value.
@item
Otherwise, we wait until the timestamp field is incremented,
and then use the wraparound value.
@end itemize
@c JP
@itemize @bullet
@item
プロセスごとに、ランダムの整数を初期値とします。
@item
v7 uuidを生成する度に、ランダムな2^@var{increment-bits}未満の
非負整数をフィールドに加算します。
フィールドがオーバーフローしなければそれをそのまま使います。
@item
フィールドがオーバーフローした場合、前回の生成からタイムスタンプが進んでいれば、
ラップアラウンドした値を使います。
@item
そうでなければ、タイムスタンプが進むまで待って、
ラップアラウンドした値を使います。
@end itemize
@c COMMON

@c EN
The optional @var{increment-bits} argument must be an positive exact integer.
The default value is 64.  You may want to pass a smaller number if you
need to create a lots of UUIDs in very short span of time.
@c JP
省略可能な@var{increment-bits}引数は正確な正の整数でなければなりません。
デフォルトの値は64です。極めて短い時間内に大量のUUIDを作りたい場合は、
小さな数を指定するのが良いでしょう。
@c COMMON

@c EN
The generators created by this procedures are thread-safe.
@c JP
この手続きで作られるジェネレータはスレッドセーフです。
@c COMMON
@end defun

@defun uuid-random-source-set! random-source
@c MOD rfc.uuid
@c DEPRECATED
@c EN
Use @code{uuid-random-source} parameter
to customize random source to be used in uuid generation.
@c JP
UUID生成に使われる乱数源をカスタマイズするには
@code{uuid-random-source}パラメータを使ってください。
@c COMMON
@end defun

@c EN
@subheading Pre-created UUID generators
@c JP
@subheading あらかじめ作られているUUIDジェネレータ
@c COMMON

@defun uuid1 :optional node-id
@defunx uuid4
@defunx uuid6 :optional node-id
@defunx uuid7
@c MOD rfc.uuid
@c EN
Pre-created uuid generators for convenience.
Those generators are created with the corresponding
@code{make-uuid*-generator} when the library is loaded,
so they use the default random source.
@c JP
簡便のために、あらかじめ作られているUUIDのジェネレータです。
これらのジェネレータはライブラリのロード時に
対応する@code{make-uuid*-generator}で作られるので、
デフォルトの乱数源を使います。
@c COMMON

@c EN
These generators are thread-safe.
@c JP
これらのジェネレータはスレッドセーフです。
@c COMMON
@end defun

@defun nil-uuid
@c MOD rfc.uuid
@c EN
Returns a nil-UUID (all bits zero).
@c JP
全てのビットが0であるnil UUIDを返します。
@c COMMON
@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.

That is, you can specify between 8 to 15 to read zlib,
24 to 31 to read gzip, or 40 to 47 to use automatic detection.

The window bits must be equal to or greater than the window bits
used to compress the source,
or a @code{<zlib-data-error>} condition is thrown.
If you don't know the compression
parameters of the input (which is most likely the case), you need to
specify the maximum value, i.e. 15 for zlib, 31 for gzip, or 47 to
autodetect.
@c JP
@var{window-bits}の意味もほぼ同じですが、
32が足された値が与えられた場合にはzlibとgzipのヘッダ自動判定が有効になります。

すなわち、zlibを読む場合は8から15、gzipを読む場合は24から31、自動判定を使う場合は
40から47の値を指定することになります。

このwindow bitsは、入力が圧縮された時に使われたwindow bits以上でなければならず、
小さいと@code{<zlib-data-error>}コンディションが投げられます。
入力の圧縮時のパラメータを知らない場合(通常そうだと思います)、
最大の値を指定するのが良いでしょう。つまり、
zlibなら15、gzipなら31、自動判定を使うなら47です。
@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{https://people.csail.mit.edu/jaffer/SLIB.html}.
@c JP
このモジュールはAubrey Jaffer氏のSLIBへのインタフェースです。
SLIBがインストールされている場合、@code{(use slib)} とすれば
SLIBの機能が使えるようになります。
SLIBそのものはGaucheのディストリビューションには含まれていません。
あなたのシステムにまだインストールされていない場合は
@uref{https://people.csail.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

@c EN
NB: SLIB probes available srfis during initialization, and by the way
it does so, all available srfis are loaded,
regardless of whether you @code{require} it or not.  This may
introduce unexpected side effects; for example, Gauche's built-in
@code{regexp-replace} is shadowed by @code{srfi.115}'s one
(@pxref{R7RS regular expressions}), which has slightly different API.
@c JP
註: SLIBは初期化時にサポートされているsrfiを自動的に検出しますが、
その副作用として、@code{require}するか否かにかかわらず
検出されたsrfiが全てロードされてしまいます。
これは思いがけない作用をもたらすことがあります。例えばGaucheの組み込みの
@code{regexp-replace}は、やや異なるAPIを持つ@code{srfi.115}の
同名の手続きによってシャドウされてしまいます
(@ref{R7RS regular expressions}参照)。
@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{https://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{https://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{https://www.w3.org/XML/1998/namespace}".

This procedure tests for the namespace constraints:
@url{https://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{https://www.w3.org/XML/1998/namespace}''に定義済みで束縛されていると
されます。

この手続きは、名前空間の制約をテストします:
@url{https://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

@c EN
Here's a simple example:
@c JP
簡単な例を示します:
@c COMMON

@example
(call-with-input-string
  "<book>
     <title>Land of Lisp</title>
     <author>Conrad Barski</author>
      <publisher>No Starch Press</publisher>
   </book>
   <book>
     <title>Programming Gauche</title>
     <author>Kahua Project</author>
     <author>Shiro Kawai</author>
     <publisher>O'Reilly Japan</publisher>
   </book>"
  (^p (ssax:xml->sxml p '())))
@result{}
  (*TOP*
    (book (title "Land of Lisp")
          (author "Conrad Barski")
          (publisher "No Starch Press"))
    (book (title "Programming Gauche")
          (author "Kahua Project")
          (author "Shiro Kawai")
          (publisher "O'Reilly Japan")))
@end example

@c EN
The entire document is put in a pseudo node @code{*TOP*}, since
the document may contain more than one toplevel nodes.
The @code{*TOP*} node can also keep the meta information.
In the following example, the XML declaration is kept under
a pseudo node @code{*PI*} (processing instructions).
@c JP
ドキュメントは複数のトップレベルノードを持っている場合があるので、
ドキュメント全体は擬似ノード@code{*TOP*}の下にまとめられます。
@code{*TOP*}ノードはまたメタ情報を保持するのにも使われます。
次の例ではXML宣言が@code{*PI*} (processing infomation) ノードとして
パーズされています。
@c COMMON

@example
(call-with-input-string
  "<?xml version=\"1.0\" encoding=\"utf-8\"?>
   <book>
     <title>Programming Gauche</title>
     <author>Kahua Project</author>
     <author>Shiro Kawai</author>
     <publisher>O'Reilly Japan</publisher>
   </book>"
  (^p (ssax:xml->sxml p '())))
@result{}
  (*TOP*
    (*PI* xml "version=\"1.0\" encoding=\"utf-8\"")
    (book (title "Programming Gauche") (author "Kahua Project")
          (author "Shiro Kawai") (publisher "O'Reilly Japan")))
@end example

@c EN
Namespaces are recognized, and their aliases are
fully expanded to the URI by default:
@c JP
名前空間も認識されます。デフォルトでは名前空間のエイリアスは全て
完全なURIへと展開されます:
@c COMMON

@example
(call-with-input-string
  "<b:book xmlns:b=\"https://example.com/book/\">
     <b:title>Programming Gauche</b:title>
     <b:author>Kahua Project</b:author>
     <b:author>Shiro Kawai</b:author>
     <b:publisher>O'Reilly Japan</b:publisher>
   </b:book>"
  (^p (ssax:xml->sxml p '())))
@result{}
  (*TOP*
   (https://example.com/book/:book
    (https://example.com/book/:title "Programming Gauche")
    (https://example.com/book/:author "Kahua Project")
    (https://example.com/book/:author "Shiro Kawai")
    (https://example.com/book/:publisher "O'Reilly Japan")))
@end example

@c EN
(This is because namespace aliases can have nested scopes,
so just keeping aliases loses information)
@c JP
(名前空間エイリアスは入れ子になったスコープを持つため、
ただエイリアスをそのまま保持するだけでは情報が失われるためです。)
@c COMMON


@c EN
However, tags with fully expanded namespace prefix is cumbersome.
You can provide your own namespace aliases for more compact
output with @var{namespace-prefix-assig} argument.
@c JP
ただ、完全なURIに展開された名前空間プレフィクスは扱い辛いので、
独自の名前空間エイリアスを@var{namespace-prefix-assig}引数で指定できます。
@c COMMON

@example
(call-with-input-string
  "<b:book xmlns:b=\"https://example.com/book/\">
     <b:title>Programming Gauche</b:title>
     <b:author>Kahua Project</b:author>
     <b:author>Shiro Kawai</b:author>
     <b:publisher>O'Reilly Japan</b:publisher>
   </b:book>"
  (^p (ssax:xml->sxml p '((Book . "https://example.com/book/")))))
@result{}
  (*TOP*
   (@@ (*NAMESPACES* (Book "https://example.com/book/")))
   (Book:book (Book:title "Programming Gauche")
              (Book:author "Kahua Project")
              (Book:author "Shiro Kawai")
              (Book:publisher "O'Reilly Japan")))
@end example
@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{aux-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 :optional namespace-prefix-assig
@defunx sxml:attr->html attr
@c MOD sxml.tools
@c EN
Creates the XML/HTML markup for attributes.
Return a tree of strings, which can be passed to
@code{tree->string} or @code{write-tree} (@pxref{Lazy text construction}).

The argument @var{attr} is a two-element list,
@code{(@var{attr-name} @var{attr-value})}, where
@var{attr-name} is a symbol.  @var{Attr-value} can be any value,
and converted to a string with @code{x->string}.
@c JP
属性のXML/HTMLマークアップを作ります。
戻り値は、@code{tree->string}や@code{write-tree}に渡せる
文字列のツリーです(@ref{Lazy text construction}参照)。

@var{attr}は2要素のリスト
@code{(@var{attr-name} @var{attr-value})}で、
@var{attr-name}はシンボルでなければなりません。
@var{attr-value}はどんな値でも良いですが、文字列以外は
@code{x->string}で文字列に変換されます。
@c COMMON

@c EN
The optional @var{namespace-prefix-assig} argument is used to replace
namespace prefix in the attibute name to its alias.  See
@code{sxml:sxml->xml} below for the details.
@c JP
省略可能な@var{namespace-prefix-assig}は、属性名の名前空間プレフィクスを
エイリアスに置き換えるのに使われます。
詳しくは下の@code{sxml:sxml->xml}を参照してください。
@c COMMON

@c EN
There's a subtle difference between the two.  If the value
is an empty string, @code{sxml:attr->html} omits the attribute
value, while @code{sxml:attr->xml} doesn't.
@c JP
二つの手続きには微妙な差があります。値が空文字列だった場合、
@code{sxml:attr->html}は値を省略しますが、@code{sxml:attr->xml}はしません。
@c COMMON

@example
(use text.tree)

(tree->string (sxml:attr->xml '(name foo)))
 @result{} " name=\"foo\""

(tree->string (sxml:attr->html '(value "He said, \"Oops.\"")))
 @result{} " value=\"He said, &quot;Oops.&quot;\""

(tree->string (sxml:attr->xml '(download "")))
 @result{} " download=\"\""

(tree->string (sxml:attr->html '(download "")))
 @result{} " download"
@end example

@c EN
Note: This procedure is slighly modified from the original sxml-tools
to escape special characters in the attribue value,
and recognize namespace prefix.
@c JP
註: この手続きは元のsxml-toolsから、
属性値中の特殊文字をエスケープするのと、名前空間プレフィクスを認識するように変更してあります。
@c COMMON
@end defun

@defun sxml:string->xml string
@defunx sxml:string->html string
@c MOD sxml.tools
@c EN
Return a tree of strings where characters @code{<}, @code{>},
@code{&}, and @code{"} in @var{string}
are replaced by character entity references.
With @code{sxml:string->xml}, @code{'} is also replaced.

The returned string tree can be passed to @code{tree->string}
or @code{write-tree} (@pxref{Lazy text construction}).
@c JP
@var{string}中の文字@code{<}、@code{>}、@code{&}、@code{"}を
対応する文字実体参照に置き換えた文字列のツリーを返します。
@code{sxml:string->xml}では@code{'}も置き換えられます。

戻り値は、@code{tree->string}や@code{write-tree}に渡せます
(@ref{Lazy text construction}参照)。
@c COMMON

@c EN
See also @code{html-escape-string}
in @ref{Simple HTML document construction}.
@c JP
@ref{Simple HTML document construction}の
@code{html-escape-string}も参照して下さい。
@c COMMON
@end defun

@defun sxml:sxml->xml sxml :optional namespace-prefix-assig
@defunx sxml:sxml->html sxml
@c MOD sxml.tools
@c EN
Converts SXML to XML and HTML, respectively.  The return value
is a tree of strings to be pased to @code{tree->string} or @code{write-tree}
(@pxref{Lazy text construction}).
@c JP
SXMLをXMLあるいはHTMLにそれぞれ変換します。戻り値は文字列のツリーで、
@code{tree->string}や@code{write-tree}に渡せます
(@ref{Lazy text construction}参照)。
@c COMMON

@c EN
@code{sxml:sxml->xml} can take an optional @var{namespace-prefix-assig},
which is the form @code{((@var{alias-symbol} . @var{namespace-string}) @dots{})}.
It is the same format as the @var{namespace-prefix-assig} argument
of @code{ssax:xml->sxml} (@pxref{SSAX Highest-level parsers - XML to SXML}).
It has two effects:
@c JP
@code{sxml:sxml->xml}は省略可能引数@var{namespace-prefix-assig}を取ります。
これは@code{ssax:xml->sxml}の同名の引数と同じく、
@code{((@var{alias-symbol} . @var{namespace-string}) @dots{})}という形の
リストでなければなりません(@ref{SSAX Highest-level parsers - XML to SXML}参照)。
これは次の二つの効果を持ちます。
@c COMMON

@itemize @bullet
@item
@c EN
It adds @code{xmlns} attributes to the top node of @var{sxml}.
@c JP
@var{sxml}のトップレベルのノードに@code{xmlns}属性を付加
@c COMMON
@item
@c EN
If a node name or an attribute name has a prefix string that matches
@var{namespace-string}, it is replaced with @var{alias-symbol}.
(If its prefix string does not match any of @var{namespace-prefix-assig},
the prefix is left as is.)
@c JP
ノード名や属性名のプリフィクスが@var{namespace-string}のいずれかと一致した場合、
対応する@var{alias-symbol}に置き換えられます
(一致するものがなければプリフィクスはそのまま出力されます)。
@c COMMON
@end itemize

@c EN
Note that @code{sxml:sxml->html} does not take
@var{namespace-prefix-assig}, for HTML doesn't have namespace prefix.
@c JP
@code{sxml:sxml->html}は@var{namespace-prefix-assig}引数を取りません。
HTMLには名前空間プレフィクスは無いからです。
@c COMMON

@c EN
Other differences between XML and HTML version are:

@itemize @bullet
@item
Handling of empty-valueed attribute
(see @code{sxml:attr->xml}/@code{sxml:attr->html} above.)
@item
Characters replaced with character entity references
(see @code{sxml:string->xml}/@code{sxml:string->html} above.)
@item
Non-terminated tags.  In HTML, some tags does not have end tags.
In XML, elements with empty content are emitted as self-terminating tags.
@end itemize
@c JP
XML版とHTML版の他の違いは次のとおりです。

@itemize @bullet
@item
空の値を持つ属性の出力
(上の@code{sxml:attr->xml}/@code{sxml:attr->html}参照)
@item
文字実体参照に置き換えられる文字の違い
(上の@code{sxml:string->xml}/@code{sxml:string->html}参照)
@item
終了タグのない要素。HTMLではいくつかの決められたタグは終了タグを持ちません。
XMLでは内容が空の要素は自己終了タグとして出力されます。
@end itemize
@c COMMON

@example
(tree->string (sxml:sxml->xml '(div (@@ (foo "") (bar "'")))))
  @result{} "<div foo=\"\" bar=\"&apos;\"/>"
(tree->string (sxml:sxml->html '(div (@@ (foo "") (bar "'")))))
  @result{} "<div foo bar=\"'\"/>"

(tree->string (sxml:sxml->xml '(img (@@ (src "foo.png")))))
  @result{} "<img src=\"foo.png\"/>"
(tree->string (sxml:sxml->html '(img (@@ (src "foo.png")))))
  @result{} "<img src=\"foo.png\">"
@end example
@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

@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{https://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{https://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

@c EN
Note: Unlike @code{sxml:sxml->xml} in @code{sxml.ssax}, this
procedure requires XML attribute values to be strings.
@c JP
註: @code{sxml.ssax}の@code{sxml:sxml->xml}と異なり、
この手続きは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

@c EN
Note: Unlike @code{sxml:sxml->html} in @code{sxml.ssax}, this
procedure requires XML attribute values to be strings.
@c JP
註: @code{sxml.ssax}の@code{sxml:sxml->html}と異なり、
この手続きは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{https://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{https://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

@c EN
@subheading Console control
@c JP
@subheading コンソール制御
@c COMMON

@deffn {Generic function} call-with-console console proc :key mode
@c MOD text.console
@c EN
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. @xref{Terminal control}, for the details.)
@c JP
コンソールの制御を取得した状態で、@var{proc}を@var{console}を唯一の引数として
呼び出します。コンソールは@var{mode}で指定されるモードにセットされます。
@var{mode}は@code{with-terminal-mode}が受け付けるシンボル、
すなわち@code{raw}、@code{rare}、@code{cooked}のいずれかでなければなりません。
省略された場合は@code{rare}になります。
このモードは、端末でのエコーを抑止し、ほぼ全てのキーストロークを
プログラムにそのまま渡しますが、端末制御機能はシステム側で処理します
(割り込みの@code{Ctrl-C}、プロセス一時停止の@code{Ctrl-Z}など。実際のキー割り当ては
端末制御で変更可能です。詳しくは@ref{Terminal control}参照。)
@c COMMON

@c EN
If @var{proc} raises an unhandled error, this generic function
resets the terminal mode before returning.  It does not clear
the screen.
@c JP
@var{proc}が捕捉されない例外を投げた場合、このジェネリック関数は
端末モードを元に戻します。ただ、スクリーンはクリアされません。
@c COMMON
@end deffn

@deffn {Generic function} putch console char
@c MOD text.console
@c EN
Display a character at the current cursor position, and
move the current cursor position.
@c JP
文字@var{char}をコンソールの現在のカーソル位置に出力し、カーソルをその分進めます。
@c COMMON
@end deffn

@deffn {Generic function} putstr console string
@c MOD text.console
@c EN
Display a string from the current cursor position, and
move the current cursor position.
@c JP
文字列@var{string}コンソールの現在のカーソル位置に出力し、カーソルをその分進めます。
@c COMMON
@end deffn

@deffn {Generic function} beep console
@c MOD text.console
@c EN
Ring the beep, or flash the screen (visible bell) if possible.
@c JP
可能なら、端末のビープ音を鳴らすか、画面をフラッシュさせます(visual bell)。
@c COMMON
@end deffn

@deffn {Generic function} getch console
@c MOD text.console
@c EN
Fetch a keypress from the console.  This blocks until
any key is pressed.

The return value may be one of the following values:
@c JP
コンソールからキー入力を読み取ります。何らかのキーが押されるまでブロックします。

戻り値は以下の値のいずれかです。
@c COMMON


@table @asis
@c EN
@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.
@c JP
@item 文字
その文字に該当するキーが押された場合。
コントロールキーと一緒に押された場合は、制御文字が返ります。
例えばユーザがCtrl-Aをタイプしたら@code{#\x01}が返ります。
@c COMMON
@c EN
@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).
@c JP
@item シンボル
特殊キーの場合です。以下のキーがサポートされています。
@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}。
(註: DELETEキーは通常@code{#\x7f}にマップされていますが、
端末設定で変更可能です)。
@c COMMON
@c EN
@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.
@c JP
@item シンボル@code{ALT}と文字のリスト
文字キーがAltキーと同時に押されたことを示します。
例えばユーザがAlt-aを押したなら、@code{(ALT #\a)}が返されます。
@c COMMON
@item EOF
@c EN
Indicates the input is closed somehow.
@c JP
入力がクローズされたことを示します。
@c COMMON
@end table

@c EN
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.
@c JP
@code{ALT}以外のモディファイアキーは別扱いではなく返される文字コードにエンコードされます。
CAPSLOCKがoffであるとき、ユーザが
@code{a}、@code{Shift}+@code{a}、@code{Ctrl}+@code{a}をタイプしたとすると、
戻り値はそれぞれ@code{#\a}、@code{#\A}、@code{#\x01}となります。
@code{Ctrl}+@code{Shift}+@code{a}は@code{Ctrl}+@code{a}と区別できません。
@code{ALT}+@code{a}、@code{ALT}+@code{Shift}+@code{a}、
@code{ALT}+@code{Ctrl}+@code{a}の戻り値はそれぞれ、
@code{(ALT #\a)}、@code{(ALT #\A)}、@code{(ALT #\x01)}となります。
@c COMMON
@end deffn

@deffn {Generic function} chready? console
@c MOD text.console
@c EN
Returns true if there's a key sequence to be read in the console's
input.
@c JP
コンソールの入力からキーシーケンスが直ちに読み出せる状態であれば@code{#t}を、
そうでなければ@code{#f}を返します。
@c COMMON
@end deffn

@deffn {Generic function} query-cursor-position console
@c MOD text.console
@c EN
Returns two values, the current cursor's x and y position.
The top-left corner is (0,0).
@c JP
コンソールのカーソル位置を問い合わせ、そのx座標とy座標を２つの値として
返します。左上のコーナーが(0, 0)です。
@c COMMON
@end deffn

@deffn {Generic function} move-cursor-to console row column
@c MOD text.console
@c EN
Move cursor to the specified position.  The top-left corner is (0,0).
@c JP
カーソルを指定位置に移動します。左上のコーナーが(0, 0)です。
@c COMMON
@end deffn

@deffn {Generic function} reset-terminal console
@c MOD text.console
@c EN
Reset terminal.  Usually this sets the
character attributes to the default,
clears the screen, and moves the cursor to (0, 0).
@c JP
端末をリセットします。通常、これは文字属性をデフォルトに戻し、
スクリーンをクリアしてカーソルを(0, 0)に移動します。
@c COMMON
@end deffn

@deffn {Generic function} clear-screen console
@c MOD text.console
@c EN
Clear entire screen.
@c JP
全画面をクリアします。
@c COMMON
@end deffn

@deffn {Generic function} clear-to-eol console
@c MOD text.console
@c EN
Clear characters from the current cursor position to the
end of the line.
@c JP
現在のカーソル位置から行末までをクリアします。
@c COMMON
@end deffn

@deffn {Generic function} clear-to-eos console
@c MOD text.console
@c EN
Clear characters from the current cursor position to the
end of the screen.
@c JP
現在のカーソル位置とそれ以降をクリアします。
@c COMMON
@end deffn

@deffn {Generic function} hide-cursor console
@deffnx {Generic function} show-cursor console
@c MOD text.console
@c EN
Hide/show the cursor.
@c JP
カーソルを隠す、あるいは表示します。
@c COMMON
@end deffn

@deffn {Generic function} cursor-down/scroll-up console
@c MOD text.console
@c EN
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.
@c JP
カーソルが画面の一番下の行にある場合は、画面全体をスクロールアップし、最下行をクリアします。
カーソルは同じ位置にとどまります。
そうでなければ、カーソルを同じカラムの一行下に移動します。
@c COMMON
@end deffn

@deffn {Generic function} cursor-up/scroll-down console
@c MOD text.console
@c EN
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.
@c JP
カーソルが画面の一番上の行にある場合は、画面全体をスクロールダウンし、最上行をクリアします。
カーソルは同じ位置にとどまります。
そうでなければ、カーソルを同じカラムの一行上に移動します。
@c COMMON
@end deffn

@deffn {Generic function} query-screen-size console
@c MOD text.console
@c EN
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.
@c JP
スクリーンの幅と高さを２つの値で返します。

註: この操作は画面上の表示に影響を与えるかもしれません。
画面全体を再描画する前にこの呼び出しを行い、結果を保存しておくことをおすすめします。
@c COMMON
@end deffn

@deffn {Generic function} set-character-attribute console attr
@c MOD text.console
@c EN
Set the console so that the subsequent characters will be written
with attributes specified by @var{attr}.

The character attributes spec is a list in the following format:
@c JP
これ以降に書かれる文字の文字属性を@var{attr}に設定します。

文字属性@var{attr}は次の形式のリストです。
@c COMMON

@example
(<fgcolor> [<bgcolor> . <option> ...])
@end example

@c EN
where:
@c JP
ここで、
@c COMMON

@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

@c EN
For example, you can set characters to be written in red with
black background and underscore, you can call:
@c JP
例えば、以降の文字を黒背景に赤字、下線つきで表示したい場合は、こう呼び出します:
@c COMMON

@example
(set-character-attribute con '(red black underscore))
@end example

@c EN
That the options may seem rather limited in the age of
full-color bitmap displays.  That's what it used to be, young lads.
@c JP
フルカラービットマップディスプレイが一般的になった現代では、
指定可能な属性がひどく限られているように感じられるかもしれません。
昔はみなこういうものだったのじゃよ、若者よ。
@c COMMON
@end deffn

@deffn {Generic function} reset-character-attribute console
@c MOD text.console
@c EN
Reset character attributes to the default.
@c JP
文字属性をデフォルトに戻します。
@c COMMON
@end deffn

@deffn {Generic function} with-character-attribute console attr thunk
@c MOD text.console
@c EN
Sets the console's attributes to @var{attr} and calls @var{thunk},
then resets the attributes.  Even if @var{thunk} throws an error,
attributes are reset.

See @code{set-character-attribute} above for the form of @var{attr}.

Note: You should be able to nest this, but currently nesting
isn't working.  The end of innermost @code{with-character-attribute}
resets the attributes.
@c JP
コンソールの文字属性を@var{attr}に変更した上で@var{thunk}を呼び出し、
その後で文字属性をデフォルトに戻します。@var{thunk}がエラーを投げた場合でも
文字属性は戻されます。

@code{attr}の形式については上の@code{set-character-attribute}を
参照してください。

註: この手続きはネストして使えるべきですが、今の所ネストは動きません。
一番内側の@code{with-character-attribute}が終わった時点で
属性がリセットされてしまいます。　
@c COMMON
@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 quote 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.
@c JP
RFC4180に定義されたフォーマットを含む、
CSV (カンマ区切りの値) の表をパーズ/生成するための手続きを提供します。
区切り文字やクオート文字をカスタマイズすることで、CSVに似たフォーマットを
広くカバーすることができます。

CSV の表は、改行で区切られた @var{record} の連続で構成されます。
それぞれのレコードは、区切り文字(デフォルトではカンマ)で区切られた
複数の @var{field} を含みます。フィールドは、クォートされている
(二重引用符で囲まれている)場合は、カンマや改行を含むことができます。
クォートされたフィールドに二重引用符を含めるには、2つの連続する
二重引用符を使います。
@c COMMON

@c EN
By default, whitespaces around an unquoted field value is ignored.
You can customize this behavior with @code{csv-trim-unquoted-charset}
parameter or @var{trim-charset} optional argument of
@code{make-csv-reader}.
@c JP
デフォルトでは、クオートされていないフィールドの値の前後にある空白文字は
無視されます。この振る舞いは@code{csv-trim-unquoted-charset}パラメータ、
あるいは@code{make-csv-reader}の@var{trim-charset}引数でカスタマイズ可能です。
@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 trim-charset
@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

@c EN
The @var{separator} argument specifies the field separator.
For the literally ``comma separated value'', it is a comma character.
Historically, however, the term CSV covers variations that uses
other separator characters such as @code{#\tab}, @code{#\:}, etc.
@c JP
@var{separator}引数はフィールドの区切り文字を指定します。
文字通りの「コンマで区切られた値 (comma separated value)」では、これはコンマです。
ただし、歴史的に「CSVフォーマット」は、
@code{#\tab}や@code{#\:}など、他の区切り文字を使う
バリエーションも含めて用いられてきました。
@c COMMON

@c EN
The optional @var{quote-char} argument specifies the quote character.
The default value is @code{#\"}.
@c JP
省略可能引数@var{quote-char}はクオート文字を指定します。
デフォルト値は@code{#\"}です。
@c COMMON

@c EN
The optional @var{trim-charset} argument must be a charset or @code{#f}.
If it is a charset, those characters surrounding @emph{unquoted} field values
are trimmed.  The default value is the value of the parameter
@code{csv-trim-unquoted-charset}, whose initial value is @code{#[\s]},
causing whitespaces around
unquoted field values are trimmed.  If it is @code{#f}, no trimming is done.
Whitespaces within quotes are never be trimmed.  Note that if this argument
is a charset, its characters can appear between separater character and quoted
field---they're just ignored.  If this argument is @code{#f}, however,
extra characters between separator and quoted field triggers an error.
@c JP
省略可能引数@var{trim-charset}は文字集合または@code{#f}でなければなりません。
文字集合の場合、@emph{クオートされていない}フィールド値の前後にある、
その文字集合に含まれる文字は取り除かれます。
デフォルト値はパラメータ@code{csv-trim-unquoted-charset}の値で、
その初期値は@code{#[\s]}です。
従ってデフォルトでは、クオートされていないフィールド値の
前後の空白文字が取り除かれます。@code{#f}の場合は何も取り除かれません。
クオート内の空白文字は決して取り除かれません。
なお、この引数が文字集合の場合、区切り文字と
クオートされたフィールドの間にその文字集合の文字が現れても構いません(単に無視されます)。
しかしこの引数が@code{#f}の場合、区切り文字とクオートされたフィールドの間に余計な文字があると
エラーになります。
@c COMMON

@c EN
Note: The default behavior of trimming whitespaces is for the backward
compatibility.  RFC 4180 states whitespaces in unquoted fields
should not be ignored.  It doesn't allow whitespaces between a separator
character and a quoted field.  Setting @code{csv-trim-unquoted-charset} to
@code{#f} or passing @code{#f} to @var{trim-charset} argument makes the
maximum comformance to RFC4180.
@c JP
註: 空白文字をデフォルトで取り除く振る舞いは後方互換性のためです。
RFC4180では、クオートされていないフィールド内の空白文字は無視すべきでないとされており、
また区切り文字とクオートされたフィールドの間に空白文字を入れることも許されていません。
@code{csv-trim-unquoted-charset}を@code{#f}にセットするか、@var{trim-charset}引数に
@code{#f}を渡すと、最大限RFC4180に準拠した動作となります。
@c COMMON

@end defun

@deffn {Parameter} csv-trim-unquoted-charset
@c MOD text.csv
@c EN
Gives the default value of @var{trim-charset} argument in
@code{make-csv-reader}.  Its value must be either a character set
or @code{#f}. The initial value is @code{#[\s]}.
@c JP
@code{make-csv-reader}の@var{trim-charset}引数のデフォルト値を与えます。
値は文字セットか@code{#f}でなければなりません。
初期値は@code{#[\s]}です。
@c COMMON
@end deffn


@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 @var{src-a} to the one from @var{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}は@code{read-line}で、
2つのシーケンスは編集リストを計算するために@code{lcs-edit-list}に渡されます。
@code{lcs-edit-list}には、等値を検査する関数@var{eq-fn}も渡されます。

編集リストとは、@var{src-a}から@var{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

@defun diff-report/context src-a src-b :key reader eq-fn writer context-size
@c MOD text.diff
@c EN
Produce a human-friendly difference of two text sources like
@code{diff-report}, but in the ``context diff'' format.
@c JP
@code{diff-report}と同じように、二つのテキストソースの差違を出力しますが、
コンテキスト形式を使います。
@c COMMON

@example
(diff-report/context "a\nb\nc\nd\n" "b\ne\nd\nf\n")
@end example
@c EN
displays:
@c JP
は次を出力します:
@c COMMON
@example
***************
*** 1,4 ****
- a
  b
! c
  d
--- 1,4 ----
  b
! e
  d
+ f
@end example

@c EN
This calls @code{lcs-edit-list/context} to get a context diff of lines,
then format it in the same way as @code{diff -c} output.
(@xref{The longest common subsequence}, for the details of
@code{lcs-edit-list/context}.)
@c JP
この手続きは@code{lcs-edit-list/context}を呼んでコンテキストdiffを得て、
それを@code{diff -c}と同じ形式にして出力します。
@c COMMON

@c EN
Each ``hunk'' (a chunk containing difference)
is preceded by a separater @code{***************},
followed by the excerpt from @var{src-a}, then the excerpt form @var{src-b},
each preceded by the header showing the line number of that excerpts
(start and end line, inclusive, 1-based).
@c JP
各 ``hunk'' (差異を含む塊)はセパレータ@code{***************}で始まり、
その後に@var{src-a}からの抜粋、そして@var{src-b}からの抜粋が続きます。
各抜粋の先頭には、そのhunkの範囲を示す行番号が出力されます
(開始と終了の行番号、どちらも範囲に含まれる、最初の行は1)。
@c COMMON

@c EN
In the excerpts, the line that's deleted from @var{src-a} is prefixed
with @code{-}, the line that's inserted into @var{src-b} is prefixed
with @code{+}, and the line changed is prefixed with @code{!}.
@c JP
抜粋の中では、@var{src-a}から削除された行の前に@code{-}が、
@var{src-b}に挿入された行の前に@code{+}が、そして置き換えられた行の前に@code{!}が、
それぞれ付加されます。
@c COMMON

@c EN
If the hunk only consists of either insertions or deletions, the other
side of excerpt is omitted.
@c JP
1つのhunkが、挿入のみ、または削除のみで構成されている場合、
変更のない方は抜粋が省略されます。
@c COMMON

@example
(diff-report/context "a\nb\nc\n" "a\nc\n")
 @r{prints:}
***************
*** 1,3 ****
  a
- b
  c
--- 1,2 ----
@end example

@c EN
As a special case, if one of the source is empty, its header is shown
as zero-th line:
@c JP
特別な場合として、一方のソースが空だった場合、その抜粋のヘッダの行番号は0となります。
@c COMMON

@example
(diff-report/context "" "a\nb\nc\n")
 @r{prints:}
***************
*** 0 ****
--- 1,3 ----
+ a
+ b
+ c
@end example

@c EN
The @var{reader}, @var{writer} and @var{eq-fn} keyword arguments are the
same as @code{diff-report}.  The @var{context-size} keyword argument
specifies the maximum unchanged lines attached to each hunk to show the
context.
@c JP
@var{reader}、@var{writer}、@var{eq-fn}キーワード引数の意味は
@code{diff-report}と同じです。@var{context-size}キーワード引数は
各hunkの前後に文脈表示のために付加される、変更のなかった行の最大数を指定します。
@c COMMON
@end defun

@defun diff-report/unified src-a src-b :key reader eq-fn writer context-size
@c MOD text.diff
@c EN
Like @code{diff-report/context}, but use ``unified diff'' format,
same as @code{diff -u}.
@c JP
@code{diff-report/context}と似ていますが、@code{diff -u}と同じ
「unified diff」形式で結果を表示します。
@c COMMON

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

@c EN
Each ``hunk'' begins with the header:
@c JP
各hunkは次のヘッダで始まります:
@c COMMON
@example
@@@@ -p,q +r,s @@@@
@end example
@c EN
where @var{p} is the start line number in @var{src-a},
@var{q} is the length of the hunk in @var{src-a},
@var{r} is the start line number in @var{src-b},
and @var{s} is the length of the hunk in @var{src-b}.
@c JP
ここで、@var{p}は@var{src-a}におけるhunkの開始行、
@var{q}は@var{src-a}におけるhunkの長さ、
@var{r}は@var{src-b}におけるhunkの開始行、
@var{s}は@var{src-b}におけるhunkの長さです。
@c COMMON

@c EN
The line-number is 1-based.
If the length of the hunk is 1, it is omitted.
@c JP
行番号は1から始まります。また、hunkの長さが1の場合、それは省略されます。
@c COMMON

@c EN
The lines deleted from @var{src-a} has @code{-} prefix,
the ones inserted into @var{src-b} has @code{+} prefix,
and unchanged lines has a space prefix.
@c JP
@var{src-a}から削除された行には@code{-}が、
@var{src-b}に追加された行には@code{+}が、
そして変更のない行にはスペースが付加されます。
@c COMMON

@c EN
As a special case, if either of sources is empty, both of its start index and
length are shown as @code{0}.
@c JP
特別な場合として、どちらかの入力が空だった場合、その開始行と長さはともに0となります。
@c COMMON

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

@c EN
The @var{reader}, @var{eq-fn}, @code{writer}, and @var{context-size}
keyword arguments are the same as @code{diff-report/context}.
@c JP
@var{reader}、@var{eq-fn}、@var{writer}、@var{context-size}キーワード引数は
@code{diff-report/context}と同じです。
@c COMMON

@c EN
This is used to show the difference of test results in @code{test*/diff}
(@pxref{Unit testing}).
@c JP
この手続きは@code{test*/diff}でテスト結果との差異を示すのに使われています
(@ref{Unit testing}参照)。
@c COMMON
@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, Text filling, 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
@c EN
A convenience module to invoke external editor program.
This is mainly to be used from REPL, but can be useful for
other purposes.
@c JP
外部エディタプログラムを起動するための便利なモジュールです。
もともとREPLで使われることを意図していましたが、他の目的にも有用かもしれません。
@c COMMON
@end deftp

@defun ed path-or-proc :key editor load-after
@c MOD text.external-editor
@c EN
Starts an external editor.  The editor program path is determined
in the following order:
@c JP
外部エディタを起動します。起動するエディタのパスは次のように決められます。
@c COMMON

@itemize @bullet
@item
@c EN
The @var{editor} keyword argument, if it's a string.
@c JP
@var{editor}キーワード引数に文字列が与えれれば、それをパスと解釈します。
@c COMMON
@item
@c EN
The value of @code{*editor*} in the user module, if defined.
@c JP
userモジュールに変数@code{*editor*}が定義されていれば、その値。
@c COMMON
@item
@c EN
The value of the environment variable @code{GAUCHE_EDITOR}.
@c JP
環境変数@code{GAUCHE_EDITOR}が定義されていれば、その値。
@c COMMON
@item
@c EN
The value of the environment variable @code{EDITOR}.
@c JP
環境変数@code{EDITOR}が定義されていれば、その値。
@c COMMON
@item
@c EN
If none works, the behavior depends on the value of @var{editor} keyword
argument:
@c JP
どれも該当しなかった場合、@var{editor}キーワード引数によって振る舞いが決まります。
@c COMMON
@table @code
@item #f
@c EN
Just returns @code{#f}.
@c JP
単に@code{#f}を返します。
@c COMMON
@item error
@c EN
Throws an error.
@c JP
エラーを投げます。
@c COMMON
@item ask
@c EN
Asks the user. (default)
@c JP
ユーザに尋ねます。(デフォルト)
@c COMMON
@item message
@c EN
Prints message and returns @code{#f}.
@c JP
メッセージを出して@code{#f}を返します。
@c COMMON
@end table
@end itemize

@c EN
Returns @code{#t} for normal termination.
@c JP
エディタを起動して、それが終了した場合は@code{#t}を返します。
@c COMMON

@c EN
The editor program may be called in one of the following way:
@c JP
エディタプログラムは次のどちらかの形で呼ばれます:
@c COMMON

@example
EDITOR filename
EDITOR +lineno filename
@end example

@c EN
The latter expects to locate the cursor on the specified line number
in the filename.
@c JP
後者の場合、エディタは@var{filename}をオープンした後、
@var{lineno}で示される行にカーソルを移動することが期待されます。
@c COMMON

@c EN
The file to open is determined by calling the generic function
@code{ed-pick-file} on the argument @var{path-or-proc}.
It should return @code{(@var{filename} @var{lineno})},
or @code{#f} to indicate that it couldn't determine the file to edit.
Methods for @code{<string>} and @code{<procedure>} are already defined;
see the entry of @code{ed-pick-file} below.
@c JP
オープンするファイル名は、ジェネリックファンクション@code{ed-pick-file}を
@var{path-or-proc}を引数として起動することで決定されます。
@code{ed-pick-file}は@code{(@var{filename} @var{lineno})}を返すか、
オープンすべきファイル名が決定できない場合は@code{#f}を返します。
@code{<string>}と@code{<procedure>}に対するメソッドは既に定義されています。
詳しくは下の@code{ed-pick-file}を見てください。
@c COMMON

@c EN
@c EN
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:
@c JP
@var{load-after}引数は、ファイルが変更された後でそれを
自動的にロードするかどうかを指定します。以下の値のいずれかでなければなりません。
@c COMMON
@table @code
@item #t
@c EN
Load the file once editor exits and the file is modified.
@c JP
エディタが終了し、その時点でファイルが変更されていた場合は、それをロードします。
@c COMMON
@item #f
@c EN
Do not load the file.
@c JP
ファイルをロードしません。
@c COMMON
@item ask
@c EN
Ask the user if the file should be loaded or not if the file is modified.
(default)
@c JP
ファイルが変更されていた場合に、ロードすべきかどうかをユーザに尋ねます。(デフォルト)
@c COMMON
@end table

@c EN
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.
@c JP
註: Common Lispの@code{ed}は引数なしで呼び出すこともできます。
しかし我々の用途ではそれはあまり有用でないと判断しました。REPLを走らせている場合、
それが既にエディタの中である可能性は高く、
それなら指定ファイルをバッファで開けばいいわけです。
また、@code{emacsclient}はファイル名を取るので、
ファイル名無しの場合の処理が煩雑になります。なので今のところ、ファイル名を必須としました。
@c COMMON
@end defun

@defun ed-string string :key editor
@c MOD text.external-editor
@c EN
Invoke an external editor (as described in @code{ed}) on a temporary file
whose content is @var{string}.
Once editor exits, returns the edited content as a string.
@c JP
@var{string}を一時ファイルに書き出して、それをオープンするエディタを起動します
(エディタがどう起動されるかについては@code{ed}のエントリを参照)。
エディタが終了したら、編集済の内容を文字列として返します。
@c COMMON
@end defun

@deffn {Generic Function} ed-pick-file obj
@c MOD text.external-editor
@c EN
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.
@c JP
何を編集するかを決めるジェネリックファンクションです。
ファイル名と行番号からなるリストか、編集すべきファイル名が見つからなければ@code{#f}を
返します。
@c COMMON

@c EN
Methods 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.
@c JP
文字列、@code{<procedure>}、そして@code{<top>}に対するメソッドが既に定義されています。
@var{obj}が文字列なら、それがファイル名です。
@var{obj}が手続きでそのソース位置が分かっていれば、ソースファイル名と定義行を返します。
@var{obj}がそれ以外なら@code{#f}を返します。
@c COMMON
@end deffn

@c ----------------------------------------------------------------------
@node Text filling, Gap buffer, Running external editor, Library modules - Utilities
@section @code{text.fill} - Text filling
@c NODE テキストの再詰め込み, @code{text.fill} - テキストの再詰め込み

@deftp {Module} text.fill
@mdindex text.fill
@c EN
This module provides procedures to fill given text within the
specified width, inserting line breaks
adequately.  It is similar to @code{fill-paragraph} of Emacs.
@c JP
このモジュールは、指定の幅にテキストを詰め込む(フィル)ように改行を適宜挿入して表示します。
Emacsの@code{fill-paragraph}のような機能です。
@c COMMON
@end deftp

@defun display-filled-text text :key port indent hanging width start-column lead-in
@c MOD text.fill
@c EN
Output @var{text} to @var{port}, while keeping the line width up to
@var{width} as much as possible by inserting line breaks.
If @var{port} is omitted, the current output port is used.
@c JP
@var{text}を、行の幅がなるべく@var{width}に収まるように改行を挿入しながら
@var{port}に出力します。
@var{port}が省略された場合は現在の出力ポートが使われます。
@c COMMON

@c EN
Two consecutive newlines mark (or, an empty line) a paragraph break.
First, @var{text} is splitted into paragraphs,
then each paragraph is filled.
All other newlines are treated as whitespaces.
@c JP
2つの連続する改行文字(あるいは、ひとつの空行)はパラグラフ境界を示します。
まず@var{text}がパラグラフに分割され、それから各パラグラフがフィルされます。
他の改行文字は空白と同じ扱いになります。
@c COMMON

@c EN
It has a few keyword arguments to control the formatting.
The @var{width} argument specifies the entire width of the filled text.
It tries to keep lines from overflowing the width, but if there's
an unbreakable chunk of text that's wider than the given width,
it lets the line oveflow.
The @var{hanging} specifies the hanging indent width of the paragraph's
first line,
and @var{indent} specifies the indent width of the rest of lines.
They are included in @var{width}.  Here's the relations of these
values:
@c JP
いくつかのキーワード引数で出力フォーマットを制御できます。
@var{width}引数はフィルされたテキスト全体の幅を指定します。テキストはこの幅を
越えないように出力されます。
但し、分割できない長い塊があった場合はこの幅を越えることがあります。
@var{hanging}はパラグラフの最初の行のハンギングインデントを、@var{indent}は2行目以降の
インデントを指定します。これらのインデントは@var{width}の一部にカウントされます。
次にこれらの値の関係を示します:
@c COMMON

@example
  width
<------------------------------------------------------------------->
  hanging
<------>
         Lorem ipsum dolor sit amet, consectetur adipiscing elit,
   sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
   Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
   nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
   in reprehenderit in voluptate velit esse cillum dolore eu fugiat
   nulla pariatur. Excepteur sint occaecat cupidatat non proident,
   sunt in culpa qui officia deserunt mollit anim id est laborum.
<->
  indent
@end example

@c EN
The arguments @var{width}, @var{indent}, and @var{hanging} must be
nonnegative exact integers or @code{#f}, if given.
When omitted or @code{#f},
@var{width} is assumed to be 65, @var{indent} to be 0,
and @var{hanging} to be the same as @var{indent}.
@c JP
@var{width}、@var{indent}、@var{hanging}は与えられたなら
正確な非負整数でなければなりません。省略されるか@code{#f}の場合、
@var{width}は65、@var{indent}は0、@var{hanging}は@var{indent}と同じになります。
@c COMMON

@c EN
If you call this procedure in the middle of the line (that is,
some text is already written to @var{port}), the procedure takes
the current column into account, as shown below:
@c JP
この手続きを、行の途中 (既に@var{port}にいくらか出力されてから改行されていない状態)
で呼び出した場合、この手続きは@var{port}の現在のカラム位置を考慮に入れるので
次のようになります。
@c COMMON

@example
  width
<--------------------------------------------------------------------->
             start column
                |   hanging
                v<---->
                        Lorem ipsum dolor sit amet, consectetur
          adipiscing elit, sed do eiusmod tempor incididunt ut labore
          et dolore magna aliqua.  Ut enim ad minim veniam, quis
          nostrud exercitation ullamco laboris nisi ut aliquip ex ea
          commodo consequat. Duis aute irure dolor in reprehenderit in
          voluptate velit esse cillum dolore eu fugiat nulla pariatur.
          Excepteur sint occaecat cupidatat non proident, sunt in culpa
          qui officia deserunt mollit anim id est laborum.
<-------->
   indent
@end example

@c EN
The @var{start-column} keyword argument can override the port's
current column with the given nonnegative exact integer.
It is only considered for the first paragraph; subsequent paragraphs
are formatted as if @var{start-column} is zero.
@c JP
@var{start-column}引数は開始カラム位置を強制的に指定するものです。
与える場合は正確な非負整数でなければなりません。
この機能は最初のパラグラフのみに適用されます。
二番目以降のパラグラフは@var{start-column}が0であるかのようにフォーマットされます。
@c COMMON

@c EN
The last line of the last paragraph is not terminated by a newline,
allowing the caller to continue output in the same line.
@c JP
最後のパラグラフの最後の行の後に改行文字は出力されません。
呼び出し側がこの行の後にさらに続けて出力することもできるようにするためです。
@c COMMON

@c EN
The length of the line is computed by each character's East Asian
Width (@pxref{East asian width property}).  The actual display
width depends on the fonts, but it gives a reasonable approximation.
@c JP
行の長さは、East Asian Widthを使って計算されます
(@ref{East asian width property}参照)。実際に表示される行幅は
フォントの設定に影響されますが、それなりの出力は得られます。
@c COMMON

@c EN
Finally, if the @var{lead-in} argument is not @code{#f}, it must be
a string that is output before any @var{text} and indentation is
output.  Then, if the column after @var{lead-in} is less than
@var{hanging} minus one, @var{text} will be emitted on the smae
line, starting from @var{hanging} column:
@c JP
最後に、@var{lead-in}引数が与えられて@code{#f}でなければ、
それは文字列でなければならず、@var{text}やインデントの前に出力されます。
そして、もし@var{lead-in}出力後のカラムが@var{hanging}-1カラムより少なければ、
@var{text}は同じ行に出力されます:
@c COMMON

@example
     hanging
<------------------>
THIS IS LEAD-IN.    Lorem ipsum dolor sit amet, consectetur
             adipiscing elit, sed do eiusmod tempor incididunt ut labore
             et dolore magna aliqua.
<----------->
    indent
@end example

@c EN
If @var{lead-in} text is equal to or longer than the @var{hanging}, @var{text}
is emitted from the next line.
@c JP
@var{lead-in}の幅が@var{hanging}以上であれば、@var{text}は次の行から
出力されます。
@c COMMON

@example
     hanging
<------------------>
THIS IS LEAD-IN LONGER THAN HANGING.
                    Lorem ipsum dolor sit amet, consectetur
             adipiscing elit, sed do eiusmod tempor incididunt ut labore
             et dolore magna aliqua.
<----------->
    indent
@end example

@c EN
Even if @var{text} contains more than one paragraph, @var{lead-in} is
displayed only once, at the beginning.
@c JP
@var{text}が複数パラグラフからなる場合でも、@var{lead-in}は最初に一度だけ
出力されます。
@c COMMON

@c EN
This is handy when you display definition-list like document, e.g.
command-line option description.
@c JP
これは定義リスト的なドキュメントを表示する時に便利です。
例えばコマンドラインオプションのヘルプ等。
@c COMMON
@end defun

@defun text->filled-stree text :key indent hanging width start-column lead-in
@c MOD text.fill
@c EN
This is a low-level routine to construct a filled text used by
@code{display-filled-text}.  It returns a string tree
(@pxref{Lazy text construction}).  If you want to add more
text around the filled paragraph, using this procedure can save
constructing intermediate strings.
@c JP
これは@code{display-filled-text}に呼ばれる低レベルルーチンで、
文字列のツリーを返します(@ref{Lazy text construction}参照)。
パラグラフをフィルした後で他のテキストをその周囲に付け足したい場合などに、
中間文字列を作らずに済みます。
@c COMMON

@c EN
The meaning of the keywrd arguments are the same as
@code{display-filled-text}, except that @var{start-column} is
assumed to be 0 if omitted.
@c JP
キーワード引数の意味は@code{display-filled-text}と同じです。
但し@var{start-column}が省略された場合は0とみなされます。
@c COMMON
@end defun


@c ----------------------------------------------------------------------
@node Gap buffer, Localized messages, Text filling, 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
@c EN
This module provides a gap buffer, a data structure useful for
editable text.
@c JP
ギャップバッファは、編集可能なテキストを実装するのに便利なデータ構造です。
@c COMMON

@c EN
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.
@c JP
ギャップバッファは、「カーソル」を持つ文字のベクタと考えることができます。
カーソル位置への文字の挿入、もしくはカーソル位置の文字の削除はO(1)時間でできます。
ほとんどの編集APIは現在のカーソル位置を対象にします。
@c COMMON
@end deftp

@defun make-gap-buffer :key initial-capacity
@c MOD text.gap-buffer
@c EN
Creates a fresh gap buffer and returns it.  The initial content
is empty.
@c JP
新たなギャップバッファを作って返します。初期状態では中身は空です。
@c COMMON

@c EN
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.
@c JP
キーワード引数@var{initial-capacity}は、正の正確な整数でなければならず、
初期状態のバッファの大きさを指定します。バッファは必要に応じて自動的に拡張されるので、
この引数は単なるヒントです。例えば最初に大きな文字列を挿入することがわかっていれば、
あらかじめ大きなバッファを取っておくことで再アロケーションのオーバヘッドを避けることが
できます。
@c COMMON
@end defun

@defun string->gap-buffer string :optional pos whence start end
@c MOD text.gap-buffer
@c EN
Creates a gap buffer that contains the given @var{string},
and returns it.
@c JP
与えられた文字列@var{string}を保持するギャップバッファを作って返します。
@c COMMON

@c EN
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.
@c JP
カーソルの初期位置は、デフォルトでは文字列の最後です。
@var{pos}と@var{whence}引数で初期位置を変更することができます。
@var{whence}はシンボル@code{beginning}か@code{end}で、@var{pos}は
whenceからのオフセットを表す正確な整数です。例えば@var{pos}が10で
@var{whence}が@code{beginning}なら、文字列の先頭から10番目の文字にカーソルが
置かれます。@var{pos}が-1で@var{whence}が@code{end}なら、文字列の最後から
ひとつ手前の文字にカーソルが置かれます。@var{pos}と@var{whence}の組み合わせが
文字列をはみ出してしまう場合はエラーが投げられます。
@c COMMON

@c EN
The optional @var{start} and @var{end} trims the input string before
creating the gap buffer.
@c JP
省略可能な@var{start}と@var{end}引数は、ギャップバッファを作る前に
入力文字列の範囲を制限します。
@c COMMON
@end defun

@defun gap-buffer? obj
@c MOD text.gap-buffer
@c EN
Returns @code{#t} iff @var{obj} is a gap buffer.
@c JP
@var{obj}がギャップバッファなら@code{#t}を、そうでなければ@code{#f}を返します。
@c COMMON
@end defun

@defun gap-buffer-copy gbuf
@c MOD text.gap-buffer
@c EN
Returns a fresh copy of a gap buffer @var{gbuf}, with the same content
and cursor position.
@c JP
ギャップバッファ@var{gbuf}の新たなコピーを作って返します。内容およびカーソル位置は
@var{gbuf}と同じになります。
@c COMMON
@end defun

@defun gap-buffer->string gbuf :optional start end
@defunx gap-buffer->generator gbuf :optional start end
@c MOD text.gap-buffer
@c EN
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.
@c JP
ギャップバッファ@var{gbuf}の内容を文字列もしくは文字のジェネレータとして取り出します。
省略可能な@var{start}と@var{end}はバッファ内の文字インデックスを指定する非負の正確な整数で、
取り出す内容の範囲を制限します。
@c COMMON

@c EN
If you modify the content of gap buffer before the returned generator
is exhausted, consistent behavior isn't guaranteed.
@c JP
返ってきたジェネレータを最後まで読む前にギャップバッファの内容を変えた場合、
一貫性のある振る舞いは保証されません。
@c COMMON
@end defun

@defun gap-buffer-pos gbuf
@c MOD text.gap-buffer
@c EN
Returns the current cursor position of @var{gbuf}, in a nonnegative
exact integer.
@c JP
ギャップバッファ@var{gbuf}の現在のカーソル位置を非負の正確な整数で返します。
@c COMMON
@end defun

@defun gap-buffer-pos-at-end? gbuf pos
@c MOD text.gap-buffer
@c EN
Returns @code{#t} if @var{pos}, a position in nonnegative integer,
is at the end of @var{gbuf}, @code{#f} otherwise.
@c JP
位置を表す非負整数@var{pos}がギャップバッファ@var{gbuf}の末尾を差していれば@code{#t}を、
そうでなければ@code{#f}を返します。
@c COMMON
@end defun

@defun gap-buffer-capacity gbuf
@c MOD text.gap-buffer
@c EN
Returns the currently allocated storage size of @var{gbuf}, in character count.
If you insert more characters into @var{gbuf}, the storage is automatically
expanded.
@c JP
ギャップバッファ@var{gbuf}に現在アロケートされているストレージの大きさを
文字数で返します。@var{gbuf}に格納する文字がそれを越えたら、ストレージは自動的に拡張されます。
@c COMMON
@end defun

@defun gap-buffer-content-length gbuf
@c MOD text.gap-buffer
@c EN
Returns the length of current content of @var{gbuf},
in the number of characters.
@c JP
ギャップバッファ@var{gbuf}に現在格納されている内容の大きさを、文字数で返します。
@c COMMON
@end defun

@defun gap-buffer-gap-at? gbuf whence
@c MOD text.gap-buffer
@c EN
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.
@c JP
@var{whence}引数はシンボル@code{beginning}か@code{end}のいずれかです。
ギャップバッファ@var{gbuf}の現在のカーソル位置がそれぞれバッファの先頭または末尾
である場合に@code{#t},をそうでなければ@code{#f}を返します。
@c COMMON
@end defun

@defun gap-buffer-ref gbuf index :optional fallback
@c MOD text.gap-buffer
@c EN
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.
@c JP
ギャップバッファ@var{gbuf}の@var{index}番目の文字を返します。@var{index}が
範囲外の場合、@var{fallback}が与えられればそれを返し、無ければエラーが投げられます。
@c COMMON
@end defun

@defun gap-buffer-set! gbuf index char
@c MOD text.gap-buffer
@c EN
Replaces @var{index}-th character of @var{gbuf} with @var{char}.
If @var{index} is out of range, an error is signaled.
@c JP
ギャップバッファ@var{gbuf}の@var{index}番目の文字を@var{char}で置き換えます。
@var{index}が範囲外の場合はエラーが投げられます。
@c COMMON
@end defun

@defun gap-buffer-move! gbuf pos :optional whence
@c MOD text.gap-buffer
@c EN
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},
@code{current} or @code{end}.  If omitted, @code{beginning} is assumed.
@c JP
@var{gbuf}のカーソル位置を@var{pos}に移動します。@var{pos}は正確な整数でなければなりません。
@var{pos}は@var{whence}からの相対位置と解釈されます。@var{whence}は
シンボル@code{beginning}、@code{current}、@code{end}のいずれかです。
省略された場合は@code{beginning}と同等です。
@c COMMON
@end defun

@defun gap-buffer-insert! gbuf content
@c MOD text.gap-buffer
@c EN
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.
@c JP
@var{content}は文字または文字列です。@var{content}を@var{gbuf}の
現在のカーソル位置に挿入します。
カーソルは、挿入された内容の末尾へと移動します。
@c COMMON
@end defun

@defun gap-buffer-delete! gbuf size
@c MOD text.gap-buffer
@c EN
Delets @var{size} characters from the current cursor position
of @var{gbuf}.  The @var{size} argument must be a nonnegative exact integer.
It is an error if @var{size} overruns.
@c JP
@var{gbuf}の現在のカーソル位置から@var{size}文字を削除します。
@var{size}は非負の正確な整数でなければなりません。
@var{size}が現在の内容を越えてしまう場合はエラーとなります。
@c COMMON
@end defun

@defun gap-buffer-clear! gbuf
@c MOD text.gap-buffer
@c EN
Makes @var{gbuf} empty.
@c JP
@var{gbuf}を空にします。
@c COMMON
@end defun

@defun gap-buffer-replace! gbuf size content
@c MOD text.gap-buffer
@c EN
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.
@c JP
これは@code{(gap-buffer-delete! gbuf size)}と
@code{(gap-buffer-insert! gbuf content)}を続けて実行するのと同じです。
@var{size}は非負の正確な整数でなければならず、
@var{content}は文字か文字列でなければなりません。
@c COMMON
@end defun

@defun gap-buffer-contains gbuf str :optional gstart gend sstart send
@c MOD text.gap-buffer
@c EN
Search a string @var{str} in a gap buffer @var{gbuf}.  If found,
returns the integer index of the beginning of @var{str} in @var{gbuf}.
If not found, returns @code{#f}.
@c JP
文字列@var{str}をギャップバッファ@var{gbuf}の中から探します。
見つかったら、その先頭の文字インデックスを返します。
見つからなかったら@code{#f}を返します。
@c COMMON

@c EN
The optional arguments @var{gstart} and @var{gend}
restricts the range of @var{gbuf} to be searched, by integer indexes.
The default is the entire buffer.
You can pass @code{#f} to indicate to use the
default value.
@c JP
省略可能引数@var{start}と@var{gend}は、@var{gbuf}内で検索すべき範囲を
制限する整数インデックスです。デフォルトではバッファ全体が検索対象となります。
@code{#f}を渡すことでデフォルトの動作とすることができます。
@c COMMON

@c EN
The optional arguments @var{sstart} and @var{send} restricts
the span of @var{str} to be searched, by integer indexes.
You can pass @code{#f} to indicate to use the
default value.
@c JP
省略可能引数@var{sstart}と@var{send}は、@var{str}から
検索文字列を切り出す整数インデックスです。
@code{#f}を渡すことでデフォルトの動作とすることができます。
@c COMMON
@end defun

@defun gap-buffer-looking-at? gbuf str :optional point
@c MOD text.gap-buffer
@c EN
Returns @code{#t} iff the content immeidately following @var{point}
matches a string @var{str}.  If @var{point} is omitted or @code{#f},
the current cursor position is used.
@c JP
整数インデックス@var{point}以降の内容の先頭が文字列@var{str}と一致する場合に
@code{#t}を、そうでなければ@code{#f}を返します。
@var{point}が@code{#f}か省略された場合は現在のカーソル位置が使われます。
@c COMMON
@end defun


@defun gap-buffer-edit! gbuf edit-command
@c MOD text.gap-buffer
@c EN
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:
@c JP
これはギャップバッファ@var{gbuf}に対する編集を「リプレイ」するのに便利な手続きです。
@var{edit-command}引数は、次のいずれかの形のフォームです。
@c COMMON

@table @code
@item (i @var{pos} @var{string})
@c EN
Insert @var{string} at a position @var{pos}.
@c JP
@var{string}を@var{pos}位置に挿入　(<b>I</b>nsert)。
@c COMMON
@item (d @var{pos} @var{length})
@c EN
Delete @var{length} characters from a position @var{pos}.
@c JP
@var{pos}位置から@var{length}文字を削除 (<b>D</b>elete)。
@c COMMON
@item (c @var{pos} @var{length} @var{string})
@c EN
Change: Deletes @var{length} characters from a position @var{pos},
then insert @var{string}.
@c JP
@var{pos}位置からの@var{length}文字を@var{string}へと変更 (<b>C</b>hange)。
@c COMMON
@end table

@c EN
Here, @var{pos} must be a nonnegative exact integer specifying the
position in the gap buffer.
@c JP
ただし、@var{pos}はバッファ先頭からの文字位置を示す非負の正確な整数です。
@c COMMON

@c EN
It returns another edit-command that undo the change.
@c JP
この手続きは、加えた変更を元に戻す編集コマンドを返します。
@c COMMON

@c EN
One of the appliations of this procedure is to handle undo/redo list.
@c JP
この手続きの使用場面のひとつは、undo/redoリストの処理です。
@c COMMON

@example
(define buf (string->gap-buffer "Hello, World!"))

(gap-buffer-edit! buf '(d 0 5))
  @result{} (i 0 "Hello")

(gap-buffer-edit! buf '(i 0 "Konnichiwa"))
  @result{} (d 0 10)

(gap-buffer->string buf)
  @result{} "Aloha, World!"

@c EN
;; Giving the returned values of gap-buffer-edit! in reverse order,
;; you can undo the changes:
@c JP
;; gap-buffer-edit!の戻り値を逆順に適用すると元に戻せる
@c COMMON

(for-each (cut gap-buffer-edit! buf <>) '((d 0 10) (i 0 "Hello")))
(gap-buffer->string buf)
  @result{} "Hello, World!"
@end example
@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, Accessing info document, 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{https://www.w3.org/TR/html4/sgml/dtd.html}).
@c JP
@var{element} の HTML 要素を構築します。現時点では以下の要素が
サポートされています。
(HTML 4.01 DTD @uref{https://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 Accessing info document, Multicolumn formatting, Simple HTML document construction, Library modules - Utilities
@section @code{text.info} - Accessing info document
@c NODE infoドキュメントアクセス, @code{text.info} - infoドキュメントアクセス

@deftp {Module} text.info
@mdindex text.info
@c EN
This module provides some basic functionalities to extract information
from @code{info} files, a documentation format defined by
@code{texinfo} system (@url{https://www.gnu.org/software/texinfo/}).
It is used in REPL toplevel commands @code{info}and @code{doc}
(@pxref{Working in REPL}).
It focuses mainly to handle Gauche documents, so it may not handle
all features used in texinfo.
@c JP
このモジュールは、@code{texinfo}システムが生成する
@code{info}ファイルから情報を抜き出す基本的な機能を提供します。
(texinfoについては@url{https://www.gnu.org/software/texinfo/}参照)。
REPLのトップレベルコマンド@code{info}や@code{doc}はこのモジュールを
使っています(@ref{Working in REPL})。
主にGaucheのドキュメントを扱うために作られたので、texinfoの全ての機能はカバーされていません。
@c COMMON
@end deftp

@deftp {Class} <info-document>
@clindex info-file
@c MOD text.info
@c EN
An object for opened info file(s), returned by @code{open-info-document}.
All slots are private.
@c JP
infoファイルの集合であるinfoドキュメントを表すオブジェクトです。
@code{open-info-document}が返します。スロットは全てプライベートです。
@c COMMON
@end deftp

@deftp {Class} <info-node>
@clindex info-node
@c MOD text.info
@c EN
An object for each info node.  It keeps the node's content, as well
as links to neighboring nodes.  Its instance should be considered
immutable object.

A node can be obtained from an @code{<info-document>} object by
@code{info-get-node}.
@c JP
infoノードを表すオブジェクトです。ノードの内容と他のノードへの参照を持っています。
インスタンスは変更不可なオブジェクトとして扱われなければなりません。

@code{<info-document>}オブジェクトに@code{info-get-node}を適用することで
ノードを得ることができます。
@c COMMON

@defivar <info-node> name
@c EN
A string name of the info node.  Every info document has at least
@code{"Top"} node.
@c JP
ノードの名前の文字列です。どのinfoドキュメントにも、最低限@code{"Top"}ノードは
含まれています。
@c COMMON
@end defivar

@defivar <info-node> next
@c EN
The string name of the next node.  You can visit all nodes in
the document following the next link.
It may be @code{#f} if the node is the last one of the document.
@c JP
「次」のノードの名前の文字列です。「次」をたどってゆくことで、ドキュメントの全ての
ノードを見ることができます。
ドキュメントの最後のノードでは@code{#f}になっています。
@c COMMON
@end defivar

@defivar <info-node> prev
@c EN
The string name of the previous node.  It's a reverse link
of the next node.  The previous node of @code{"Top"} is
@code{"(dir)"} by convention, which is a special node
that lists all info documents installed on the system (it is not
included in the info document itself.)
@c JP
「前」のノードの名前の文字列です。「次」のノードとは逆のリンクになっています。
@code{"Top"}のノードの前は慣習により@code{"(dir)"}となっていて、
infoシステムではシステムにインストールされている全てのinfoドキュメントを表示する
特別なノード名となっています。
@c COMMON
@end defivar

@defivar <info-node> up
@c EN
If the node is a subnode, this contains the name of the upper node
(a chapter name for sections, a section name for subsections, etc.)
It is @code{#f} for @code{"Top"} node.
@c JP
このノードが他のノードのサブノードなら、親となるノードの名前の文字列。
例えばこのノードが節(section)なら、親は章(chapter)です。
@code{"Top"}ノードではここは@code{#f}です。
@c COMMON
@end defivar

@defivar <info-node> file
@c EN
An @code{<info-document>} object of the info document this node is contained.
@c JP
このノードが含まれる@code{<info-document>}オブジェクトです。
@c COMMON
@end defivar

@defivar <info-node> content
@c EN
A string content of the node.
@c JP
ノードの内容の文字列です。
@c COMMON
@end defivar
@end deftp

@defun open-info-document info-file-path
@c MOD text.info
@c EN
Open the named info document and returns an @code{<info-document>} instance.
The argument is a pathname to a master info file, usually with
@code{.info} suffix.  Depending on the installation, info files
may be compressed with gzip or bzip2, having extensions
@code{.gz} or @code{.bz2} after @code{.info}; you don't need to
specify those extensions.  The procedure searches possible compression
options.
@c JP
指定されたパスのinfoドキュメントを読み込んで@code{<info-document>}インスタンスを
返します。引数はマスターinfoファイルのパス名で、通常@code{.info}サフィックスが
ついています。インストール状況によってはinfoファイルはgzipやbzip2で圧縮されていて、
@code{.info}の後に@code{.gz}や@code{.bz2}がついていることもありますが、
これらの圧縮サフィックスはつける必要がありません。この手続きは指定のパス名そのものが
見つからなかったら圧縮サフィックスがついている名前も探します。
@c COMMON

@c EN
A large info document may be splitted into multiple info files,
each with a suffix @code{.info-1}, @code{.info-2} etc.  Those are
automatically read, so you only need to give the path to the master file.
@c JP
大きなinfoドキュメントは分割されていて、それぞれに@code{.info-1}、@code{.info-2}
などの名前がついていますが、それらは自動的に読まれるので、マスターとなるinfoファイルだけ
指定すれば良いです。
@c COMMON

@c EN
If it can't find the named document, or can't recognize its format,
an error is thrown.
@c JP
infoドキュメントが見つからなかったり、ファイルフォーマットが認識できなかった場合は
エラーが投げられます。
@c COMMON
@end defun

@defun info-get-node info-doc node-name
@c MOD text.info
@c EN
The @var{info-doc} argument is an @code{<info-document>} instance.
Returns an @code{<info-node>} instance with the string name @var{node-name},
or @code{#f} if no node with the given name is found.
@c JP
@code{<info-document>}のインスタンス@var{info-doc}から、
@var{node-name}を持つノードを探して、その@code{<info-node>}インスタンスを返します。
該当するノードが見つからなければ@code{#f}を返します。
@c COMMON
@end defun

@defun info-index-add! info-doc index-node-name :optional key-modifier
@c MOD text.info
@c EN
Read the node named @var{index-node-name} in the info document
@var{info-doc}, and adds its menu entries into the index table.
@c JP
infoドキュメント@var{info-doc}にある、名前@var{index-node-name}持つノードを
読み取り、そのメニューの内容をインデックステーブルに加えます。
@c COMMON

@c EN
It is particularly useful to give the index page of the info doc,
so that you'll be able to lookup particular term (e.g. function name)
quickly.  Typical info document has a node called @code{Index}.
Large documents, such as programming language reference
(Gauche Users' Reference is one of them) may have multiple
index pages for different categories.  You can call this procedure
multiple times to add more than one index pages.
@c JP
この手続きは、infoドキュメントの索引ノードを読み込んで索引を作るのに便利です。
例えば関数索引のページを読み込めば、関数名から定義があるノードを探し当てることができます。
典型的なinfoドキュメントでは、索引ページには@code{Index}という名前がついています。
但し、長いドキュメントでは索引がカテゴリごとに分けられていて、
それぞれ違う名前がついているかもしれません (Gaucheのユーザリファレンスもそのひとつです)。
この手続きをそれぞれの索引ノードについて呼び出すことで、複数の索引ノードの内容を
取り込むことができます。
@c COMMON

@c EN
The optional @var{key-modifier} argument is a procedure applied to
the entry-name (string) to obtain a key (string) in the index table.
Sometimes the index uses different entry name
from the actual name; e.g. Gauche's class index lists class names without
surrounding @code{<} and @code{>}, since using the actual name makes all
class names being listed below @code{<} subheading, which isn't very useful.
You can pass @code{(^e #"<~|e|>")} as @var{key-modifier} to recover the actual
class name to be used as the key.
@c JP
省略可能な@var{key-modifier}引数は、索引ノードのテーブルのキー(文字列)を取って
実際の見出しを文字列で返す手続きです。
しばしば索引に示されるキーは、実際の見出しとは異なることがあります。
例えばGaucheのクラス索引は、クラス名を囲む@code{<}と@code{>}を取り除いたものを
キーとしています。実際の名前を使うと、全てのキーが@code{<}の下に集められてしまい
あまり有用ではないからです。この場合は、@var{key-modifier}に
@code{(^e #"<~|e|>")}を渡すことで、実際の名前で索引を引けるようになります。
@c COMMON

@c EN
If there are more than one entries per key, both are saved in the
index table.  See @code{info-index-ref} below.
@c JP
同じキーに対応するエントリが複数ある場合、それらは全てテーブルに格納されます。
下の@code{info-index-ref}を参照してください。
@c COMMON
@end defun

@defun info-index-ref info-doc key
@c MOD text.info
@c EN
Lookup index with the given key.  Returns a list of
@code{(@var{node-name} @var{line-number})}.

You can use pass @var{node-name} to @code{info-node-get} to obtain the
info node contaning the definition, then pass the node and
@var{line-number} to @code{info-extract-definition}
to obtain the definition as a text.
@c JP
キーに対応するエントリを索引テーブルから探し、
@code{(@var{node-name} @var{line-number})}のリストを返します。

@var{node-name}を@code{info-node-get}に渡せば定義を含んでいるinfoノードを
得られます。また、そのinfoノードと@var{line-number}を
@code{info-extract-definition}に渡せば定義をテキストで得ることができます。
@c COMMON
@end defun

@defun info-index-keys info-doc
@c MOD text.info
@c EN
Returns a list of keys (strings) in the index.
@c JP
infoドキュメントの索引テーブルに登録されているキー(文字列)のリストを返します。
@c COMMON
@end defun

@defun info-index->alist info-doc
@c MOD text.info
@c EN
Returns the content of the index
as @code{((key (node line) ...) ...)}.
@c JP
infoドキュメントの索引テーブルの内容を
@code{((key (node line) ...) ...)}の形で返します。
@c COMMON
@end defun

@defun info-parse-menu info-node
@c MOD text.info
@c EN
This is used in @code{info-index-add!}, but it is generally
useful to parse a menu in an info node.   It searches
the @code{* Menu:} line, then gathers menu entry names and
associated node names.  Some menus such as index page also
lists line numbers for each entry.
@c JP
これは@code{info-index-add!}の中で使われている手続きですが、
単独でinfoノード中のメニューをパーズするのにも使えます。
@code{* Menu:}という行を探し、見つかったらそれに続く
エントリ名とノード名を集めます。索引ページの場合はノード名だけでなく
定義のある行番号も記されています。
@c COMMON

@c EN
Returns a list of menu entries.
Each menu entry is the following form:
@c JP
見つかったメニューエントリのリストを返します。各エントリは次の形です。
@c COMMON
@example
(<entry-name> <node-name> [<line-number>])
@end example
@end defun

@defun info-extract-definition info-node start-line
@c MOD text.info
@c EN
Extract one definition from the node's content.  Assumes the definition
begins from the specified line; then we go forward to find the end of
the definition.  The end of definition is when we see the end of content,
or we see a line begins with less than or equal to 3 whitespaces.
(Except the 'defunx'-type multi entry).
@c JP
ノードの内容から、ひとつの定義を抜き出して文字列で返します。
定義は@var{start-line}で示される行から始まっていると解釈されます。
その行から順に見てゆき、定義の終わりを探します。定義の終わりは、
infoノードの終わりか、3つ未満の空白文字で始まっている行の手前までです
(但し、'defunx'形式の複数エントリは定義の終わりとはみなされません)。
@c COMMON

@c EN
Returns a string describing the definition.  If no definition is found,
an empty string is returned.
@c JP
定義を記述している文字列を返します。定義が見つからなければ空文字列が返ります。
@c COMMON

@c EN
A typical idiom is to add index node using @code{info-index-add!},
and get the node name and line number of the definition of a specific
item with @code{info-index-ref}, then
then use this procedure to extract the definition.
@c JP
典型的な使いかたは、まず索引ノードを@code{info-index-add!}で登録しておき、
@code{info-index-ref}で知りたい見出しの定義を含むノードと行を入手して、
この手続きで実際の定義を得るというものです。
@c COMMON
@end defun

@c ----------------------------------------------------------------------
@node Multicolumn formatting, Display with pager, Accessing info document, Library modules - Utilities
@section @code{text.multicolumn} - Multicolumn formatting
@c NODE 複数列フォーマット, @code{text.multicolumn} - 複数列フォーマット

@deftp {Module} text.multicolumn
@mdindex text.multicolumn
@c EN
This module provides the means to format a list of words into
a multicolumn text.  Think of the output of @code{ls} command.
@c JP
このモジュールは、単語のリストを複数カラム形式に揃えてフォーマットする手段を提供します。
@code{ls}コマンドの出力のようなものを想像してください。
@c COMMON

@example
(display-multicolumn
  (string-tokenize "The quick brown fox \
                    jumps over the lazy dog"))
 @result{} @r{prints}
The     fox     the
quick   jumps   lazy
brown   over    dog
@end example

@c EN
Various options are provided to customize the output.
@c JP
出力をカスタマイズできる様々なオプションが提供されます。
@c COMMON
@end deftp

@defun display-multicolumn strs :key width minimum-width max-columns order indent style
@c MOD text.multicolumn
@c EN
Display items in a list of strings @var{strs} in multicolumn format,
to the current output port.
The items shouldn't contain newline or tab characters; the procedure
doesn't treat them specially, so the output would be disturbed.

The width of a column is chosen to contain the longest string in @var{strs}
or @var{minimum-width}, whichever greater.
The default of @var{minimum-width} is 8.
@c JP
文字列のリスト@var{strs}の要素を、現在の出力ポートに複数カラム形式に揃えて表示します。
要素中にタブや改行文字があってはなりません。手続きはタブや改行文字を特別扱いしないので、
もし含まれていた場合は出力が乱れます。

カラムの幅は、@var{strs}中の文字列のうち最も長いものか、@var{minimum-width}の
どちらか大きい方で決まります。@var{minimum-width}のデフォルトは8です。
@c COMMON

@c EN
Then as many columns are displayed as fit in @var{width} characters,
whose default is 80.  However, the number of columns won't exceed
@var{max-columns} if it is given and not @code{#f}.
@c JP
カラムの幅が決まったら、@var{width}文字の幅にいくつのカラムが収まるかが計算されます。
@var{width}のデフォルトは80です。但し@var{max-columns}が与えられて@code{#f}でなければ、
カラム数は@var{max-column}を越えません。
@c COMMON

@c EN
The @var{order} argument must be either a symbol @code{column} or
@code{row}.  If it is @code{column} (default), the items are sorted
column-first; that is, it is filled in the first column from top to
down, then the second column from top to down, and so on.
If it is @code{row}, the items are sorted row-first; it is filled
in the first row from left to right, and then second row, and so on.
@c JP
@var{order}引数はシンボル@code{column}か@code{row}のどちらかです。
@code{column}の場合(デフォルト)、要素はカラムファースト、つまり最初のカラムを
上から下へ、それから第二カラムを上から下へ、という順に並べられます。
@code{row}の場合はロウファースト、つまり最初の行の左から右、次の行の左から右、
という順に並べられます。
@c COMMON

@c EN
The @var{indent} argument must be a nonnegative exact integer.  If it is
greater than zero, that number of whitespaces are prepended before
each line.  The @var{width} includes this indentation; so the actual
area of text becomes narrower by @var{indent} characters.
@c JP
@var{indent}引数は、与えられたなら非負の正確な整数でなければなりません。
これが1以上の場合、その数の空白文字が各行の先頭に追加されます。
@var{width}で指定される幅はこのインデントを含んだものとなります。つまり
テキストの表示領域の幅はこの引数の分だけ狭くなります。
@c COMMON

@c EN
The @var{style} argument may take either one of the symbols @code{even}
or @code{packed}.  If it is @code{even} (default), all columnts have
even width, based on the longest item.
If it is @code{packed}, each column gets a width that's enough to contain
that particular column.  It may allow more columns to fit.
@c JP
@var{style}引数はシンボル@code{even}か@code{packed}のどちらかです。
@code{even}の場合(デフォルト)、全てのカラムは等幅で、最も長い項目が
収まるように配置されます。@code{packed}の場合は、各カラムの幅は
そのカラムの項目だけを収めるのに必要な分が取られます。
これにより、より多くのカラムを幅に収めて表示できるかもしれません。
@c COMMON

@c EN
The @code{packed} style is particulary effective when you have mostly
short items and just a few long items.  With @code{even} style,
columns that do not contain long items still gets the same width,
resulting lots of whitespaces.  @code{Packed} style takes width only for
columns that contain long items, leading to more columns, fewer rows,
and more uniform text density.
@c JP
@code{packed}スタイルは、ほとんどの項目が短い中にごく少数の長い項目が含まれている
ような場合にとりわけ有効です。@code{even}スタイルだとそういう場合、
短い項目だけが含まれるカラムにも同じ幅が割当てられるため、空白が多い、
スカスカな表示になってしまいます。@code{packed}スタイルでは
長い項目を含んでいるカラムだけに広い幅を与えるので、より少ない行、
より多くのカラムを使って、見た目のテキストの密度がより一様な表示になります。
@c COMMON
@end defun

@defun layout-multicolumn strs :key width minimum-width max-columns order style
@c MOD text.multicolumn
@c EN
This is an underlying procedure of @code{display-multicolumn}.  It returns
a list of text tree (@pxref{Lazy text construction}).  Each text
tree stands for a line, not including the newline character.
This can be handy if you want to modify the layout.
@c JP
この手続きは@code{display-multicolumn}の下請けにあるもので、
テキストツリーのリストを返します (テキストツリーについては
@ref{Lazy text construction}参照)。
各テキストツリーが一行に相当します。改行文字は含まれません。
レイアウトを後から加工したい場合に便利です。
@c COMMON

@example
(layout-multicolumn
  (string-tokenize "The quick brown fox \
                    jumps over the lazy dog"))
 @result{}
(("The     " "fox     " "the")
 ("quick   " "jumps   " "lazy")
 ("brown   " "over    " "dog"))
@end example

@c EN
NB: The actual structure of each text tree may be changed, but
passing it to @code{tree->string} or @code{write-tree} produces
the line.
@c JP
註: テキストツリーの中身はバージョンによって異なるかもしれませんが、
@code{tree->string}や@code{write-tree}に渡した結果は同じになります。
@c COMMON
@end defun


@c ----------------------------------------------------------------------
@node Display with pager, Parsing input stream, Multicolumn formatting, Library modules - Utilities
@section @code{text.pager} - Display with pager
@c NODE ページャーを用いた出力, @code{text.pager} - ページャーを用いた出力

@deftp {Module} text.pager
@mdindex text.pager
@c EN
A convenience module to present long text nicely to the user.
@c JP
長いテキストをユーザに見やすく呈示するための便利モジュールです。
@c COMMON
@end deftp

@deffn {Parameter} pager-program
@c MOD text.pager
@c EN
A parameter containing a list of pager program and its arguments
(e.g. @code{("/usr/bin/less" "-M")}).
@c JP
ページャーとして使うプログラムとその引数のリストを保持するパラメータです。
例: @code{("/usr/bin/less" "-M")}。
@c COMMON

@c EN
The program must take input from the standard input.
@c JP
プログラムは標準入力から入力を取らなければなりません。
@c COMMON

@c EN
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.  If none is found, @code{#f} is set.
@c JP
デフォルトの値は、環境変数@code{PAGER}がセットされていればその値、
そうでなければ、システムに@code{less}または@code{more}があればそれを使います。
いずれにも該当しなければ@code{#f}になっています。
@c COMMON
@end deffn

@defun display/pager string
@c MOD text.pager
@c EN
Display @var{string} by a pager subprocess specified by the parameter
@code{pager-program}.  The procedure returns when the subprocess exits.
@c JP
パラメータ@code{pager-program}で指定されるプログラムをサブプロセスとして起動し、
@var{string}を表示させます。サブプロセスが終了するまでこの手続きは返ってきません。
@c COMMON

@c EN
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.
@c JP
端末がページングに適さない場合 (例えば@code{TERM}が@code{dumb}や@code{emacs}である
場合)は、@var{string}が単に@code{display}で表示されます。
@c COMMON

@c EN
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).
@c JP
MinGWバージョンの@code{gosh}をminttyで使っている場合、
サブプロセス経由のページングはうまく動かないので、
この手続きがページャの動作をエミュレートします (@code{pager-program}は無視されます)。
@c COMMON
@end defun

@defun with-output-to-pager thunk
@c MOD text.pager
@c EN
Call @var{thunk} with its current output port to a string buffer,
then show the buffered output using @code{display/pager}.
@c JP
現在の出力ポートを文字列のバッファにして@var{thunk}を呼び出し、
結果を@code{display/pager}で表示します。
@c COMMON
@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{https://okmij.org/ftp/Scheme/parsing.html}).
His library is used in lots of other libraries, notably,
a full-Scheme XML parser/generator SSAX (@uref{https://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{https://okmij.org/ftp/Scheme/parsing.html}) に
触発され、互換性を持つものです。氏のライブラリは、他のたくさんの
ライブラリで使われています。特に、Scheme のみで書かれたパーサ/ジェネレータ
である SSAX (@uref{https://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, Segmented string matching, 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 Segmented string matching, Shell text utilities, Showing progress on text terminals, Library modules - Utilities
@section @code{text.segmented-match} - Segmented string matching
@c NODE 区切られた文字列のマッチ, @code{text.segmented-match} - 区切られた文字列のマッチ

@deftp {Module} text.segmented-match
@mdindex text.segmented-match
@c EN
Sometimes you want to search for a group of words concatenated with
a delimiter, using only the prefixes of each words.  For example:
you want to search @code{call-with-current-continuation} using
@code{c-w-c-c}.  One of its popular applications is symbol completion,
which Gauche provides on REPL (@pxref{Input editing}).
@c JP
しばしば、複数の単語をデリミタでつないだ文字列を、各単語のプレフィクスだけを指定して
サーチしたいことがあります。例えば@code{c-w-c-c}を指定して
@code{call-with-current-continuation}を探す、というようなことです。
これはシンボルの補完などによく使われ、
GaucheのREPLでも採用しています (@ref{Input editing}参照)。
@c COMMON

@c EN
This module provides basic parts to perform such searching.
@c JP
このモジュールは、そういうサーチをするための基本的な部品を提供します。
@c COMMON
@end deftp

@defun segmented-prefix? pattern word :optional separator
@c MOD text.segmented-match
@c EN
The @var{pattern} and @var{word} arguments must be a string, and
@var{separator} must be either a character, a character set,
a regexp, a predicate taking a character, or a string.
When @var{separator} is omitted, @code{#\-} is assumed.
@c JP
@var{pattern}と@var{word}はともに文字列、@var{separator}は
文字、文字集合、正規表現、文字を取る述語、あるいは文字列のいずれかでなければなりません。
@var{separator}が省略された場合は@code{#\-}が使われます。
@c COMMON

@c EN
First, @var{pattern} and @var{word} are splitted into segments
by @var{separator},
using @code{string-split} (@pxref{String utilities}).  If every
segments from @var{pattern} consist a prefix of the corresponding
segments from @var{word}, it returns @code{#t}.  It is allowed
for @var{word} to have more segments than @var{pattern}.
@c JP
まず@var{pattern}と@var{word}が@var{separator}を区切りとして
@code{string-split}により分割されます (@ref{String utilities}参照)。
そして、@var{pattern}の分割されたそれぞれの断片が全て@var{word}の分割された対応する
断片のプレフィクスになっている場合に@code{#t}が、そうでなければ@code{#f}が返されます。
@var{word}の断片の方が@var{pattern}の断片より多い場合は、余った分は無視されます。
@c COMMON

@example
(segmented-prefix? "a-b-c" "alpha-bravo-charlie") @result{} #t
(segmented-prefix? "a-b" "alpha-bravo-charlie") @result{} #t
(segmented-prefix? "al-br-char" "alpha-bravo-charlie") @result{} #t
(segmented-prefix? "a-b" "alpha-delta-charlie") @result{} #f
@end example
@end defun

@defun make-segmented-prefix-matcher pattern separator
@c MOD text.segmented-match
@c EN
This is a subfunction of @code{segmented-prefix?}.
@c JP
@code{segmented-prefix?}の下請け手続きです。
@c COMMON

@c EN
Returns a procedure that takes a string @var{word}, and sees if
each segment of @var{pattern} is a prefix of corresponding segment
of @var{word}.  If any of the @var{pattern}'s segment is not a
prefix of the corresponding @var{word}'s segment, @code{#f} is
returned.  Otherwise, it returns a true value: If the number of
@var{word}'s segments is the same as the @var{pattern}'s, @code{#t}
is retured; if @var{word} has more segments, the remaining part
of the @var{word} (exclusing leading separator) is returned.
@c JP
一つの文字列引数@var{word}を取る述語関数を返します。その関数は、
@var{pattern}のそれぞれの断片のうち、@var{word}の対応する断片の
プレフィクスになっていないものがひとつでもあれば@code{#f}を返します。
そうでない場合、@var{word}の断片の数と@var{pattern}の断片の数が同じであれば
@code{#t}が、@var{word}の断片の数が多ければ、@var{word}のマッチしなかった
残りの部分 (先頭の@var{separator}は除く) が返されます。
@c COMMON

@example
((make-segmented-prefix-matcher "a-b-c" #\-) "alpha-bravo-charlie")
 @result{} #t
((make-segmented-prefix-matcher "a-b" #\-) "alpha-bravo-charlie-delta")
 @result{} "charlie-delta"
((make-segmented-prefix-matcher "a-b" #\-) "alpha-charlie-delta")
 @result{} #f
@end example

@c EN
This preprocesses @var{pattern}, so if you want to match
many words against a single pattern, it is faster to get
predicates with this procedure than applying @code{segmented-prefix?}
repeatedly.
@c JP
この手続きは@var{pattern}をプリプロセスするので、一つのパターンに対して
多くの単語をマッチさせたい場合は、毎回@code{segmented-prefix?}を呼び出すより
効率的です。
@c COMMON
@end defun

@c ----------------------------------------------------------------------
@node Shell text utilities, SQL parsing and construction, Segmented string matching, Library modules - Utilities
@section @code{text.sh} - Shell text utilities
@c NODE シェルのテキストユーティリティ, @code{text.sh} - シェルのテキストユーティリティ

@deftp {Module} text.sh
@mdindex text.sh
@c EN
This module provides several utilities useful when you're writing
shell-like scripts.
@c JP
このモジュールは、シェルスクリプト風のスクリプトを書いている時に便利な
いくつかのユーティリティを提供します。
@c COMMON
@end deftp

@defun shell-escape-string str :optional flavor
@c MOD text.sh
@c EN
If @var{str} contains characters that affects shell's command-line
argument parsing, escape @var{str} to avoid shell's interpretation.
Otherwise, returns @var{str} itself.

The optional @var{flavor} argument takes a symbol to
specify the platform; currently @code{windows} and
@code{posix} can be specified.  The way shell handles
the escape and quotation differ a lot between these platforms;
the @code{windows} flavor uses MSVC runtime argument parsing behavior,
while the @code{posix} flavor assumes IEEE Std 1003.1.
When omitted, the default
value is chosen according to the running platform.
(Note: Cygwin is regarded as @code{posix}.)

Use this procedure when you need to build a command-line string by yourself.
(If you pass a command-line argument list, instead of a single
command-line string, you don't need to escape them since we
bypass the shell.)

(NB: Use this with caution on Windows; if you run a batch file
(@file{*.bat} or @file{*.cmd}), its command-line arguments are
parsed differently, and it is known that there's no safe escaping
way that works for all the cases.  It's up to you to ensure
all arugments are safe when you run those files.  See also
@code{sys-exec} (@pxref{Process management})).
@c JP
@var{str}がシェルのコマンドライン引数解析に影響を与える文字を含んでいる場合、
それらがシェルによって解釈されないようにエスケープされた文字列を返します。
そうでなければ@var{str}自体を返します。

省略可能な@var{flavor}引数はシンボルを取り、プラットフォームを指定します。
現在は@code{windows}か@code{posix}が指定可能です。シェルが
エスケープやクオートを処理する方法がこの二つのプラットフォームで大きく
異なるからです。@code{windows}フレーバーの場合はMVCSランタイムの
引数パージングに合わせ、@code{posix}フレーバーの場合はIEEE Std 1003.1に
合わせます。
省略された場合は、プロセスが走っているプラットフォームが
デフォルトの値となります。(Cygwinは@code{posix}とみなされます。)

自分でコマンドライン文字列を組み立てる必要がある場合に使ってください。
(単一のコマンドライン文字列でなく、コマンドライン引数のリストを渡す場合は
エスケープの必要はありません。引数はシェルを通さずに子プロセスに渡される
からです。)

(註: Windowsでバッチファイル(@file{*.bat}、@file{*.cmd})を起動する場合は、
コマンドラインが異なる方法でパーズされることに注意してください。
特に、あらゆる場合に対して安全に引数をエスケープする方法が無いことが
知られています。バッチファイルに渡す引数を用意する場合は独自にそれが
安全であることを確かめて下さい。@code{sys-exec}のエントリも参照のこと
(@ref{Process management}))。
@c COMMON
@end defun

@defun shell-tokenize-string str :optional flavor
@c MOD text.sh
@c EN
Split a string @var{str} into arguments as the shell does.
@c JP
シェルがやるように、文字列@var{str}を引数リストに分割します。
@c COMMON

@example
(shell-tokenize-string "grep -n -e \"foo bar\" log")
 @result{} ("grep" "-n" "-e" "foo bar" "log")
@end example

@c EN
The optional @var{flavor} arguments can be a symbol either
@code{windows} or @code{posix} to specify the syntax.
If it's @code{windows}, we follow MSVC runtime command-line
argument parser behavior.  If it's @code{posix}, we follow
IEEE Std 1003.1 Shell Command Language.  When omitted,
the default value is chosen according to the running platform.
(Note: Cygwin is regarded as @code{posix}.)
@c JP
省略可能な@var{flavor}引数はシンボル@code{windows}か@code{posix}を取り、
構文を指定します。@code{windows}の場合はMVCSランタイムの
引数パージングに合わせ、@code{posix}フレーバーの場合はIEEE Std 1003.1
Shell Command Languageに合わせます。
省略された場合は、プロセスが走っているプラットフォームが
デフォルトの値となります。(Cygwinは@code{posix}とみなされます。)
@c COMMON

@c EN
This procedure does not handle fancier shell features such
as variable substitution.  If it encounters a metacharacter
that requires such interpretation, an error is signaled.
In other words, metacharacters must be properly quoted
in @var{str}.
@c JP
この手続きはシェルの変数置換のような高度な機能は持っていません。
もしそういった解釈が必要なメタ文字に出会った場合はエラーが投げられます。
言い換えれば、メタ文字は@var{str}の中で全て適切にクオートされている
必要があります。
@c COMMON

@example
(shell-tokenize-string "echo $foo" 'posix)
  @result{} @r{signals error}

(shell-tokenize-string "echo \"$foo\"" 'posix)
  @result{} @r{still signals error}

(shell-tokenize-string "echo '$foo'" 'posix)
  @result{} ("echo" "$foo")

(shell-tokenize-string "echo \\$foo" 'posix)
  @result{} ("echo" "$foo")
@end example
@end defun

@defmac shell-case expr clause @dots{}
@c MOD text.sh
@c EN
This macro implements shell's @code{case} built-in command.
Each @var{clause} must be one fo the following forms:
@c JP
このマクロは、シェルの@code{case}組み込みコマンドを実装します。
各@var{clause}は次の形式のいずれかでなければなりません。
@c COMMON

@itemize @bullet
@item
@code{(@var{pattern} @var{body} @dots{})}
@item
@code{((@var{pattern} @dots{}) @var{body} @dots{})}
@item
@code{(else @var{body} @dots{})}
@end itemize

@c EN
The @code{else} form must appear as the last @var{clause}, if there's any.
@c JP
また、@code{else}フォームはあるなら最後の@var{clause}でなければなりません。
@c COMMON

@c EN
First, @var{expr} is evaluated.  It must produce a string.
Then, each @var{clause} is examined, and the value of @var{expr}
matches one of the @var{pattern}s, then @var{body} @dots{} of the
clause is evaluated, and the last result is returned.
@c JP
まず@var{expr}が評価されます。値は文字列でなければなりません。
次に各@var{clause}が順番に吟味され、@var{expr}の値が@var{pattern}にマッチした
場合にその@var{clause}が選ばれて@var{body} @dots{}が評価され、
最後の式の値が全体の値となります。
@c COMMON

@c EN
When none of @var{clause} has matching @var{pattern}, if @code{else}
clause is provided its @var{body} @dots{} is evaluated, otherwise
an undefined value is returned.
@c JP
いずれの@var{pattern}もマッチしなかった場合、@code{else}節が与えられていれば
その@var{body} @dots{}が評価されて最後の式の値が全体の値となり、
@code{else}節がなければ未定義値が返されます。
@c COMMON

@c EN
The matching is done as @code{glob} (@pxref{Directories}) does.
That is, if a @var{pattern} is @code{"abc*"}, then the value
@code{"abc"},  @code{"abcd"}, @code{"abccc"}, etc. match,
and if a @var{pattern} is @code{"a[bcd]"}, then the value
@code{"ab"}, @code{"ac"} and @code{"ad"} match.
@c JP
マッチは@code{glob}と同じ方法で行われます (@ref{Directories}参照)。
例えば、@var{pattern}が@code{"abc*"}であれば、
@var{expr}の値が@code{"abc"}、@code{"abcd"}、@code{"abccc"}等である
場合にマッチし、@var{pattern}が@code{"a[bcd]"}であれば、
@code{"ab"}、@code{"ac"}、@code{"ad"}がマッチします。
@c COMMON

@c EN
For example, the following shell @code{case} command:
@c JP
次のシェルの@code{case}コマンドは:
@c COMMON

@example
case $arg in
  foo*)        process_foo $arg;;
  ba[rz]|quux) process_bar $arg;;
   *)          process_other $arg;;
esac
@end example

@c EN
can be translated as follows:
@c JP
次のように書き直せるでしょう。
@c COMMON

@example
(shell-case arg
  ["foo*" (process-foo arg)]
  [("ba[rz]" "quux")  (process-bar arg)]
  [else (process-other arg)])
@end example

@c EN
The same thing can be achieved with @code{rxmatch-case}, for example,
but manually translating shell glob pattern to regexp can be tedious
and error-prone.  This is particulary useful when you're rewriting
existing shell scripts in Gauche.
@c JP
同等の処理は例えば@code{rxmatch-case}を使って書くこともできますが、
シェルのglobパターンを正規表現に置き換えてゆくのは面倒ですし
ミスが入り込む余地もあります。
既存のシェルスクリプトをGaucheで最実装する場合には@code{shell-case}は非常に便利な
ツールになるでしょう。
@c COMMON
@end defmac

@defun shell-match pattern str
@c MOD text.sh
@c EN
This extract the matching function of @code{shell-case} to be used
independently.   The @var{pattern} argument must be a glob pattern
string, or a list of glob pattern strings.
The @var{str} argument must be a string.
@c JP
これは@code{shell-case}のマッチ部分の機能だけを独立して取り出したものです。
@var{pattern}はglobパターンを表す文字列、もしくは
globパターンを表す文字列のリストで、
@var{str}は文字列でなければなりません。
@c COMMON

@c EN
If the value of @var{str} matches @var{pattern} (or one of @var{pattern}s
in the second form), it returns @code{#t}. Otherwise, it returns @code{#f}.
@c JP
@var{str}の値が@var{pattern} (もしくは、2番めの形式の場合は@var{pattern}のいずれかに)
マッチしたら@code{#t}を、そうでなければ@code{#f}を返します。
@c COMMON
@end defun

@c ----------------------------------------------------------------------
@node SQL parsing and construction, Simple template expander, Shell text utilities, 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{from-list} contains duplicated characters, the first correspondence
is used, and the subsequent correspondences are ignored.
@c JP
@var{from-list}に文字の重複があった場合、最初の出現位置との対応が使われ、
以降の同じ文字の対応は無視されます。
@c COMMON

@example
(string-tr "abc" "aabbcc" "123456")
 @result{} "135"
@end example

@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

@example
(string-tr "abracadabra" "abc" "" :delete #t)
 @result{} "rdr"
@end example


@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

@c EN
A typical way to compute a message digest would be as follows:
@c JP
メッセージダイジェストを計算する典型的なコードは次のとおりです:
@c COMMON

@example
(use rfc.sha)       ; import actual digest implementation
(use util.digest)

(digest-message-to 'base64url <sha256> "message")
@end example

@c EN
You can use different algorithms, and choose different output
format (e.g. u8vector, hexadecimal string, etc.)
If you need to digest with a secret key, @pxref{HMAC keyed-hashing}.
@c JP
異なるアルゴリズムを選んだり、異なる出力形式を選ぶこともできます
(例: u8vector, 16進数文字列など)。
秘密鍵を用いたダイジェストについては@ref{HMAC keyed-hashing}を参照してください。
@c COMMON
@end deftp

@c EN
@subheading User API
@c JP
@subheading ユーザ向けAPI
@c COMMON

@c EN
To digest a message, you can use the following API.
@c JP
メッセージダイジェストを計算するには、以下のAPIが使えます。
@c COMMON

@deffn {Generic Function} digest-message-to target digester message
@c MOD util.digest
@c EN
Compute a digest of @var{message} using algorithm implemented by @var{digester},
and returns as an instance of class @var{target}.
@c JP
@var{message}のダイジェストを、@var{digester}で指定されるアルゴリズムを使って
計算し、@var{target}クラスのインスタンスで結果を返します。
@c COMMON

@c EN
The @var{message} argument may be a string or a u8vector.
@c JP
@var{message}引数は文字列かu8vectorです。
@c COMMON

@c EN
The @var{digester} argument must be a class inheriting
@code{<message-digest-algorithm>} and implementing the digester protocol
described below.  Gauche provides SHA
(@pxref{SHA message digest}) and MD5 (@pxref{MD5 message digest}) by
default.
@c JP
@var{digester}引数は@code{<message-digest-algorithm>}を継承し、
後で述べるダイジェストプロトコルを実装しているクラスです。
Gaucheにデフォルトでついてくるものとしては、SHA
(@ref{SHA message digest}参照)とMD5(@ref{MD5 message digest}参照)があります。
@c COMMON

@c EN
The supported @var{target} class is @code{<u8vector>} and @code{<string>}.
Digest result is a bytestring in general, so using @code{<u8vector>}
is recommended; if you give @code{<string>}, the result
is likely to be an incomplete string.
@c JP
@var{target}には@code{<u8vector>}か@code{<string>}を指定できます。
ダイジェスト結果は一般にバイト列になるので、@code{<u8vector>}が推奨です。
@code{<string>}を指定した場合は、不完全文字列が返ってくることが多いでしょう。
@c COMMON

@c EN
For the convnience, the following symbols are also allowed as @var{target},
in which case the output byte sequence is encoded to a readable string
For the details of those encodings, @pxref{Base64 encoding/decoding}.
@c JP
簡便のために、@var{target}には以下のシンボルのいずれかを渡すこともできます。
その場合、ダイジェスト結果が指定の形式で可読文字列にエンコードされて返されます。
これらのエンコーディングの詳細については@ref{Base64 encoding/decoding}を参照してください。
@c COMMON

@table @code
@item base64
@c EN
Base64 encoding (original).
@c JP
オリジナルのBase64エンコーディング
@c COMMON
@item base64url
@c EN
URL-safe Base64 encoding.
@c JP
URL安全なBase64エンコーディング
@c COMMON
@item base64url-nopad
@c EN
URL-safe Base64 encoding and omitting trailing padding character (@code{=})
@c JP
URL安全なBase64で、末尾のパディング文字(@code{=})を省略したもの
@c COMMON
@item base32
@c EN
Base32 encoding.
@c JP
Base32エンコーディング
@c COMMON
@item base32hex
@c EN
Base32hex encoding.
@c JP
Base32hexエンコーディング
@c COMMON
@item base16
@c EN
Base16 encoding, a.k.a. hexadecimal encoding (using @code{#[0-9A-F]}.
@c JP
Base16エンコーディング、あるいは16進数形式。@code{#[0-9A-F]}が使われます。
@c COMMON
@item hex
@c EN
Base16 encoding but use lowercase letters (using @code{#[0-9a-f]}.
@c JP
16進数形式、アルファベットに小文字が使われます。
@c COMMON
@end table
@end deffn

@deffn {Generic Function} digest-to target digester
@c EN
Read input from the current input port until EOF, compute
its digest using the algorithm specified by @var{digester},
and returns result in an instance of a class given to @var{target}.
You can also give some symbols to specify encodings as @var{target}.
See @code{digest-message-to} above for the details of
@var{target} and @var{digester}.
@c JP
入力を現在の入力ポートから読んで、@var{digester}で指定されるアルゴリズムで
ダイジェストを計算し、結果を@var{target}クラスのインスタンスで返します。
@var{target}には可読文字列へのエンコーディングを指定するシンボルを与えることもできます。
@var{target}と@var{digester}引数について詳しくは、上の
@code{digest-message-to}の項目を参照してください。
@c COMMON
@c MOD util.digest

@end deffn

@c EN
@subheading Implementer API
@c JP
@subheading 実装者向けAPI
@c COMMON

@c EN
The following API is for the impelmenter of the actual
digest aglrithms.
@c JP
以下のAPIはダイジェストアルゴリズムを実装する人向けです。
@c COMMON

@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

@c EN
@subheading Deprecated API
@c JP
@subheading 非推奨API
@c COMMON


@deffn {Generic function} digest-string class string
@c MOD util.digest
@c DEPRECATED
@c EN
Use @code{digest-message-to} for the new code.

Same as @code{(digest-message-to <string> @var{class} @var{string})},
where only a string is allowed to the @var{string} argument.
@c JP
新たなコードではより柔軟な@code{digest-message-to}を使ってください。

@code{(digest-message-to <string> @var{class} @var{string})}と同じです。
ただし@var{string}引数は文字列でなければなりません。
@c COMMON
@end deffn

@defun digest-hexify digest-result
@c MOD util.digest
@c DEPRECATED
@c EN
Same as @code{(base16-encode-message digest-result :lowercase #t)}
(@pxref{Base64 encoding/decoding}).  In typical case, you can pass
@code{hex} as the target to @code{digest-message-to} to get
the hexified output directly.  This procedure is only kept for
the backward compatibility.
@c JP
@code{(base16-encode-message digest-result :lowercase #t)}と同じです
(@ref{Base64 encoding/decoding}参照)。通常は@code{digest-message-to}の
@var{target}引数に@code{hex}を渡すことで直接16進数表記の結果が得られます。
この手続きは互換性のためだけに残されています。
@c COMMON
@end defun

@c ----------------------------------------------------------------------
@node Calculate dominator tree, R6RS identifier syntax, 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 (alist-ref *graph* n eq? '()))
  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 R6RS identifier syntax, Determine isomorphism, Calculate dominator tree, Library modules - Utilities
@section @code{util.identifier-syntax} - R6RS identifier syntax
@c NODE R6RS識別子マクロ, @code{util.identifier-syntax} - R6RS識別子マクロ

@deftp {Module} util.identifier-syntax
@mdindex util.identifier-syntax
@c EN
Provide R6RS's @code{identifier-syntax} form.
@c JP
R6RSの@code{identifier-syntax}フォームを提供します。
@c COMMON
@end deftp

@defmac identifier-syntax template
@defmacx identifier-syntax (id1 template1) ((@code{set!} id2 pattern) template2)
[R6RS]
@c MOD util.identifier-syntax
@c EN
Creates an idendifier macro transformer in the way R6RS specifies.
For identifier transformers, @pxref{Identifier transformer}.  This macro
is built on top of @code{make-id-transformer}.
We provide this to ease porting R6RS code to Gauche.
@c JP
R6RSで規定されている方法で識別子マクロ変換器を作ります。
識別子マクロについては@ref{Identifier transformer}を参照してください。
このマクロは@code{make-id-transformer}を使って作られています。
R6RSコードをGaucheにポートする際に便利でしょう。
@c COMMON

@c EN
This form must appear as @var{transformer-spec} in macro definitions
(@pxref{Hygienic macros}).  The behavior is undefined if this is
used in other places.
@c JP
このフォームはマクロ定義の@var{transformer-spec}として使うことができます
(@ref{Hygienic macros}参照)。それ以外の部分に現れた場合の動作は未定義です。
@c COMMON

@c EN
The first form creates an identifier macro that expands to @var{template}.
Suppose you define a macro with this:
@c JP
最初の形式は、識別子マクロを@var{template}へと展開します。
例えば次の定義があったとします:
@c COMMON

@example
(define-syntax now (identifier-syntax (sys-time)))
@end example

@c EN
Then, any use of @code{now} is expanded to @code{(sys-time)}; however,
@code{(set! now expr)} will raise an error.
@c JP
すると、@code{now}が現れたらそれは全て@code{(sys-time)}へと展開されます。
ただし@code{(set! now expr)}はエラーになります。
@c COMMON

@c EN
The second form allows @code{set!} as well.  The following is a contrived
example:
@c JP
二番目の形式は@code{set!}に使われた場合の展開も定義します。
次はちょっとわざとらしい例ですが:
@c COMMON

@example
(define-syntax foo
  (identifier-syntax
   [_ (get-foo)]
   [(set! _ expr) (set-foo! expr)]))
@end example

@c EN
Any use of @code{foo} is expanded to @code{(get-foo)}, except
@code{(set! foo something)}, which is expanded to @code{(set-foo! something)}.
@c JP
@code{foo}が出現するとそれは@code{(get-foo)}に置き換えられます。
ただし@code{(set! foo something)}の場合はそれが
@code{(set-foo! something)}となります。
@c COMMON

@c EN
(Unlike using @code{make-id-transformer} and @code{syntax-rules} combination,
the @code{set!} matching clause can come later.)
@c JP
(@code{make-id-transformer}と@code{syntax-rules}の組み合わせとは違って、
@code{set!}とマッチする節を後に置きます。)
@c COMMON

@c EN
The expansion is hygienic.  The identifiers used in @var{template} captures
meaning in the scope where @code{identifier-syntax} appears, and won't
be affected by the scope where the macro is used.
@c JP
展開は衛生的です。@var{template}に現れる識別子は@code{identifier-syntax}が現れた
環境での意味を捕捉し、マクロが使われる環境に影響されません。
@c COMMON
@end defmac

@c ----------------------------------------------------------------------
@node Determine isomorphism, The longest common subsequence, R6RS identifier syntax, 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;
@pxref{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つのテキストストリームの
相違点を計算する@code{test.diff}モジュールです
(@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

@defun lcs-edit-list/context a b :optional eq-fn :key context-size
@defunx lcs-edit-list/unified a b :optional eq-fn :key context-size
@c MOD util.lcs
@c EN
Calculates edit list of two sequences @var{a} and @var{b}, including
context surrounding the changes.
It is similar to what you get with @code{diff -c} and @code{diff -u}
commands, respectively.
The @code{text.diff} module provides context diff on top of
this procedure (@pxref{Calculate difference of text streams}).
@c JP
二つのシーケンス@var{a}と@var{b}から、変更の文脈を含めた編集リストを計算します。
@code{diff -c}および@code{diff -u}コマンドの出力と似たようなものです。
@code{text.diff}モジュールではこの手続きの上に、コンテクストdiff出力を得る
ユーティリティを提供しています
(@ref{Calculate difference of text streams}参照)。
@c COMMON

@c EN
The @var{eq-fn} argument specifies the equality predicate on the elements.
Its default is @code{equal?}.
The @var{context-size} keyword argument specifies the maximum
size of the unchanged elements surrounding each edits.  It must be
an exact positive integer.  Its default is 3.
@c JP
@var{eq-fn}引数はシーケンスの各要素を比較する述語で、デフォルトは@code{equal?}です。
@var{context-size}引数は、文脈を示すために変更点の前後に付加される変更のない
要素の最大数で、正の正確な整数でなければなりません。デフォルトは3です。
@c COMMON

@c EN
Returns a list of @emph{hunk}s.  Each hunk represents a chunk of
difference between @var{a} and @var{b}.  The format of hunk
differs between @code{lcs-edit-list/context} and
@code{lcs-edit-list/unified}.
@c JP
戻り値は@emph{hunk}のリストです。各hunkが@var{a}と@var{b}の相違点を示します。
hunkのフォーマットは@code{lcs-edit-list/context}と@code{lcs-edit-list/unified}で
異なります。
@c COMMON

@c EN
@strong{A hunk of @code{lcs-edit-list/context}} has the following form:
@c JP
@strong{@code{lcs-edit-list/context}のhunk}は次のとおりです。
@c COMMON

@example
<hunk> : #(<a-edits> <b-edits>)

<a-edits> : <edits>
<b-edits> : <edits>

<edits> : (<start-pos> <end-pos> <edit> ...)

<edit> : (= <element>)     ; same in both a and b
       | (- <element>)     ; deleted: only in a
       | (+ <element>)     ; inserted: only in b
       | (! <element>)     ; changed
@end example

@c EN
The @var{<start-pos>} and @var{<end-pos>} are exact integer indexes
of the sequence the hunk is covering; the start position inclusive,
the end position exclusive, and 0-based.
@c JP
@var{<start-pos>}と@var{<end-pos>}は正確な整数のインデックスで、
シーケンス中でhunkがカバーする範囲を示します (@var{<start-pos>}は含まれ、
@var{<end-pos>}は含まれません)。
@c COMMON

@c EN
Each @var{<edit>} shows the element in that range, and whether the
element is to be unchanged, deleted, inserted or changed, to edit
the sequence @var{a} to make @var{b}.
@c JP
各@var{<edit>}はその範囲の要素と、それが両シーケンスで同じなのか、
削除された(@var{a}だけに存在)か、挿入された(@var{b}だけに存在)か、
あるいは置き換えられたかを示します。
@c COMMON

@c EN
Here's an example:
@c JP
これが例です:
@c COMMON

@example
(lcs-edit-list/context '(a b c) '(a B c d))
 @result{}
   (#((0 3 (= a) (! b) (= c))
     ((0 4 (= a) (! B) (= c) (+ d)))))
@end example

@c EN
The result contains one hunk.  It shows that you should change @code{b}
to @code{B}, and insert @code{d}.
@c JP
結果には1つのhunkが含まれ、それは@code{b}を@code{B}に置き換えて@code{d}を追加することを
指示しています。
@c COMMON

@c EN
@strong{A hunk of @code{lcs-edit-list/unified}} has the following form:
@c JP
@strong{@code{lcs-edit-list/unified}のhunk}は次のとおりです:
@c COMMON

@example
<hunk> : #(<a-start> <a-size> <b-start> <b-size> (<edit> ...))

<edit> : (= <element>)     ; unchanged
       | (- <element>)     ; deleted
       | (+ <element>)     ; inserted
@end example

@c EN
Each @var{start} and @var{size} in the hunk specifies
the start position within the sequence (0-based) and
the length of the hunk in the sequence, respectively.
@c JP
各@var{start}と@var{size}はそれぞれのシーケンス中での、
hunkの開始位置(0起点)とその長さを示します。
@c COMMON

@example
(lcs-edit-list/unified '(a b c) '(a B c d))
  @result{}
  (#(0 3 0 4 ((= a) (- b) (+ B) (= c) (+ d))))
@end example

@c EN
@strong{Context size:}
In each hunk, up to @var{context-size} unchanged elements are attached
before and after the inserted/delete/changed elements, to show the
context.  If there's less than @code{(+ 1 (* conext-size 2))} elements
between two changes, they are merged into one hunk.  In the followig
example, the change of @code{b} to @code{B} and @code{e} to @code{E}
are merged into one hunk for they're not far enough, while
the change of @code{i} to @code{I} is in a separate hunk:
@c JP
@strong{コンテキストの大きさ}:
各hunkの前後には、文脈を示すために、
最大で@var{context-size}の、変更のない要素が付加されています。
もし変更のあった二ヶ所の間の要素が@code{(+ 1 (* conext-size 2))}より少なければ、
二つの変更箇所は一つのhunkにまとめられます。
次の例では、@code{b}から@code{B}、@code{e}から@code{E}への変更は
十分に離れていないのでひとつのhunkになり、一方@code{i}から@code{I}への変更は
別のhunkになっています:
@c COMMON

@example
(lcs-edit-list/context '(a b c d e f g h i j)
                       '(a B c d E f g h I j)
                       equal? :context-size 1)
 @result{}
   (#((0 6 (= a) (! b) (= c) (= d) (! e) (= f))
      (0 6 (= a) (! B) (= c) (= d) (! E) (= f)))
    #((7 10 (= h) (! i) (= j))
      (7 10 (= h) (! I) (= j))))

(lcs-edit-list/unified '(a b c d e f g h i j)
                       '(a B c d E f g h I j)
                       equal? :context-size 1)
 @result{}
   (#(0 6 0 6 ((= a) (- b) (+ B) (= c) (= d) (- e) (+ E) (= f)))
    #(7 3 7 3 ((= h) (- i) (+ I) (= j))))
@end example
@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
You can also use a symbol @code{..1}, @code{..2},
@dots{}, in place of @code{...},
which specifies the minimum number of repetition.
@c JP
また、@code{...}のかわりにシンボル @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{})} matches when all @var{pat} matches the
corresponding subtree.  A common idiom to realize ``as'' matching,
with which you can bind the entire tree as well as its substrees,
can be written with @code{and} operator.  For example,
@code{(and (x . y) p)} matches a pair, binding its cdr to @var{x},
its car to @var{y}, and the entire pair to @var{p}.
@c JP
@code{(and pat @dots{})}は、対応する式が全ての@var{pat}にマッチした時に
マッチに成功します。よく使われるイディオムとして、@code{and}で「asマッチング」、
つまり部分式ごとにマッチした全体を別の変数にマッチさせることができます。
例えば@code{(and (x . y) p)}はペアにマッチし、そのcarを@var{x}に、
cdrを@var{y}に、そしてペア全体を@var{p}に束縛します。
@c COMMON

@item
@c EN
@code{(or pat @dots{})} tries to match each @var{pat} against
the corresponding subtree, and if any succeeds, the entire @code{or}
pattern succeeds.  If no @var{pat} matches the subtree, the entire
@code{or} pattern fails.
If there're pattern variables in @var{pat}, the set of variables
in each @var{pat} must be the same: That is,
@code{(or (_ x y) (_ x y _))} is ok but @code{(or (_ x _) (_ x y _))} is not.
It is because the latter may leave some of pattern variables
unbound even match succeeds.
@c JP
@code{(or pat @dots{})}は対応する式に対して@var{pat}を順に試し、
マッチするものがあればそこで成功、ひとつもマッチしなければ失敗とします。
パターン変数を使う場合、各@var{pat}中のパターン変数は同じでなければなりません。
つまり@code{(or (_ x y) (_ x y _))} はokですが、
@code{(or (_ x _) (_ x y _))} は許されません。
マッチする@var{pat}によっては束縛されないパターン変数が出てしまうからです。
@c COMMON

@item
@c EN
@code{(not pat @dots{})} matches when none of @var{pat} matches
the corresponding subtree.
@c JP
@code{(not pat @dots{})} はどの@var{pat}も式にマッチしない場合に
マッチ成功となります。
@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]
  [_ #f])
 @result{} 42

(match '(the answer was 42)
  [`(the answer is ,value) value]
  [_ #f])
 @result{} #f

(match '(a b c d)
  [(the answer is value) value]
  [_ #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))]
    [_ 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, Temporal relation, 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}.
This procedure returns immediately; @var{stream} can be infinite.
@c JP
@var{pred}をパスする要素のみからなる新しいストリームを返します。
この手続きは直ちに返ります。@var{stream}は無限ストリームであっても構いません。
@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}.
It is the same as @code{(stream-filter (complement pred) stream)}.
@c JP
述語@var{pred}を満たさない要素のみからなる新しいストリームを返します。
@code{(stream-filter (complement pred) stream)}と同じです。
@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
@c EN
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.
@c JP
与えられたストリームのうち、最初の@var{count}要素だけを含むストリームを返します。
与えられたストリームが@var{count}要素より少ない要素しか持っていなかった場合、
@code{stream-take}が返すストリームは、元のストリームの終端を越えてアクセスしようとした時に
エラーを投げます。一方、@code{stream-take-safe}が返すストリームは、
元のストリームが@var{count}要素より少なかった場合に、その要素までを返すストリームを
返します。
@c COMMON

@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

@c EN
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.
@c JP
註: SRFI-41 (@code{scheme.stream}) も@code{stream-take}を提供していますが、
引数の順序が逆になっています。また、SRFI-41の@code{stream-take}は
元のストリームが@var{count}以下の要素しか持っていなかった場合でもエラーとしません。
@c COMMON
@end defun

@defun stream-drop stream count
@defunx stream-drop-safe stream count
@c MOD util.stream
@c EN
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.
@c JP
与えられたストリームのうち、最初の@var{count}要素を取り除いたストリームを返します。
与えられたストリームが@var{count}要素より少ない要素しか持っていなかった場合、
@code{stream-drop}は、アクセスされるとエラーを投げるストリームを返します。
一方、@code{stream-drop-safe}は空のストリームを返します。
@c COMMON

@c EN
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.
@c JP
註: SRFI-41 (@code{scheme.stream}) も@code{stream-drop}を提供していますが、
引数の順序が逆になっています。また、SRFI-41の@code{stream-drop}は
元のストリームが@var{count}以下の要素しか持っていなかった場合にエラーとせず
空のストリームを返します。
@c COMMON
@end defun

@defun stream-intersperse stream element
@c MOD util.stream
@c EN
Returns a new stream in which @var{element} is
inserted between each consecutive two elements of @var{stream}.
@c JP
@var{element}が@var{stream}の連続する2要素の間に挿入されているような新たなストリームを
返します。
@c COMMON

@example
(stream->list (stream-intersperse (stream 1 2 3) 0))
 @result{} (1 0 2 0 3)
@end example
@end defun

@defun stream-split stream pred
@c MOD util.stream
@c EN
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.
@c JP
@var{stream}を、@var{pred}を満たす要素で分割し、
分割されたストリームのストリームを返します。
分割に使われた要素は結果に含まれません。
@c COMMON

@example
(stream->list
 (stream-map stream->list
             (stream-split (stream 1 3 2 5 7 9 6 8 1) even?))))
 @result{} ((1 3) (5 7 9) () (1))
@end example
@end defun

@defun stream-last stream
@c MOD util.stream
@c EN
Returns the last element of @var{stream}.
If @var{stream} is empty, an error is thrown.
If @var{stream} is infinite, this procedure won't return.
@c JP
@var{stream}の最後の要素を返します。@var{stream}が空ならエラーが投げられます。
@var{stream}が無限ストリームの場合、この手続きは戻ってきません。
@c COMMON
@end defun

@defun stream-last-n stream count
@c MOD util.stream
@c EN
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.
@c JP
@var{stream}の最後の@var{count}要素を含むストリームを返します。
@var{count}は非負の正確な整数でなければなりません。
もし@var{stream}が@var{count}要素より短ければ、@var{stream}がそのまま返されます。
@var{stream}が無限ストリームならこの手続きは戻ってきません。
@c COMMON
@end defun

@defun stream-butlast stream
@c MOD util.stream
@c EN
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.
immediately.  The argument can be an infinite stream.
@c JP
@var{stream}の最後の要素を除く内容を持つストリームを返します。
@var{stream}が空の場合は空のストリームが返されます。
@var{stream}は無限ストリームであっても構いません。
@c COMMON
@end defun

@defun stream-butlast-n stream count
@c MOD util.stream
@c EN
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.  @var{Stream} can be infinite.
@c JP
@var{stream}の最後の@var{count}要素を除いた内容を持つストリームを作って返します。
@var{count}は非負の正確な整数でなければなりません。
@var{stream}の要素数が@var{count}より少なければ、空のストリームが返されます。
@var{stream}は無限ストリームであっても構いません。
@c COMMON
@end defun

@defun stream-length stream
[R7RS stream]
@c MOD util.stream
@c EN
Returns the number of elements in @var{stream}.
It diverges if @var{stream} is infinite.
@c JP
@var{stream}の要素数を返します。
@var{stream}が無限ストリームの時は戻ってきません。
@c COMMON
@end defun

@defun stream-length>= stream n
@defunx stream-length= stream n
@c MOD util.stream
@c EN
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.
@c JP
@var{stream}の要素数が、それぞれ@var{n}以上か、@var{n}と等しければ@code{#t}を、
そうでなければ@code{#f}を返します。
これらの手続きは@var{stream}の最初の@var{n}要素のみを現実化します。
@c COMMON
@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
@c EN
The predicate @var{pred} is called with each of the first element of
@var{stream} @dots{}, then each of the second element, and so on, until
any of the stream is exhausted.  Then returns the number that
@var{pred} returns a true value.
At least one stream needs to be finite.
@c JP
@var{pred}は、まず@var{stream} @dots{}それぞれの最初の要素を引数として呼び出され、
次にそれぞれの2番目の要素を引数として呼ばれ、以降いずれかの@var{stream}が尽きるまで
呼ばれます。そして、そのうち@var{pred}が真の値を返した数が戻り値となります。
少なくとも@var{stream}のうちのひとつは有限でなければなりません。
@c COMMON

@example
(stream-count < (stream 1 2 3 4 5) (stream 2 2 2 10 10))
 @result{} 3
@end example
@end defun

@defun stream-find pred stream
@c MOD util.stream
@c EN
The predicate @var{pred} is applied to each element of @var{stream} in turn,
and as soon as the @var{pred} returns true, returns the element that
caused @var{pred} to return true.  Remaining elements of @var{stream}
won't be realized.

If no elements in @var{stream} satisfy @var{pred}, @code{#f} is returned.
@c JP
@var{pred}を@var{stream}の要素に順に適用し、@var{pred}が真の値を返したら
直ちにその要因となった要素を返します。@var{stream}の残りは現実化されません。

@var{stream}の要素の中に@var{pred}を満たすものが無かった場合は@code{#f}が返ります。
@c COMMON
@end defun

@defun stream-find-tail pred stream
@c MOD util.stream
@c EN
The predicate @var{pred} is applied to each element of @var{stream} in turn,
and as soon as the @var{pred} returns true, returns a stream
that contains the element and the rest of the input stream.
Remaining elements of @var{stream} won't be realized.

If no elements in @var{stream} satisfy @var{pred}, the empty stream is returned.
@c JP
@var{pred}を@var{stream}の要素に順に適用し、@var{pred}が真の値を返したら
その要素およびそれ以降の要素からなるストリームを返します。
@var{stream}の残りは現実化されません。

@var{stream}の要素の中に@var{pred}を満たすものが無かった場合は空のストリームが返ります。
@c COMMON
@end defun

@defun stream-take-while pred stream
@defunx stream-drop-while pred stream
[R7RS stream]
@c MOD util.stream
@c EN
Returns a stream that contains or excludes initial consecutive elements
of @var{stream} that satisfy @var{pred}, respectively.
@c JP
それぞれ、@var{stream}の最初から連続する、@var{pred}を満たす要素だけからなる
ストリームと、それらの要素を除いたストリームを返します。
@c COMMON

@example
(stream->list (stream-take-while even? (stream 2 4 6 1 4 2)))
 @result{} (2 4 6)
(stream->list (stream-drop-while even? (stream 2 4 6 1 4 2)))
 @result{} (1 4 2)
@end example
@end defun

@defun stream-span pred stream
@defunx stream-break pred stream
@c MOD util.stream
@c EN
Return two streams; the first one consists of the initial consequent
elements of @var{stream} that satisfy or dissatisfy @var{pred},
and the second one is the rest of the stream.
@c JP
ふたつのストリームを返します。最初のストリームは、@var{stream}の最初から連続する、
@var{pred}を満たす/満たさない要素からなるストリームで、
二番目のストリームは残りのストリームです。
@c COMMON

@example
(map stream->list
     (values->list (stream-span even? (stream 2 4 6 1 4 2))))
 @result{} ((2 4 6) (1 4 2))
(map stream->list
     (values->list (stream-break even? (stream 1 9 6 1 4 2))))
 @result{} ((1 9) (6 1 4 2))
@end example
@end defun


@defun stream-any pred stream @dots{}
@defunx stream-every pred stream @dots{}
@c MOD util.stream
@c EN
The predicate @var{pred} is applied to each of the first elements of
@var{stream} @dots{}, then second, and so on.
When @var{pred} returns a true value, @code{stream-any} returns
the value immediately without looking further.
When @var{pred} returns @code{#f}, @code{stream-every} returns @code{#f}
immediately without looking further.

If none of applications of @var{pred} returns a true value
until one of the streams is exhausted, @code{stream-any} returns @code{#f}.
If none of applications of @var{pred} returns @code{#f}
until one of the streams is exhausted, @code{stream-every} returns
the last result of @var{pred}.
@c JP
@var{pred}は、まず@var{stream} @dots{}それぞれの最初の要素を引数として、
次にそれぞれの2番目の要素を引数として、と順次呼ばれます。
@code{stream-any}は@var{pred}が真の値を返したらただちに評価を打ち切り、
@var{pred}が返した値をそのまま返します。
@code{stream-every}は@var{pred}が@code{#f}を返したらただちに
評価を打ち切り、@code{#f}を返します。

streamのいずれかが終端に達するまでに@code{pred}が一度も真の値を返さなければ、
@code{stream-any}は@code{#f}を返します。
streamのいずれかが終端に達するまでに@code{pred}が一度も偽の値を返さなければ、
@code{stream-every}は最後の@var{pred}の結果を返します。
@c COMMON

@example
(stream-any (^[x y] (and (> x y) (list x y)))
            (stream 1 2 3 4 5)
            (stream 3 3 3 3 3))
 @result{} (4 3)

(stream-every (^[x y] (and (> x y) (list x y)))
              (stream 6 6 6 6 6)
              (stream 1 2 3 4 5))
 @result{} (6 5)
@end example
@end defun

@defun stream-index pred stream @dots{}
@c MOD util.stream
@c EN
The predicate @var{pred} is applied to each of the first elements of
@var{stream} @dots{}, then second, and so on.  If it returns a true
value, @code{stream-index} returns immediately with the index.
If @var{pred} never returns a true value until one of
the streams is exhausted, @code{stream-index} returns #f.
@c JP
@var{pred}は、まず@var{stream} @dots{}それぞれの最初の要素を引数として、
次にそれぞれの2番目の要素を引数として、と順次呼ばれます。
@var{pred}が真の値を返したら@code{stream-index}は評価を打ち切り、
そのインデックスを返します。
streamのいずれかが終端に達するまでに@code{pred}が一度も真の値を返さなければ、
@code{#f}が返されます。
@c COMMON

@example
(stream-index odd? (stream 2 4 6 7 8))
 @result{} 3
@end example
@end defun

@defun stream-member obj stream :optional elt=
@defunx stream-memq obj stream
@defunx stream-memv obj stream
@c MOD util.stream
@c EN
Stream version of @code{member}, @code{memq}, and @code{memv}
(@pxref{Other list procedures}).   Search an element equivalent to
@var{obj} from @var{stream}, and if it is found, returns a stream
consists of the element and the rest of the stream.
If no such element is found, @code{#f} is returned.

They differ regarding which equivalent procedure to be used;
@code{stream-member} uses the given @var{elt=} procedure, or @code{equal?}
if omitted, @code{stream-memq} uses @code{eq?}, and @code{stream-memv}
uses @code{eqv?}.
@c JP
@code{member}, @code{memq}, @code{memv}のストリーム版です
(@ref{Other list procedures}参照)。
@var{obj}と等しい要素を@var{stream}から探し、見つかったその要素を含む
残りのストリームを返します。要素がみつからなければ@code{#f}を返します。

これらの手続きの違いは等価判定述語です。@code{stream-member}は与えられた@var{elt=}か、
省略された場合は@code{equal?}を使います。
@code{stream-memq}は@code{eq?}を、@code{stream-memv}は@code{eqv?}を使います。
@c COMMON
@end defun

@defun stream-delete obj stream :optional elt=
@c MOD util.stream
@c EN
Equivalent to @code{(stream-remove (cut elt= obj <>) stream)}, that is,
returns a stream that is the same as input except @var{obj}s.
If @var{elt=} is omitted, @code{equal?} is used.
@c JP
@code{(stream-remove (cut elt= obj <>) stream)}と等価です。
すなわち、入力ストリームから@var{obj}と等しい要素を除いた要素を持つ
ストリームを返します。
@c COMMON
@end defun

@defun stream-delete-duplicates stream :optional elt=
@c MOD util.stream
@c EN
Returns a stream that is the same as input except the consecutive
equivalent elements are removed but the first one.
Elements are compared with @var{elt=}, defaulted to @code{equal?}.
@c JP
入力ストリームのうち、連続する等しい要素があればその最初以外のものを除いた
ストリームを返します。
要素は@var{elt=}で比較されます。省略時は@code{equal?}が使われます。
@c COMMON
@end defun

@defun stream-grep re stream
@c MOD util.stream
@c EN
The @var{re} argument must be a regexp object, or a string representation
of regexp (which is converted to regexp by @code{string->regexp}).

Returns a stream that contains input elements that matches @var{re}.
@c JP
@var{re}引数は正規表現オブジェクトか、その文字列表現でなければなりません
(文字列の場合は@code{string->regexp}で正規表現に変換されます)。

入力ストリームの要素のうち、@var{re}にマッチするものだけを含むようなストリームを
返します。
@c COMMON
@end defun

@defun write-stream stream :optional oport writer
@c MOD util.stream
@c EN
Writes each element of @var{stream} to @var{oport}, using @var{writer}.
When @var{oport} is omitted, the current output port is used.
When @var{writer} is omitted, @code{write-char} is used.

No 'spacer' is written between elements.
As the default suggests, this is most useful to write out a stream
of characters.
@c JP
@var{stream}の各要素を@var{writer}を使って@var{oport}に書き出します。
@var{oport}が省略された場合は現在の出力ポートが、
@var{writer}が省略された場合は@code{write-char}が使われます。

要素の間には何も出力されません。既定値が示すように、
この手続きは文字の遅延ストリームを表示するのに便利です。
@c COMMON
@end defun

@c ----------------------------------------------------------------------
@node Temporal relation, Topological sort (legacy), Stream library, Library modules - Utilities
@section @code{util.temporal-relation} - Temporal relation
@c NODE 時間的関係, @code{util.temporal-relation} - 時間的関係

@deftp {Module} util.temporal-relation
@mdindex util.temporal-relation
@c EN
Procedures to find relation between two temporal intervals,
or a temporal interval and a point in time.
@c JP
二つの時間間隔、もしくは時間間隔と時刻の関係を調べる手続きを提供します。
@c COMMON

@c EN
A temporal interval is represented by two points in time,
@var{lesser} bound and @var{greater} bound.   This module does not define
a concrete structure for temporal intervals.  Instead, the user
provides a @emph{interval protocol}, which specifies how to
access start/end time and how to compare them.
@c JP
時間間隔は、開始時刻(@emph{lesser bound})と終了時刻(@emph{greater bound})
で表されるオブジェクトです。
このモジュールは、時間間隔についての具体的なデータ構造は定めません。
代わりに、ユーザは自分の好みのデータ構造が時間間隔として
扱えるような@emph{時間間隔プロトコル}を提供します。
@emph{時間間隔プロトコル}は、時間間隔の開始時刻と終了時刻へのアクセサおよび
時間の比較方法をまとめたものです。
@c COMMON

@c EN
Given two temporal intervals x and y, there are 13 possible relations
(the terms are taken from Haskell Rampart library
@url{https://hackage.haskell.org/package/rampart-2.0.0.0/docs/Rampart.html}):
@c JP
二つの時間間隔xとyがある時、その関係は13種類に分類できます
(用語はHaskellのRampartライブラリから取りました
@url{https://hackage.haskell.org/package/rampart-2.0.0.0/docs/Rampart.html}):
@c COMMON

@example
|<-- x -->|
             |<-- y -->|             x before y

|<-- x -->|
          |<-- y -->|                x meets y

|<--- x ---->|
         |<-- y -->|                 x overlaps y

|<------ x ------->|
         |<-- y -->|                 x finished-by y

|<------- x -------->|
    |<---- y ---->|                  x contains y

   |<-- x -->|
   |<------ y ---->|                 x starts y

  |<---- x ---->|
  |<---- y ---->|                    x equal y

  |<----- x ----->|
  |<-- y -->|                        x started-by y

  |<---- x ---->|
|<--------y -------->|               x during y

         |<-- x -->|
|<------ y ------->|                 x finishes y

         |<-- x -->|
|<----- y ---->|                     x overlapped-by y

          |<-- x -->|
|<-- y -->|                          x met-by y

             |<-- x -->|
|<-- y -->|                          x after y
@end example
@end deftp

@defun make-interval-protocol lesser greater :optional compare-points
@c MOD util.temporal-relation
@c EN
Creates and returns an interval protocol.  The @var{lesser} and
@var{greater} arguments are procedures taking an user-defined interval
object, and returns its lesser bound and greater bound, respectively.
The @var{compare-points} argument is a procedure that takes two points of
time, and must return either a negative real value (if the first point is before
the second), zero (if two points are the same), or a positive real value
(if the first point is after the second).
@c JP
時間間隔プロトコルを作って返します。
@var{lesser}と@var{greater}は、ユーザが使いたい時間間隔オブジェクトを引数にとって
それぞれ開始時刻と終了時刻を返す手続きです。
@var{compare-points}は二つの時刻a, bを取り、aの方がbより時間的に前なら
負の実数を、aとbが同時刻なら0を、aの方がbより時間的に後なら正の実数を返す
手続きです。
@c COMMON

@c EN
The actual representation of time points are up to the caller.
@c JP
時刻をどう表現するかはユーザに任されます。
@c COMMON

@c EN
If the @var{compare-points} argument is omitted,
the built-in @code{compare} procedure
is used (@pxref{Comparison}).  It is suffice for most scalar values;
e.g. you may use real numbers, @code{<time>}, or @code{<date>} objects.
@c JP
@var{compare-points}が省略された場合は、
組み込みの@code{compare}が使われます(@ref{Comparison}参照)。
ほとんどのスカラー値はそれで充分です。
例えば実数や、@code{<time>}オブジェクト、@code{<date>}オブジェクトなどはそのまま
時刻を表す値として使えます。
@c COMMON
@end defun

@defvar pair-interval-protocol
@c MOD util.temporal-relation
@c EN
Bound to @code{(make-interval-protocol car cdr)}; that is, an interval
represented by cons of lesser bound and greater bound.
@c JP
@code{(make-interval-protocol car cdr)}の値に束縛されています。
すなわち、開始時刻と終了時刻のペアで時間間隔を表すプロトコルです。
@c COMMON
@end defvar

@defun relation? obj
@c MOD util.temporal-relation
@c EN
Returns @code{#t} iff @var{obj} is a symbol representing
a temporal relation.  Valid symbols are one of
@code{before}, @code{meets}, @code{overlaps}, @code{finished-by},
@code{contains}, @code{starts}, @code{equal}, @code{started-by},
@code{during}, @code{finishes}, @code{overlapped-by}, @code{met-by}
and @code{after}.
@c JP
@var{obj}が時間的関係を表すシンボルであれば@code{#t}を、そうでなければ
@code{#f}を返します。有効なシンボルは以下のいずれかです:
@code{before}, @code{meets}, @code{overlaps}, @code{finished-by},
@code{contains}, @code{starts}, @code{equal}, @code{started-by},
@code{during}, @code{finishes}, @code{overlapped-by}, @code{met-by},
@code{after}。
@c COMMON
@end defun

@defun inverse rel
@c MOD util.temporal-relation
@c EN
The argument must be a symbol representing a temporal relation
(see @code{relation?} above for the valid symbols).
This procedure returns its inverse relation; that is,
@code{(relate _ x y)} @equiv{} @code{(inverse (relate _ y x))},
where @code{_} is an interval protocol.
@c JP
引数@var{rel}は時間的関係を表すシンボルでなければなりません
(有効なシンボルについては上の@code{relation?}の項を参照)。
この手続きは、@var{rel}の逆になる関係を表すシンボルを返します。
すなわち、@code{_}を時間間隔プロトコルとした時に、
@code{(relate _ x y)} @equiv{} @code{(inverse (relate _ y x))}が常に成り立ちます。
@c COMMON

@c EN
An error is thrown if @var{rel} is not a valid relation.
@c JP
@var{rel}が有効な時間的関係でなければエラーが投げられます。
@c COMMON
@end defun

@defun relate proto x y
@c MOD util.temporal-relation
@c EN
The @var{proto} argument is an interval protocol, and both @var{x} and @var{y}
must be temporal intervals that is compatible to the protocol @var{proto}.
@c JP
@var{proto}は時間間隔プロトコル、@var{x}と@var{y}はそのプロトコルが有効な
時間間隔でなければなりません。
@c COMMON

@c EN
The procedure returns a temporal relation, represented as one of
the following symbols:
@code{before}, @code{meets}, @code{overlaps}, @code{finished-by},
@code{contains}, @code{starts}, @code{equal}, @code{started-by},
@code{during}, @code{finishes}, @code{overlapped-by}, @code{met-by}
and @code{after}.
@c JP
この手続きは二つの時間間隔の時間的関係を返します。返り値は次のシンボルのいずれかです:
@code{before}, @code{meets}, @code{overlaps}, @code{finished-by},
@code{contains}, @code{starts}, @code{equal}, @code{started-by},
@code{during}, @code{finishes}, @code{overlapped-by}, @code{met-by},
@code{after}。
@c COMMON
@end defun

@defun relate-point proto x point
@c MOD util.temporal-relation
@c EN
The @var{proto} argument is an interval protocol, and @var{x} must
be a temporal interval that implements the protocol.  The @var{point}
is a point of time, comparable by the compare-points procedure
of the protocol.
@c JP
@var{proto}は時間間隔プロトコル、@var{x}はそのプロトコルが有効な時間間隔、
@var{point}は@var{proto}の時刻比較手続きに渡せる時刻でなければなりません。
@c COMMON

@c EN
The possible relations are a subset of interval-interval relations:
@c JP
返される時間関係は、時間間隔と時間間隔の間の関係のサブセットになります。
@c COMMON

@example
|<-- x -->|
               p                 x before p

|<--- x --->|
            p                    x finished-by p

  |<--- x --->|
          p                      x contains p

     |<--- x --->|
     p                           x started-by p

       |<-- x -->|
   p                             x after p
@end example
@end defun


@c ----------------------------------------------------------------------
@node Topological sort (legacy), Unification, Temporal relation, 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

@c EN
SRFI-234 now defines a superset of the functionalities this module provides.
New code should use it instead of this module (@pxref{Topological sorting}).
@c JP
今では、SRFI-234がこのモジュールの上位互換の機能を提供しています
(@ref{Topological sorting}参照)。
新しいコードはSRFI-234を使ってください。
@c COMMON
@end deftp

@defun topological-sort graph :optional eqproc
@c MOD util.toposort
@c EN
Returns a topologically sorted list of nodes,
when the node dependencies are specified by @var{graph}.
@xref{Topological sorting}, for the details.

This procedure differs from SRFI-234's @code{topological-sort}
in the following ways:

@itemize @bullet
@item
When @var{graph} contains cycles, this one raises an error,
while SRFI-234's returns @code{#f}.
@item
The default of node comparison predicate @var{eqproc} is @code{eqv?},
while in SRFI-234 it is @code{equal?}
@item
This one does not take the third argument.
@end itemize
@c JP
@var{graph}によって指定される依存関係の元で、
トポロジカルソートされたノードのリストを返します。
@var{graph}の形式について詳しくは@ref{Topological sorting}を参照してください。

この手続きは、SRFI-234の@code{topological-sort}に比べて次の点で異なります。

@itemize @bullet
@item
@var{graph}が循環を含んでいた場合、SRFI-234は@code{#f}を返しますが、
この手続きはエラーを投げます。
@item
ノード比較手続き@var{eqproc}のデフォルトは、SRFI-234では@code{equal?}ですが、
この手続きでは@code{eqv?}です。
@item
この手続きは3番目の引数を取りません。
@end itemize
@c COMMON
@end defun

@c ----------------------------------------------------------------------
@node Unification, CGI utility, Topological sort (legacy), 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{https://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{https://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 you need just to decompose URL query string, you can use
@code{uri-decompose-query} in @code{rfc.uri} (@pxref{URI parsing and construction}).
This procedure has more features useful for CGI scripting.)
@c JP
(単にURLクエリ文字列を分解したいだけなら、@code{rfc.uri}モジュールの
@code{uri-decompose-query}を使うと良いでしょう
(@ref{URI parsing and construction}参照)。
この手続きはCGIスクリプトに便利な機能をたくさん追加しています。)
@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 useful procedures to test CGI scripts.
The test 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 EN
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:
