EB ライブラリの関数の呼び出しは、常に成功するとは限りません。
たとえば、EB_Book オブジェクトを書籍に結びつける関数
eb_bind() には、引数として書籍のトップディレクトリを渡しますが、
存在しないディレクトリを指定した場合、処理は失敗に終わります。
一般にこうした事象は、ユーザが誤ったパスを指定したときに起こりますが、 メモリ不足のように、ユーザのミスが原因ではない失敗も起こりえます。
本章では、関数の呼び出しが失敗した場合の処理について説明します。
EB ライブラリの関数の多くは、戻り値として EB_Error_Code
型の値を返します。
処理が成功したときに返す値は EB_SUCCESS ですが、失敗したときは
エラーの原因に応じて様々な値を返します。
このため、EB ライブラリでは次のような EB_SUCCESS との比較処理
がよく行われます。
EB_Error_Code error_code;
error_code = eb_bind(&book, "/mnt/cdrom");
if (error_code != EB_SUCCESS) {
printf("eb_bind() failed\n");
return;
}
エラーコードの値は、関数 eb_error_message() によって
エラーメッセージに変換することもできます。
こうすることで、エラーの原因をアプリケーションプログラムのユーザに
もう少し分かりやすく伝えることができます。
error_code = eb_bind(&book, "/mnt/cdrom");
if (error_code != EB_SUCCESS) {
printf("eb_bind() failed, %s\n",
eb_error_message(error_code));
return;
}
error_code が EB_ERR_TOO_LONG_FILENAME に
セットされていれば、次のようなエラーメッセージが出力されます。
too long filename
あるいは、次のように日本語のメッセージかも知れません。
ファイル名が長すぎます
メッセージの国際化機能 (NLS) を無効にして EB ライブラリをコンパイル した場合は、常に英語のメッセージが返ります。 有効にした場合は、ロケールの設定によってどちらの言語のメッセージが 返るかが決まります。
本書ではプログラムを簡潔にするために、エラー処理は最低限しか行って いません。 けれども一般のアプリケーションプログラムでは、関数の呼び出しが成功 したかどうかを常にチェックし、処理が失敗した際はエラーメッセージを出力 して、ユーザにエラーの原因を伝えるのが望ましいといえます。
EB_Book オブジェクトは、状態に関するパラメタをいくつか持って
います。
オブジェクトが CD-ROM 書籍に結び付いているかどうかも、こうしたパラメタ
のうちの一つです。
引数に EB_Book オブジェクトへのポインタを取る関数には、
あらかじめオブジェクトの特定のパラメタがセットされていることを前提と
しているものもあります。
たとえば、eb_path() は、オブジェクトが書籍に結び付いていること
を前提としています。
では、もしも書籍に結び付いていないオブジェクトを eb_path() に
渡したらどうなるでしょうか。
EB_Book book; EB_Error_Code error_code; char path[EB_MAX_PATH_LENGTH + 1]; eb_initialize_library(); eb_initialize(&book); error_code = eb_path(&book, path); /* どうなる? */
この場合、eb_path() は EB_ERR_UNBOUND_BOOK を
返します。
EB ライブラリの関数は、必要なパラメタがセットされていないオブジェクトを
検知して拒絶します。
しかしながら、参照マニュアルで明示されている場合を除いて、EB ライブラリ
の関数は、与えられたポインタが NULL かどうかまでは調べません。
次のようなことをすると、プログラムを異常終了させてしまいます。
eb_bind(NULL, "/mnt/cdrom"); /* 異常終了! */ eb_bind(&book, NULL); /* これも異常終了! */
この節で説明しているデータ型を使うには、次のようにヘッダファイルを 読み込んで下さい。
#include <eb/error.h>
EB_Error_Code 型
データ型 EB_Error_Code は、EB ライブラリのエラーコードを
表します。
この型は符合付き整数型の別名として定義されていますので、2 つのコードを
2 項演算子 == と != で一致比較することができます。
EB ライブラリでは、全部で EB_NUMBER_OF_ERRORS 個の
フックコードを定義しています。
エラーコードの一覧については、
次の節 (「エラーコードの一覧」 を参照のこと)
を参照して下さい。
この節で説明しているエラーコードを使うには、次のようにヘッダファイルを 読み込んで下さい。
#include <eb/error.h>
EB_SUCCESS成功。 エラーは起きていない。
EB_ERR_MEMORY_EXHAUSTED
EB ライブラリが malloc() を呼び出したが、NULL
が返ってきた。
EB_ERR_TOO_LONG_FILE_NAME与えられた書籍のパス名が長すぎる。
EB_ERR_BAD_FILE_NAME書籍のパス名が不正である。
EB_ERR_BAD_DIR_NAMEディレクトリ名が不正である。 (EB ライブラリの内部処理用なので、 このエラーコードがアプリケーションプログラムに返ることはありません。)
EB_ERR_TOO_LONG_WORD与えられた検索語は長すぎる。
EB_ERR_BAD_WORD与えられた検索語に不正な文字が含まれている。
EB_ERR_EMPTY_WORD与えられた検索語は空である。
EB_ERR_FAIL_GETCWD
getcwd() もしくは getwd() が失敗した。
EB_ERR_FAIL_OPEN_CATEB ライブラリが、書籍のカタログファイルを開くことに失敗した。
EB_ERR_FAIL_OPEN_CATAPPEB ライブラリが、appendix のカタログファイルを開くことに失敗した。
EB_ERR_FAIL_OPEN_TEXTEB ライブラリが、書籍の本文ファイルを開くことに失敗した。
EB_ERR_FAIL_OPEN_FONTEB ライブラリが、書籍の外字ファイルを開くことに失敗した。
EB_ERR_FAIL_OPEN_APPEB ライブラリが、appendix ファイルを開くことに失敗した。
EB_ERR_FAIL_OPEN_BINARYEB ライブラリが、バイナリデータファイルを開くことに失敗した。
EB_ERR_FAIL_READ_CATEB ライブラリが、書籍のカタログファイルを読み込むことに失敗した。
EB_ERR_FAIL_READ_CATAPPEB ライブラリが、appendix のカタログファイルを読み込むことに失敗した。
EB_ERR_FAIL_READ_TEXTEB ライブラリが、書籍の本文ファイルを読むことに失敗した。
EB_ERR_FAIL_READ_FONTEB ライブラリが、書籍の外字ファイルを読み込むことに失敗した。
EB_ERR_FAIL_READ_APPEB ライブラリが、appendix のメインファイルを読み込むことに失敗した。
EB_ERR_FAIL_READ_BINARYEB ライブラリが、書籍のバイナリデータファイルを読み込むことに失敗した。
EB_ERR_FAIL_SEEK_CATEB ライブラリが、書籍のカタログファイルのシークに失敗した。
EB_ERR_FAIL_SEEK_CATAPPEB ライブラリが、appendix のカタログファイルのシークに失敗した。
EB_ERR_FAIL_SEEK_TEXTEB ライブラリが、書籍の本文ファイルのシークに失敗した。
EB_ERR_FAIL_SEEK_FONTEB ライブラリが、書籍の外字ファイルのシークに失敗した。
EB_ERR_FAIL_SEEK_APPEB ライブラリが、appendix のメインファイルのシークに失敗した。
EB_ERR_FAIL_SEEK_BINARYEB ライブラリが、書籍のバイナリデータファイルのシークに失敗した。
EB_ERR_UNEXP_CATEB ライブラリが、書籍のカタログファイル内で、期待とは異なるデータ列を 見つけた。
EB_ERR_UNEXP_CATAPPEB ライブラリが、appendix のカタログファイル内で、想定外のデータ列を 見つけた。
EB_ERR_UNEXP_TEXTEB ライブラリが、書籍の本文ファイル内で、想定外のデータ列を見つけた。
EB_ERR_UNEXP_FONTEB ライブラリが、書籍の外字ファイル内で、想定外のデータ列を見つけた。
EB_ERR_UNEXP_APPEB ライブラリが、appendix のメインファイル内で、想定外のデータ列を 見つけた。
EB_ERR_UNEXP_BINARYEB ライブラリが、書籍のバイナリデータファイル内で、想定外のデータ列を 見つけた。
EB_ERR_UNBOUND_BOOK
呼び出された EB ライブラリの関数は、書籍に結び付けられた
EB_Book オブジェクトを引数にとるが、与えられたオブジェクトは
書籍に結び付けられていなかった。
EB_ERR_UNBOUND_APP
呼び出された EB ライブラリの関数は、appendix に結び付けられた
EB_Appendix オブジェクトを引数にとるが、与えられた
オブジェクトは appendix に結び付けられて
いなかった。
EB_ERR_NO_SUB書籍は副本を一つも持っていない。
EB_ERR_NO_APPSUBappendix は副本を一つも持っていない。
EB_ERR_NO_FONT選択中の副本は、外字を一種類も持っていない。
EB_ERR_NO_TEXT選択中の副本は、本文データを持っていない。
EB_ERR_NO_CUR_SUB
呼び出された関数は、副本が選択されている EB_Book
オブジェクトを引数としてとるが、与えられたオブジェクトでは選択されて
いなかった。
EB_ERR_NO_CUR_APPSUB
呼び出された関数は、副本が選択されている EB_Appendix
オブジェクトを引数にとるが、与えられたオブジェクトでは選択されて
いなかった。
EB_ERR_NO_CUR_FONT
呼び出された関数は、外字が選択されている EB_Book
オブジェクトを引数にとるが、与えられたオブジェクトでは選択されて
いなかった。
EB_ERR_NO_CUR_BINARY
呼び出された関数は、バイナリデータの読み込み要求をセットしている
EB_Book オブジェクトを引数にとるが、与えられたオブジェクトでは
セットされていなかった。
EB_ERR_NO_SUCH_SUB
EB_Book オブジェクトと副本コードが関数に与えられたが、
EB_Book オブジェクトに結び付けられている書籍は、その
副本コードに一致する副本を持っていない。
EB_ERR_NO_SUCH_APPSUB
EB_Appendix オブジェクトと副本コードが関数に与えられたが、
EB_Appendix オブジェクトに結び付けられている appendix は、
その副本コードに一致する副本を持っていない。
EB_ERR_NO_SUCH_FONT
EB_Book オブジェクトと外字の縦のサイズが関数に与えられたが、
EB_Book オブジェクトに結びつけられていた書籍で選択中の副本は、
そのサイズの外字を持っていない。
EB_ERR_NO_SUCH_CHAR_BMP
EB_Book オブジェクトと文字番号が関数に与えられたが、
EB_Book オブジェクトに結び付けられていた書籍で選択中の副本は、
その番号の外字のビットマップデータを持っていない。
EB_ERR_NO_SUCH_CHAR_TEXT
EB_Appendix オブジェクトと文字番号が関数に与えられたが、
EB_Appendix オブジェクトに結び付けられている appendix で
選択中の副本は、その番号の外字の代替文字列を持っていない。
EB_ERR_NO_SUCH_SEARCH選択中の副本は、指定された検索メソッドを持っていないので、検索は行えない。
EB_ERR_NO_SUCH_HOOK不正なフックコードが関数に渡された。
EB_ERR_NO_SUCH_BINARY指定された位置に、指定された形式のバイナリデータは存在しない。
EB_ERR_DIFF_CONTENTアプリケーションプログラムからテキストデータの取得を要求されたが、指定 されたテキストデータの種類が、前回リクエストされたときと一致していない。
EB_ERR_NO_PREV_SEARCH
eb_hit_list() が呼び出されたが、アプリケーションプログラム
から前もって検索のリクエストがなされていない。
EB_ERR_NO_SUCH_MULTI_ID
EB_Book オブジェクトと複合検索コードが関数に渡されたが、
結び付けられた書籍で選択中の副本は、そのコードに一致する複合検索を持って
いない。
EB_ERR_NO_SUCH_ENTRY_ID
EB_Book オブジェクトと複合検索エントリコードが関数に
渡されたが、結び付けられた書籍で選択中の副本は、そのエントリコードに
一致する複合検索エントリを持っていない。
EB_ERR_TOO_MANY_WORDSアプリケーションプログラムから条件検索もしくは複合検索の検索をリクエスト されたが、検索語の個数が多すぎる。
EB_ERR_NO_WORDアプリケーションプログラムから条件検索もしくは複合検索の検索をリクエスト されたが、検索語がすべて空である。
EB_ERR_NO_CANDIDATES
eb_multi_entry_candidates() が呼び出されたが、
指定された複合検索エントリは、検索語の候補一覧データを持っていない。
EB_ERR_END_OF_CONTENT
eb_forward_text() あるいは eb_backward_text()
で本文の頭出しを行おうとしたが、すでに本文の末尾ないし先頭に達していて、
それ以上先に進むことができなかった。
EB_ERR_NO_PREV_SEEK
あらかじめ eb_seek_text() でシークを行っていない状態で、
テキストデータの読み込みや頭出しを行おうとした。
EB_ERR_EBNET_UNSUPPORTEDこの EB ライブラリは、遠隔ホストへのアクセスには対応していない。
EB_ERR_EBNET_FAIL_CONNECT遠隔ホストへのアクセスを試みたが、サーバ (EBNETD) に接続できなかった。
EB_ERR_EBNET_SERVER_BUSY遠隔ホストへの接続を行ったが、書籍にアクセスしているクライアントの数が すでに上限に達しているため、その書籍を利用できなかった。
EB_ERR_EBNET_NO_PERMISSION遠隔ホストへの接続を行ったが、その書籍への利用権限がないため、サーバ からアクセスを拒否された。
EB_ERR_UNBOUND_BOOKLIST
呼び出された EB ライブラリの関数は、遠隔ホストに結び付けられた
EB_BookList オブジェクトを引数にとるが、与えられたオブジェクト
は遠隔ホストに結び付けられていなかった。
EB_ERR_NO_SUCH_BOOK
EB_BookList オブジェクトと書籍の要素番号を関数に渡されたが、
EB_BookList に結び付けられた遠隔ホスト上には、その要素番号に
該当する書籍は存在しない。
この節で説明している関数を使うには、次のようにヘッダファイルを読み込んで 下さい。
#include <eb/error.h>
const char *eb_error_string (EB_Error_Code error_code)
関数 eb_error_string() は、エラーコード error_code
を文字列に変換したものを返します。
文字列の文字コードは、ASCII になります。
たとえば、エラーコード値 EB_SUCCESS を渡すと文字列
"EB_SUCCESS" を返します。
未知のエラーコードを渡したときは、"EB_ERR_UNKNOWN" を返します。
const char *eb_error_message (EB_Error_Code error_code)
関数 eb_error_message() は、エラーコード error_code
に対応したメッセージを文字列にして返します。
関数の返すメッセージは、英語か日本語になります。
国際化機能を有効にして EB ライブラリをコンパイルしていない場合は、常に 英語のメッセージを返します。 このときのメッセージの文字コードは、ASCII になります。
メッセージの国際化機能 (NLS) を有効にして EB ライブラリをコンパイル した場合は、ロケールの設定に応じてどちらの言語のメッセージを返すのか が決まります。 また、GNU gettext バージョン 0.36 以降では iconv() と連携することにより、 メッセージの文字コードもロケールに応じて変化します。 gettext が iconv() との連携を行わなければ、英語のメッセージは ASCII、 日本語のメッセージは日本語 EUC になります。 この関数の呼び出しによって、gettext のテキストドメインの設定は変化 しません。
未知のエラーコードを渡したときに返すメッセージは、英語では "unknown error"、日本語では "未知のエラーです" になります。