UNVIS(3)

名称
unvis, strunvis - キャラクタの画像表現のデコード

ライブラリ
libc

書式
<vis.h> int unvis(char *cp, int c, int *astate, int flag) int strunvis(char *dst, const char *src)

解説
unvis() および strunvis() 関数は、例えば vis(3) 関数によって作り 出されたようなキャラクタの画像表現をデコードして元の形に戻します。 unvisは c にある連続するキャラクタとともに有効なシーケンスが認識されるまで呼び 出され、それが認識されるとデコードされたキャラクタが cp によって指されるキャラクタのところに置かれます。 strunvisは、 src により指されるキャラクタを dst により指されるバッファへデコードします。

strunvis() 関数は、エスケープシーケンスをデコードしながら単に src を dst へコピーし、 dst に置かれたキャラクタの数を返すか、または無効な エスケープシーケンスが検出された場合には -1 を返します。 dst のサイズは、 src のサイズに等しくなければなりません (すなわち、デコード中には拡張は 起こりません)。

unvis() 関数は、任意のバイトストリームをデコードできるステートマシンを インプリメントしています。デコードされるそのバイトに付随するすべての ステートは、 unvis() 関数の外に保存されますから (すなわち、ステートへの ポインタは渡されますから)、異なるストリームをデコードする呼び出しを自由に 混在することができます。バイトストリームのデコードを開始するには、まず 整数をゼロに初期化します。この整数へのポインタおよびデコード先キャラクタ へのポインタとともに連続するバイトのそれぞれに unvis() を呼び出します。 unvis() 関数は、適切に取扱わねばならないいくつかのリターンコードを 持っています。それらは次の通りです:

0 (ゼロ)
    キャラクタがもう一つ必要であり、まだ何も認識されていません。

UNVIS_VALID
    有効なキャラクタが認識され、cp によって指される場所に置かれています。

UNVIS_VALIDPUSH
    有効なキャラクタが認識され、cp によって指される場所に 置かれています。しかし、現在渡されているそのキャラクタをもう一度渡す 必要があります。

UNVIS_NOCHAR
    有効なシーケンスが検出されたが、キャラクタは 作成されていません。このリターンコードは、キャラクタの間の論理的区切りを 示すために必要です。

UNVIS_SYNBAD
    無効なエスケープシーケンスが検出されたか、または デコーダが不明のステートにあります。デコーダはスタート時のステートに 置かれます。

ストリームのすべてのバイトが処理されたとき、 flag を UNVIS_END に設定してもう一度 unvis() を呼び出して残っているキャラクタを 抽出します (渡されたキャラクタは無視されます)。

次のような部分的コードは、 unvis() の適切な使用法を示しています。

    int state = 0;
    char out;
    while ((ch = getchar()) != EOF) {
    again:
    	switch(unvis(&out, ch, &state, 0)) {
    	case 0:
    	case UNVIS_NOCHAR:
    		break;
    	case UNVIS_VALID:
    		(void) putchar(out);
    		break;
    	case UNVIS_VALIDPUSH:
    		(void) putchar(out);
    		goto again;
    	case UNVIS_SYNBAD:
    		(void)fprintf(stderr, "bad sequence!\n");
    	exit(1);
    	}
    }
    if (unvis(&out, (char)0, &state, UNVIS_END) == UNVIS_VALID)
    	(void) putchar(out);

関連項目
vis(1)

歴史
unvis() 関数は、 4.4BSD ではじめて登場しました。