SyncTERMはネイティブMacOS端末エミュレータとは異なる文字エンコーディングを使用し、互換性がないことがわかりました。たとえば、フォーマット文字列にブロック文字を印刷するとします。 IBM拡張ASCII文字エンコーディングを使用するSyncTERMは、8進エスケープシーケンスを使用します\261
。たとえば、Terminal.app(およびおそらくiTerm2)は疑問符のみを印刷します。これらの端末はUTF-8を使用するため、\uxxxx
エスケープシーケンスを使用する必要があります。
ASCII以外の特定の文字をフォーマット文字列として印刷し、文字セットに関係なくすべての端末エミュレータで動作したいとします。私はあなたがデータベースのterminfoエントリを使用すると思いますが、私はterminfoに精通していません。ここに指示が必要です。
答え1
答え2
setlocale(LC_ALL, "")
then呼び出しを使用してアプリケーションのロケールを初期化しますnl_langinfo(CODESET)
。これにより、LANG、LC_CTYPE、およびLC_ALL環境変数に対して検証された値が提供されます。
これは実際にいいえターミナルエミュレータが実際にどのように機能するかを教えてくれますが、ほとんどすべてのアプリケーションがそれに依存しています。これにより、誤った結果が表示された場合、システムは誤って設定され、他のほとんどすべてのアプリケーションも端末エミュレータで正しく動作しません。アプリケーション開発者としてのあなたの使命は、問題があるかどうかを検出して修正しようとするものではありません。自分に合わせて正しく設定されたと安全に想定できます。システム管理者、デプロイメント開発者、またはシステムハッキングユーザーとしてのあなたの使命は、ロケール変数と端末エミュレータの実際の動作が一致することを確認することです。
答え3
端末エミュレータが正しく設計され構成されている場合、環境変数の値はLC_CTYPE
そのエンコーディングに一致する値に設定されます。残念ながら、実際には検査がLC_CTYPE
常に信頼できるわけではありません。設定されていないか、間違っている可能性があります。 (他の環境変数はロケールを渡すことができます。ロケールを何に設定する必要がありますか?これはどのような影響を及ぼしますか?もっと学ぶ。 )
可能な文字エンコーディングのアイデアがある場合は、経験的な方法でエンコードを決定できます。さまざまなエンコーディングでさまざまな幅のバイト文字列を表示し、カーソルがどれだけ移動するかを確認します。これはすべての場合には役に立ちません。たとえば、シングルバイトエンコーディングを区別することはできません。しかし、UTF-8と以前のエンコーディングが2つの可能性だけであれば問題ありません。シェルの起動時に公開したLC_CTYPE
スクリプトを使用してこのように設定しました。widthof
文字列の表示幅を取得します。。widthof -1
UTF-8で2文字を表す4バイト文字列を表示します。これらのうち、3バイトのみが印刷可能なラテンN文字です。したがって、幅2はUTF-8(または私にとっては不可能な他のマルチバイトエンコーディング)を意味し、幅3はラテンN(Nを知る方法がない)を意味し、4は印刷可能なシングルバイトエンコーディングです。を意味します。文字は128〜159です。
widthof -1
case $? in
0) export LC_CTYPE=C;; # 7-bit charset
2) locale_search .utf8 .UTF-8;; # utf8
3) locale_search .iso88591 .ISO8859-1 .latin1 '';; # 8-bit with nonprintable 128-159, we assume latin1
4) locale_search .iso88591 .ISO8859-1 .latin1 '';; # some full 8-bit charset, we assume latin1
*) export LC_CTYPE=C;; # weird charset
esac