Ada 2020 (1日目) - Wide_Wide_File_Names

文章を書くリハビリを兼ねてAda 2020の変更点を書いていきます。 まずは簡単なところから。

経緯

今までAdaではファイル名にLatin-1以外の文字を使えませんでした。 基本的な文字列型である String のエンコーディングがLatin-1と規格で決められていたからです。 他のエンコーディングは認められていませんでした。

Latin-1に無い文字を格納できるのは、UCS-2の Wide_String と、UTF-32の Wide_Wide_String です。 Wide_String は規格ではUTF-16ではなくUCS-2です。 サロゲートペアには対応していません。

しかし、標準ライブラリで使われているファイル名を表す型は String でした。

Ada 2012では Ada.Strings.UTF_Encoding というUTF-8を String に入れるライブラリも追加されましたが、他の標準ライブラリがLatin-1を想定しているところにUTF-8を入れてもまともに動くはずがありません。

実際の処理系では、String に無理やりLatin-9、SJIS、EUC-JP等を突っ込んで使うこともありましたが、言ってしまえば規格違反でした。

GNATでは、ファイル名を扱うサブプログラムの Form パラメータに "encoding=utf-8" を渡すことでファイル名をUTF-8として解釈させることができました。 Form パラメータは、処理系定義の追加のオプションを渡すためのパラメータです。 (https://gcc.gnu.org/onlinedocs/gnat_rm/FORM-Strings.html)

これは、なんか複数の処理系で合意があったとかなかったとかそんなやり方らしいのですが、大きな欠点がありました。 ファイル名を扱う全てのサブプログラムが Form パラメータを持っているわけではないのです。 当たり前ですよねー。

そのため Ada.Directories.Start_Search 等でディレクトリにあるファイル名を列挙させただけで、もしLatin-1に収まらないファイル名があればランタイムエラーになるというお粗末なことになりました。(これは規格上の動作で、GNATの Ada.Directories.Start_Search はファイル名を無変換のまま独自の謎チェックにかけてLatin-1として有効なファイル名でも一部エラーにしてしまう更にお粗末なことになっています。)

そんな状況でしたので、これまではAdaでまともにファイル名を扱おうとすれば規格違反の実装を使うしかありませんでした。

Ada 2020での改善

Ada 2020では、ファイル名を扱う全てのサブプログラムに Wide_StringWide_Wide_String 版が用意されます。

先述のようにUTF-16ですらない Wide_String に存在価値はありませんので、ファイル名は全て Wide_Wide_String で扱え、ということになります。

関連AI

追加されるパッケージ

  • Ada.*_IO.Wide_File_Names (Direct_IO, Sequential_IO, Streams.Stream_IO, Text_IO, Wide_Text_IO, そしてWide_Wide_Text_IO)

  • Ada.*_IO.Wide_Wide_File_Names (同上)

  • Ada.Wide_Command_Line

  • Ada.Wide_Wide_Command_Line

  • Ada.Wide_Environment_Variables

  • Ada.Wide_Wide_Environment_Variables

  • Ada.Wide_Directories (子パッケージ群も)

  • Ada.Wide_Wide_Directories (同上)

直接ファイル名を扱うものではありませんが、Ada.Command_LineAda.Environment_Variables にも追加されます。 コマンドラインや環境変数経由でファイル名(に限らずLatin-1に収まらない文字列)が指定されることもありますから必要です。

所感

こうなりますと、Wide_Wide_ の付かない元々の String 版ライブラリって丸っとゴミになりますよね……。 追加される Wide_ 版も丸っとゴミなわけですが……。

しかし、まあでも、長年の問題が解消されるわけで、喜んでいいと思いますたぶんきっとおそらく。

明日はもっとポジティブな話題を書きたいです。