S-JIS[2007-02-22] 変更履歴

geniconvtbl 〔-f〕 ソースファイル名

iconvで文字コード変換できるパターン(コードセット・コンバーター)を生成するUNIXコマンド。(generate iconv table)


概要

オプション 説明
-f バイナリテーブルが既に存在していたら、(エラーにせずに)上書きする。

iconvでの文字コード変換は、具体的には「/usr/lib/iconv/geniconvtbl/binarytables」に置いてある“拡張子btのファイル”が使われる。
このbt(バイナリーテーブル)ファイルを生成するのがgeniconvtblコマンド。(Solaris)


バイナリテーブルファイルの生成手順

  1. ソースファイルを作成する。
    from_code%to_code.src」というファイルを作る。 内容の書き方は後述
    from_code,to_codeは、例えばeuc_jpとかSJISとか。自分で好きな名称を付ける。
     
  2. バイナリテーブルを生成する。
    > geniconvtbl from_code%to_code.src
    これを実行すると、ソースファイルと同じディレクトリに拡張子btのファイルが作られる。
    ただし既に存在していた場合はエラーになるので、-fオプションを付けて上書きするようにする。
     
  3. バイナリテーブルを所定の場所に格納する。
    iconvは、「/usr/lib/iconv/geniconvtbl/binarytables」に置いてあるバイナリテーブルファイルを使用する。
    したがってそのディレクトリにbtファイルをコピーするか、シンボリックリンクを張る。(このディレクトリは、rootユーザーでないと書き込めない)
    > su -
    # cd /usr/lib/iconv/geniconvtbl/binarytables
    # ln -s /〜/original_iconv/from_code%to_code.bt .
    # exit
    シンボリックリンクを一度作っておけば、元の位置のファイルを何度更新しても大丈夫。(rootユーザー以外でも)
     
  4. 文字コード変換を実行する。
    > iconv -f from_code -t to_code 変換元ファイル > 変換先ファイル


逆変換がしたければ、新しいバイナリテーブルを別途作る必要がある。


ソースファイルの文法

ソースのサンプル(?)は、「/usr/lib/iconv/geniconvtbl/srcs」に入っている。拡張子srcのファイル。
この内容はC言語風の独自言語。おおまかに、次のような構造をしている。

構造 説明
マクロ定義 #define#include。省略可能
from_code%to_code { 変換元コード名称変換先コード名称
  サブルーチン定義 サブルーチン定義。省略可能
direction { 変換定義
  条件 変換内容 コードをどのように変換するかを記述。
条件:conditiontrue
変換内容:operationmap
(複数記述可)
};  
}  

「//」で行コメント。

from_code%to_code.srcの例:

//
// geniconvtbl sample src
//

#include <sys/errno.h>
#define	A_END	0x52

from_code%to_code {	//コード名称
	operation sub {	//サブルーチン定義
		output = input[0] + s;
		discard;
	};

	direction {
		condition {
			between 0x30...0x39;	//入力バイト列の処理位置の1バイトが0x30〜0x39のとき
		} operation {
			output = input[0] | 0xf0;	//入力バイトにf0の論理和をとって出力

			// Move input buffer pointer one byte.
			discard;			//入力の処理位置を後ろにずらす
		}

		condition {
			between 0x41...A_END;
		} operation {
			if (input[0] <= 0x49) {
				s = 0x80;
			} else {
				s = 0x87;
			}
			operation sub;	//サブルーチン呼び出しの例
		};

		condition {
			between 0x20...0x29;
		} map {
			default	0x6f	//下記以外は0x6fを出力
			0x20	0x40	//入力バイトが0x20だったら0x40を出力
			0x22	0x7f
			0x23	0x7b
			0x25	0x6c
			0x26	0x50
			0x27	0x7d
			0x28	0x4d
			0x29	0x5d
		};

		true operation {			//上記以外の入力だった場合
			//output = input[0];
			//discard;
			error EILSEQ;	//エラーを発生させる
		};
	};
}

マクロ定義

マクロ定義には#defineを使用する。→

#define	VAR	0x00

定義したマクロ名は、between条件変数への代入エラーコードなどに使用できる。

#includeを使うと、C言語のヘッダーファイルがそのまま読み込まれるっぽい。→
そのヘッダーファイルの中に書かれている#defineが使えるようになるっぽい。

#include <sys/errno.h>

「sys/errno.h」の中にはEILSEQ・E2BIG・EINVALといったマクロ(エラーコード)が定義されている。
こういったコードを使わないのであれば、#include自体不要。


コード名称

変換元のコード名称と変換後のコード名称を「%」で区切って記述する。→
その後ろに「{ }」でくくったブロックを作り、その中に変換内容を記述していく。


サブルーチン定義

サブルーチンを定義することが出来る。→
サブルーチンを使わないなら、定義不要。

	operation サブルーチン名 {
		内容;
	};

サブルーチン名が「init」だと、初期処理として最初に呼ばれるらしい。
グローバル変数の初期化に使える。

	operation init {
		cs = 0;
	};

サブルーチンの呼び出しも、同じくoperationを使用する。


direction

「{ };」でくくったブロックを作り、その中に条件変換方法を記述していく。→


条件

入力文字列(バイト列)に対し、条件を指定する。
その条件にマッチすれば、直後の処理を行う。

	condition { 条件式 } 処理;

条件式で最もよく使われるのがbetween。入力バイト列の現在の位置の文字(バイト)に対してコードの範囲を指定する。→

	condition { between 0x00...0x7f; } 処理;
		between 0x41...0x5a, 0x61...0x7a;
		between	0x41...0x5a,
			0x61...0x7a;

2バイト以上をbetween条件にすることも出来る。

		between 0x0041...0x005a;

入力の処理位置にあるバイト列が「00 41」であればマッチするが、「41」のみだとマッチしない。
C言語等の他の言語から見れば0x41と0x0041は同じだが、geniconvtblではマッチするバイト数が異なるので要注意!


条件式には変数の比較も使える。

	condition { cs == 0; } 処理;


また、無条件に実行したい場合は(conditionの代わりに)trueを使う。→
directionの一番最後で使えば、「その他全て」を実現できる。

	true 処理;

処理

変換処理を具体的に記述する。operationmapの2通りの書き方が存在する。

operationは、プログラム的な文を記述する。→
変数への代入や、if文(変数値の比較)や演算が出来る。
変数はグローバル変数で、特に定義しなくても使える。代入せずに使用すると 初期値として0が入っているっぽい。

	operation {
		if (cs == 0) {
			cs = 1;
		}
		output = input[0] & 0x7f;
	};

特殊な変数としてinputoutputがある。
input[0]は、現在処理中の1バイト目を指す。input[1]が2バイト目、input[2]が3バイト目。→
(1バイトのbetweenは、input[0]と比較していると言えよう)
outputに値を代入すると、出力になる。→

	output = 0x00;	←00を1バイト出力
	output = 0x0000;	←00を2バイト出力


discardで、入力バイト列の処理位置を1バイト後ろへずらす。→
「discard 2;」で、2バイトずらす。

	// Move input buffer pointer two bytes.
	discard 2;

errorで、エラーを発生させる。→

	error E2BIG;

E2BIGは、#include <sys/errno.h>で読み込まれたマクロ。
どういうときにどういう値を返すべきかは、iconv(3C)のマニュアルに載っている。
エラーを発生させると、iconvがエラー終了する。ただしiconvのエラー時のリターンコードは1のみなので、error文で何を返しても あまり意味が無い。

operation サブルーチン名;」で、サブルーチンを呼び出す。→
サブルーチンの中にもプログラムを書ける。


mapは、値を別の値へ単純に置き換える。→

	map {
		入力値	変換値
		…
	};
	map {
		0x30	0xf0		…0x30を0xf0に変換する
		0x31	0xf1
		0x32	0xf2
	};
	map {
		0x30...0x39	0x00	…範囲指定。0x30〜0x39を全て0x00に変換する
	};
	map {
		default		0x00	…「その他」はdefaultで表す
		0x30...0x39	0xff
	};
	map {
		0x12	0x0012		…1バイトの0x12を0x0012(2バイト)に変換する
	};
	map {
		0x0012	0x12		…2バイトの0x0012を0x12(1バイト)に変換する
	};

UNIXコマンドへ戻る
メールの送信先:ひしだま