この節では、Solaris 8 環境に含まれているいくつかの国際化機能について説明します。
コードセットの独立性のサポート
ロケールデータベース
プロセスコードの書式 (ワイド文字表現)
libw と libintl
ctype マクロ
genmsg ユーティリティ
また、この節には次のような国際化アプリケーションの開発に役立つ情報も書かれています。
動的リンクアプリケーション
Solaris 8 国際化 API
Solaris 8 の操作環境は、日本の PC-Kanji、台湾の Big-5、中華人民共和国の GBK のような非 EUC エンコーディングをサポートしています。
コンピュータ市場の大半では EUC 以外のコードセットサポートが要求されるため、Solaris 8 では EUC と非 EUC コードセットのサポートを可能にするフレームワークを提供します。このサポートを CSI と呼びます。
CSI の目標は、Solaris OS ライブラリやコマンドから、特定のコードセットやエンコーディング方法についての EUC 依存性を除去することです。CSI アーキテクチャにより、Solaris 環境において UNIX ファイルシステムで安全なエンコーディングをサポートできます。CSI は UTF-8、PC-Kanji、Big-5 など、多くの非 EUC コードセットをサポートします。
CSI により、アプリケーションおよびプラットフォームソフトウェア開発者は、UTF-8 などのエンコーディングからコードを独立させたり、ソースコードを変更せずに新しいエンコーディングを採用することができます。このアーキテクチャのアプローチは、Java の国際化とも異なります。Java ではアプリケーションは Unicode 依存でなければならず、アプリケーションでのコード変換を必要とします。
既存の多くの国際化アプリケーション (たとえば Motif など) は、基礎となるシステムから自動的に CSI のサポートを継承します。これらのアプリケーションは、変更しなくても新しいロケールで動作します。しかし、XView または OLIT ベースの OPEN LOOK アプリケーションは、XView が EUC コードセットに依存するため非 EUC のロケールでは動作しません。
CSI は本来どのコードセットにも依存しませんが、Solaris 8 ではファイルコードのエンコーディング (コードセット) について次のような前提条件があります。
Unicode (16 ビット固定幅) はファイルコードとしてサポートできません。
表 2-1 に、Solaris 8 で CSI 使用可能なコマンドを示します。これらのコマンドのマニュアルページには、CSI 機能について記述されています。
これらのコマンドは、特に説明がない場合、すべて /usr/bin ディレクトリにあります。
表 2-1 Solaris 8 の CSI 使用可能なコマンド
/usr/lib/diffh | acctcom | gencat | script |
/usr/sbin/accept | apropos | getopt | sdiff |
/usr/sbin/reject | batch | getoptcvt | settime |
/usr/ucb/lpr | bdiff | head | sh |
/usr/xpg4/bin/awk | cancel | join | split |
/usr/xpg4/bin/cp | cat | jsh | strconf |
/usr/xpg4/bin/date | catman | kill | strings |
/usr/xpg4/bin/du | chgrp | ksh | sum |
/usr/xpg4/bin/ed | chmod | lp | tabs |
/usr/xpg4/bin/edit | chown | man | tar |
/usr/xpg4/bin/egrep | cmp | mkdir | tee |
/usr/xpg4/bin/env | col | msgfmt | touch |
/usr/xpg4/bin/ex | comm | news | tty |
/usr/xpg4/bin/expr | compress | nroff | uncompress |
/usr/xpg4/bin/fgrep | cpio | pack | unexpand |
/usr/xpg4/bin/grep | csh | paste | uniq |
/usr/xpg4/bin/ln | csplit | pcat | unpack |
/usr/xpg4/bin/ls | cut | pg | wc |
/usr/xpg4/bin/more | diff | printf | whatis |
/usr/xpg4/bin/mv | diff3 | priocntl | write |
/usr/xpg4/bin/nice | disable | ps | xargs |
/usr/xpg4/bin/nohup | echo | pwd | zcat |
/usr/xpg4/bin/od | expand | rcp | |
/usr/xpg4/bin/pr | file | red | |
/usr/xpg4/bin/rm | fine | remsh | |
/usr/xpg4/bin/sed | fold | rksh | |
/usr/xpg4/bin/sort | ftp | rmdir | |
/usr/xpg4/bin/tail |
|
rsh | |
/usr/xpg4/bin/tr | |||
/usr/xpg4/bin/vedit | |||
/usr/xpg4/bin/vi | |||
/usr/xpg4/bin/view |
Solaris 8 の libc (/usr/lib/libc.so) のほとんどすべての関数は CSI 使用可能です。しかし、libc の以下の関数は EUC 依存の関数であるため、CSI 使用可能ではありません。
csetcol() csetlen() euccol()
euclen() eucscol() getwidth()
また、以下のマクロは EUC に依存するので CSI 使用可能ではありません。
csetno() wcsetno()
Solaris 8 製品の libgen (/usr/ccs/lib/libgen.a) は国際化されていますが、CSI 使用可能ではありません。
Solaris 8 製品の libcurses (/usr/ccs/lib/libcurses.a) は国際化されていますが、CSI 使用可能ではありません。
次のような 5 つのユーティリティがあります。
ユーティリティ (32 ビットアプリケーション) :
/usr/bin/geniconvtbl
特別 iconv 共用オブジェクト :
/usr/lib/iconv/geniconvtbl.so
/usr/lib/iconv/sparcv9/geniconvtbl.so
サンプルの geniconvtbl(1) 入力ソースファイルと、システムが用意したバイナリテーブルファイル :
/usr/lib/iconv/geniconvtbl/srcs/
ISO8859-1_to_ISO646.txt
ISO646_to_ISO8859-1.txt
ISO8859-1_to_UTF-8.txt
UTF-8_to_ISO8859-1.txt
ShiftJIS_to_eucJP.txt
eucJP_to_ShiftJIS.txt
/usr/lib/iconv/geniconvtbl/binarytables/
ISO8859-1%ISO646.bt
ISO646%ISO8859-1.bt
libc.so.1s にある変更された iconv_open(3) :
/usr/lib/libc.so.1
/usr/lib/sparcv9/libc.so.1 (sparcv9 の例)
マニュアルページ :
/usr/share/man/sman1/geniconvtbl.1
/usr/share/man/sman4/geniconvtbl.4
geniconvtbl(1) に関する節では、その使用方法と、iconv の関数とユーティリティで使用できるように生成されたバイナリテーブルファイルを配置する方法が説明されています。
geniconvtbl(4) のマニュアルページを参照してください。
Solaris 8 のロケールデータベースの形式および構造は非公開であり、将来のリリースで変更される可能性があります。したがって、国際化アプリケーションを作成するときには、このロケールデータベースに直接アクセスしないようにしてください。代わりに Solaris 国際化 API を使用します。
Solaris 8 を使用する場合は、Solaris 8 製品に含まれているロケールデータベースを使用してください。以前のバージョンの Solaris のロケールデータベースを使用しないでください。
Solaris 8 製品のワイド文字の形式は非公開であり、将来のリリースで変更される可能性があります。したがって、国際化アプリケーションを作成するときには、このワイド文字の形式が将来も同じであると仮定しないでください。代わりに、Solaris 国際化 API を使用してください。
複数バイト文字はシングルバイトとして保存できない文字の総称で、中国語、日本語、韓国語などの文字を含みます。複数バイト文字を保存するには 2 バイトまたは 3 バイトを必要とします。より詳細な定義については、ISO/IECC 9899:1990 サブクラス 3.13 の項目を参照してください。プログラミングモデルでは、これらの複数バイト文字を論理ユニットとして読み込み、ワイド文字として保存できます。プログラム内において、ワイド文字は論理エンティティとして独立して取り扱うことができます。また、適切な変換処理を行ったのち、これらワイド文字を論理ユニットとして出力できます。このことは、シングルバイト文字を読み込んで加工したのち出力する場合と似ています。MSE には、これと同等の処理を複数バイトに対して行うためのインタフェースが提供されています。このため MSE では、シングルバイト文字の場合と同じプログラミングモデルを用いて複数バイト文字を取り扱うためのプログラムを作成できます。
Solaris 8 では、アプリケーションを libc などのシステムライブラリにリンクする方法として、動的リンクと静的リンクを選択できます。しかし、システムライブラリの国際化機能を必要とするアプリケーションは動的にリンクしなければなりません。このようなアプリケーションが静的にリンクされている場合、setlocale 関数を使用してロケールを C または POSIX 以外に設定する操作は失敗します。静的にリンクされたアプリケーションは、C および POSIX ロケールでのみ動作します。
デフォルトでは、リンカープログラムはアプリケーションを動的にリンクしようとします。リンカーやコンパイラのコマンド行のオプションとして、-Bstatic や -dn を指定すると、アプリケーションは静的にリンクされる場合があります。既存のアプリケーションが動的にリンクされているかどうかを調べるには、/usr/bin/ldd コマンドを使用します。
たとえば、次のように入力します。
% /usr/bin/ldd /sbin/sh |
このコマンドは以下のメッセージを表示します。
% ldd: /sbin/sh: file is not a dynamic executable or shared object |
このメッセージは、/sbin/sh コマンドが動的にリンクされたプログラムではないことを示します。また、次のように入力します。
% /usr/bin/ldd /usr/bin/ls |
このコマンドは以下のメッセージを表示します。
% libc.so.1 => /usr/lib/libc.so.1 % libdl.so.1 => /usr/lib/libdl.so.1 |
このメッセージは、/usr/bin/ls コマンドは 2 つのライブラリ libc.so と libdl.so.l に動的にリンクされていることを示します。
つまり、ldd コマンドからアプリケーションに対するメッセージに libc.so.l が含まれていない場合は、アプリケーションが libc に静的にリンクされていることを示します。この場合、リンカーのコマンド行オプションを動的リンクが使用されるように変更し、アプリケーションを再リンクします。
これらのインタフェースは libc に移動したので、libw と libintl にはありません。
共有オブジェクトは、既存のアプリケーションの実行の互換性を保証し、アーカイブとともにアプリケーション作成時のコンパイル環境の互換性を提供します。ただし、libw や libintl に対してアプリケーションを作成する必要はなくなりました。
フィルタの詳細については、『リンカーとライブラリ』を参照してください。
表 2-2 に libw および libintl のスタブエントリポイントを示します。
表 2-2 libw および libintl のスタブエントリポイントlibw: |
fgetwc |
fgetws |
fputwc |
fputws |
getwc |
getwchar |
getws |
isenglish |
isideogram |
isnumber |
|
isphonogram |
isspecial |
iswalnum |
iswalpha |
iswcntrl |
|
iswctype |
iswdigit |
iswgraph |
iswlower |
iswprint |
|
iswpunct |
iswspace |
iswupper |
iswxdigit |
putwc |
|
putwchar |
putws |
strtows |
towlower |
towupper |
|
ungetwc |
watoll |
wcscat |
wcschr |
wcscmp |
|
wcscoll |
wcscpy |
wcscspn |
wcsftime |
wcslen |
|
wcsncat |
wcsncmp |
wcsncpy |
wcspbrk |
wcsrchr |
|
wcsspn |
wcstod |
wcstok |
wcstol |
wcstoul |
|
wcswcs |
wcswidth |
wcsxfrm |
wctype |
wcwidth |
|
wscasecmp |
wscat |
wschr |
wscmp |
wscol |
|
wscoll |
wscpy |
wscspn |
wsdup |
wslen |
|
wsncasecmp |
wsncat |
wsncmp |
wsncpy |
wspbrk |
|
wsprintf |
wsrchr |
wsscanf |
wsspn |
wstod |
|
wstok |
wstol |
wstoll |
wstostr |
wsxfrm |
|
libintl: |
bindtextdomain |
dcgettext |
dgettext |
gettext |
textdomain |
文字の分類や文字の変換マクロは、/usr/include/ctype.h で定義されています。Solaris 8 環境は新しい ctype マクロを提供しています。新しいマクロは、XPG4 で定義された文字の分類および変換セマンティクスをサポートしています。この新しいマクロにアクセスするには、次のいずれかの条件が満たされていなければなりません。
_XPG4_CHAR_CLASS が定義されている
_XOPEN_SOURCE および _XOPEN_VERSION=4 が定義されている
_XOPEN_SOURCE および _XOPEN_SOURCE_EXTENDED=1 が定義されている
つまり、XPG4 および XPG4.2 アプリケーションは自動的に新しいマクロが含まれます。_XOPEN_SOURCE、_XOPEN_VERSION、_XOPEN_SOURCE_ECTENDED は、新しい ctype マクロの他に XPG4 関連機能をもたらすので、XPG4 または XPG4.2 以外のアプリケーションは __XPG4_CHAR_CLASS__ を使用しなければなりません。
これに相当する ctype 関数もあります。Solaris 8 関数は XPG4 セマンティクスもサポートします。
詳細については、ctype(3C) のマニュアルページを参照してください。
Solaris 8 は 2 つの種類の API を提供します。
複数バイト (ファイルコード)
ワイド文字
アプリケーションはワイド文字コードで処理を行います。
プログラムはファイルから入力を受け取ると、mbtwoc および mbtowcs API を使用して、ファイルの複数バイトデータをワイド文字に変換します。ファイル出力データをワイド文字形式から複数バイト形式に変換するには、wcstombs および wetomb API を使用します。
表 2-3 に Solaris 8 に含まれる国際化 API を示します。
表 2-3 libc の国際化
API タイプ |
ライブラリルーチン |
説明 |
---|---|---|
メッセージ処理関数 | ||
catclose() |
メッセージカタログを閉じる |
|
|
catgets() |
プログラムメッセージを読み取る |
|
catopen() |
メッセージカタログを開く |
|
dgettext() |
指定したドメインのメッセージカタログからメッセージを取得する |
|
dcgettext() |
指定したドメインとカテゴリのメッセージカタログからメッセージを取得する |
|
textdomain() |
現在のドメインを設定および照会する |
|
bindtextdomain() |
メッセージドメインパスをバインドする |
コード変換 |
|
|
|
iconv() |
コードを変換する |
|
iconv_close() |
変換記述子の割り当てを解除する |
|
iconv_open() |
変換記述子を割り当てる |
正規表現 |
|
|
|
regcomp() |
正規表現をコンパイルする |
|
regexec() |
正規表現の照合を実行する |
|
regerror() |
エラーコードとエラーメッセージのマッピングを行う |
|
regfree() |
regcomp() により割り当てられたメモリーを解放する |
ワイド文字クラス |
|
|
|
wctype() |
文字クラスを定義する |
|
wctrans |
文字のマッピングを定義する |
|
towctrans |
ワイド文字のマッピング |
|
setlocale() |
プログラムのロケールを変更および照会を行う |
|
nl_langinfo() |
現在のロケールの言語および文化情報を取得する |
|
localeconv() |
現在のロケールの通貨および数値形式の情報を取得する |
文字分類 | ||
|
isalpha() |
文字はアルファベットか |
|
isupper() |
文字は大文字か |
|
islower() |
文字は小文字か |
|
isdigit() |
文字は数か |
|
isxdigit() |
文字は 16 進数か |
|
isalnum() |
文字は英数字か |
|
isspace() |
文字は空白か |
|
ispunct() |
文字は句読点か |
|
isprint() |
文字は印刷可能か |
|
iscntrl() |
文字は制御文字か |
|
isascii() |
文字は ASCII 文字か |
|
isgraph() |
文字は表示可能な文字か |
|
isphonogram() |
ワイド文字は表音文字か |
|
isideogram() |
ワイド文字は表意文字か |
|
isenglish() |
ワイド文字は補助コードセットの英語のアルファベットか |
|
isnumber() |
ワイド文字は補助コードセットの数か |
|
isspecial() |
ワイド文字は補助コードセットの文字か |
|
iswalpha() |
ワイド文字はアルファベットか |
|
iswupper() |
ワイド文字は大文字か |
|
iswlower() |
ワイド文字は小文字か |
|
iswdigit() |
ワイド文字は数か |
|
iswxdigit() |
ワイド文字は 16 進数か |
|
iswalnum() |
ワイド文字は英数字か |
|
iswspace() |
ワイド文字は空白か |
|
iswpunct() |
ワイド文字は句読点か |
|
iswprint() |
ワイド文字は印刷可能な文字か |
|
iswgraph() |
ワイド文字は表示可能な文字か |
|
iswcntrl() |
ワイド文字は制御文字か |
|
iswascii() |
ワイド文字は ASCII 文字か |
toupper() |
小文字を大文字に変換する |
|
|
tolower() |
大文字を小文字に変換する |
|
towupper() |
ワイド文字の小文字を大文字に変換する |
|
towlower() |
ワイド文字の大文字を小文字に変換する |
文字照合 | ||
|
strcoll() |
文字列を照合する |
|
strxfrm() |
文字列を照合用に変換する |
|
wcscoll() |
ワイド文字の文字列を照合する |
|
wcsxfrm() |
ワイド文字の文字列を照合用に変換する |
通貨の処理 | ||
|
strfmon() |
通貨の値を文字列表現に変換する |
日付と時間の処理 | ||
|
getdate() |
ユーザー形式の日付と時間を変換する |
|
strftime() |
日付と時間を文字列表現に変換する。%u の変換機能は、X/Open CAE 仕様、System Interfaces and Headers, Issue 4, Version 2 に準拠しています。この機能は、10 進法の 1 から 7 で週日を表しており、現在では 1 が月曜日を表します。 |
|
strptime() |
日付と時間の変換 |
複数バイトの処理 | ||
|
btowc |
シングルバイトからワイド文字に変換する |
|
mbrlen() |
1 つの文字に含まれるバイト数を取得する (再起動可能) |
|
mbsinit() |
変換オブジェクトの状態を決定する |
|
mbtowc() |
1 つの文字を 1 つのワイド文字に変換する (再起動可能) |
|
mbstowcs() |
文字列をワイド文字の文字列に変換する (再起動可能) |
ワイド文字 | ||
|
wcsncat() |
ワイド文字の文字列を長さ n に連結する |
|
wsdup() |
ワイド文字の文字列を重複させる |
|
wcscmp() |
ワイド文字の文字列を比較する |
|
wcsncmp() |
ワイド文字の文字列を長さ n 分比較する |
|
wcscpy() |
ワイド文字の文字列をコピーする |
|
wcsncpy() |
ワイド文字の文字列を長さ n 分コピーする |
|
wcschr() |
ワイド文字の文字列内の文字を検索する |
|
wcsrchr() |
ワイド文字の文字列を右から検索する |
|
wcslen() |
ワイド文字の文字列の長さを取得する |
|
wscol() |
ワイド文字の文字列の表示幅を返す |
|
wcsspn() |
ワイド文字の文字列が別のワイド文字の文字列に現れる長さを返す |
|
wcscspn() |
ワイド文字の文字列が別のワイド文字の文字列に現れない長さを返す |
|
wcspbrk() |
別のワイド文字の文字列に含まれている、ワイド文字の文字列の先頭のポインタを返す |
|
wcstok() |
ワイド文字の文字列の中でトークンを移動する |
|
wcswcs() |
ワイド文字の文字列内の文字列を検索する |
|
wcstombs() |
ワイド文字の文字列を複数バイトの文字列に変換する |
|
wctomb() |
ワイド文字を複数バイト文字に変換する |
|
wcwidth() |
ワイド文字のカラム数を調べる |
|
wcswidth() |
ワイド文字の文字列のカラム数を調べる |
|
wctob |
ワイド文字からシングルバイト文字に変換する |
|
wcrtomb |
ワイド文字から文字に変換する (再起動可能) |
|
wcsrtombs |
形式に従ってワイド文字列を解釈する |
ワイド文字の書式化 | ||
|
wsprintf() |
書式に従ってワイド文字の文字列を生成する |
|
wsscanf() |
書式付き入力規約 |
|
fwprintf |
ワイド文字書式付き出力を印刷する |
|
fwscanf |
ワイド文字書式付き入力を変換する |
|
wprintf |
ワイド文字書式付き出力を印刷する |
|
wscanf |
ワイド文字列書式付き入力を変換する |
|
swprintf |
ワイド文字書式付き出力を印刷する |
|
swscanf |
ワイド文字書式付き入力を印刷する |
|
vfwprintf |
stdarg 引数リストをワイド文字書式で出力する |
|
vswprintf |
stdarg 引数リストをワイド文字書式で出力する |
ワイド文字と数 | ||
|
wcstol() |
ワイド文字の文字列をロング整数に変換する |
|
wcstoul() |
ワイド文字の文字列を符号なしロング整数に変換する |
|
wcstod() |
ワイド文字の文字列を倍精度に変換する |
ワイド文字の文字列 | ||
|
wscasecmp() |
大文字と小文字を区別せずにワイド文字の文字列を比較する |
wsncasecmp() |
コード文字列動作を処理する |
|
|
wcsstr |
ワイド文字の部分文字列を検索する |
|
wmemchr |
ワイド文字をメモリ内で検索する |
|
wmemcmp |
メモリ内のワイド文字を比較する |
|
wmemcpy |
メモリ内のワイド文字をコピーする |
|
wmemmove |
領域がオーバーラップする状態でメモリ内のワイド文字をコピーする |
|
wmemset |
メモリ内のワイド文字を設定する |
ワイド文字の標準入出力 | ||
|
fgetwc() |
ストリームから複数バイト文字を取り出し、ワイド文字に変換する |
|
getwchar() |
標準入力から複数バイト文字を取り出し、ワイド文字に変換する |
|
fgetws() |
ストリームから複数バイトの文字列を取り出し、ワイド文字に変換する |
|
getws() |
標準入力から複数バイトの文字列を取り出し、ワイド文字に変換する |
|
fputwc() |
ワイド文字を複数バイト文字に変換し、ストリームに送る |
|
fwide |
ストリームの方向を設定する |
|
putwchar() |
ワイド文字を複数バイト文字に変換し、標準入力に送る |
|
fputws() |
ワイド文字を複数バイトの文字列に変換し、ストリームに送る |
|
putws() |
ワイド文字を複数バイトの文字列に変換し、標準出力に送る |
|
ungetwc() |
新しい genmsg ユーティリティは、国際化されたソースメッセージカタログを作成するために、catgets() ファミリの関数で使用されます。このユーティリティは、ソースプログラムファイルの catgets での関数の呼び出しを調べ、見つかった情報からソースメッセージカタログを作成します。以下に例を示します。
% cat example.c ... /* NOTE: %s is a file name */ printf(catgets(catd, 5, 1, "%s cannot be opened.")); /* NOTE: "Read" is a past participle, not a present tense verb */ printf(catgets(catd, 5, 1, "Read")); ... % genmsg -c NOTE example.c The following file(s) have been created. new msg file = "example.c.msg" % cat example.c.msg $quote " $set 5 1 "%s cannot be opened" /* NOTE: %s is a file name */ 2 "Read" /* NOTE: "Read" is a past participle, not a present tense verb */ |
上記の例では、ソースファイル example.c について genmsg が実行され、example.c.msg という名前のソースメッセージカタログが作成されています。-c オプションの引数 NOTE により、genmsg はカタログにコメントを含めます。ソースプログラムのコメントに指定された文字列が含まれている場合、コメントはメッセージカタログの catgets() の呼び出しから抽出された次の文字列の後に表示されます。
genmsg を使用して、メッセージセット内のメッセージの番号を自動的に付けることができます。
詳細については、genmsg(1) のマニュアルページを参照してください。
この節の内容は、『Creating Worldwide Software: Solaris International Developer's Guide』(第 2 版、Bill Tuthill、David A. Smallberg 共著、Sun Microsystems Press、Prentice Hall 発行、 1997 Sun Microsystems, Inc.) の内容を許可を得て使用しています。