Termcap
Termcap (terminal capability;タームキャップ) はUnix系オペレーティングシステム (OS) で使われるライブラリでありデータベースである。 これを使うと端末をデバイス独立に扱うことができ、移植性の高いテキストモードのアプリケーションを書く労力を大いに軽減できる。 最初のtermcapは1978年にビル・ジョイによってBSD用に書かれ[1][2]、 その後ほぼすべてのUnix系OSに移植された。それ以前のIncompatible Timesharing Systemにおける端末データベースの設計の影響を受けていると言われる[3]。
termcapデータベースには数百種類ものディスプレイ端末の端末ケーパビリティが記述されている。 これによってプログラムは端末の種類に依存せずにキャラクタベースのインターフェイスを実現できる。 viやEmacsなどのスクリーンエディタはtermcapを使っているであろうプログラムの例である。
データベースには以下のような情報が記述されている:
- ディスプレイのカラム幅がいくつであるか
- カーソルを任意の位置に移動させるために送信する文字列(行と列の番号をどうエンコーディングするかも含め)
- 画面を上にスクロールする方法
- スクロール操作に必要なパディングの量
データモデル
[編集]termcapデータベースは1個以上の端末の記述からなる。
インデックス
[編集]各記述は端末のカノニカル名を含んでいなければならない。1個以上のエイリアスを含んでいてもよい。 termcapライブラリはカノニカル名・エイリアスをキーにしてデータベースを検索する。
値
[編集]記述は1個以上のケーパビリティを含む。ケーパビリティは慣習的な名前を持ち、真偽型、数値型、文字列型のいずれかになる。 各ケーパビリティに既定の型はなく、次のように構文によって判断される:
- 文字列型ケーパビリティは名前と値の間に「=」を含む
- 数値型ケーパビリティは名前と値の間に「#」を含む
- 真偽型ケーパビリティは値を持たない(指定されたものがtrueになる)
termcapを使うアプリケーションはよく使われるケーパビリティが特定の型であることを前提にしており、ケーパビリティが前提通りの型でないと失敗するライブラリ関数を使って値を取得する。
階層構造
[編集]termcapの記述は他の記述をインクルードでき、そのときインクルードしたケーパビリティの一部を無効にしたり上書きしたり追加することができる。 ストレージモデルが何であれ、termcapライブラリは要求があったときに記述をインクルードして構築する。
ストレージモデル
[編集]termcapのデータはテキストで保存されるため、編集が容易である。そのテキストはファイルまたは環境変数に保存できる。
環境変数
[編集]環境変数 TERM には端末の種類名をセットする。
環境変数 TERMCAP にはtermcapデータベースをセットできる。 使われ方としては、端末エミュレータがその特性をシェルに伝えるために1個の記述を入れるという手法がよくある。
環境変数 TERMPATH は比較的新しい実装で使われ、termcapファイルを検索するパスをセットする。
フラットなファイル構造
[編集]オリジナルの(そしてほとんどの)実装では、フラットなテキストファイルからデータを抽出する。 500 KBといった大きなファイルから記述を検索するのは遅いので、reorderのようなユーティリティが使われる。これはよく使われるエントリをファイルの最初の方に配置するものである。
ハッシュデータベース
[編集]BSD-4.4ベースの実装では記述をハッシュデータベースに保存する(例:Berkeley DB version 1.85など)。 この場合、カノニカルなエントリと、カノニカルなエントリを指すエイリアスという2種類のレコードが保存される。 エントリのテキストはそのまま保存される[4]。
制限と拡張
[編集]オリジナルの実装は使用メモリが少なくなるように設計された:
- 16ビットに収まるように最初の名前は2文字
- ケーパビリティ名は2文字
- 記述は1023文字まで
- インクルードできる記述は1個まで。最後に置かなければならない
比較的新しい実装ではエントリの最初に2文字の名前を書かなくてもよくなっている。
ケーパビリティ名は未だに全ての実装で2文字である。
端末の記述を読み込む tgetent 関数は、呼び出す側が十分なサイズのバッファを用意せねばならず、そのサイズは1024バイトとされていた。 新しい実装ではバッファの代わりにNULLポインタを渡すことでこの制限が緩和されている[5]。 またterminfoがtermcapをエミュレートしている場合もあり、その場合は固定長バッファは使わない。
terminfoによりエミュレーションの場合は、他のエントリを複数インクルードすることができ、位置の制限もない。 はっきりと文書化されてはいないが、いくつかの新しいtermcap実装でもこの機能が取り入れられている [6]。
廃止された機能
[編集]"hz"ケーパビリティはHazeltine 1500のために特別に定義されていた。不幸なことにこの端末はASCII文字のチルド(「~」)を制御シーケンスに使っていた。