C++ STL fun -- re: std::locale és toupper

Erre a kérdésre támadt kedvem összeállítani egy C++-ízű megoldást. Íme:

Hozzászólások

A fájl UTF-8-ban mentve, majd clang-2.8 és g++ 4.2.1 eredménye FreeBSD-n (ugyenzt kapom, ha UTF-8-at használó locale-lal futtatom UTF-8-as xterm-ben)

$ ./toupper.clang
terminate called without an active exception
Abort trap
$ ./toupper.gcc
terminate called after throwing an instance of 'std::runtime_error'
what(): locale::facet::_S_create_c_locale name not valid
Abort trap
$ locale
LANG=hu_HU.ISO8859-2
LC_CTYPE="hu_HU.ISO8859-2"
LC_COLLATE="hu_HU.ISO8859-2"
LC_TIME="hu_HU.ISO8859-2"
LC_NUMERIC="hu_HU.ISO8859-2"
LC_MONETARY="hu_HU.ISO8859-2"
LC_MESSAGES="hu_HU.ISO8859-2"
LC_ALL=
$

Könnyen reprodukálható nálam is, ha valamelyik LC_XXX változóban érvénytelen értéket adok meg. A "locale" parancs (paraméterek nélkül) csak annyit jelez vissza, hogy a felhasználó milyen beállításokat szeretne érvényesíteni; arról nem szól, hogy ebből mi elégíthető ki.

Ez a sor hajít el egy std::runtime_error-t (a [lib.locale.cons] p7 által dokumentáltan):


  const std::locale cur_loc("");

Biztosat persze csak úgy fogsz tudni, ha engedélyezed a core dump írását, és belenézel gdb-vel (... és ha a forrást -g3-mal fordítod).

Az a parancs, hogy "locale -k", nem jelez hibát? Pl. LC_MESSAGES hiányára nem panaszkodik?

... Arra akarok kilyukadni, hogy a hu_HU.ISO8859-2 nincs 100%-osan telepítve. Egy "rendes" programnak természetesen az ilyen hibákat is kezelnie kell, de most ezzel nem foglalkoztam. Pl. a ::setlocale() visszatérési értékét sem ellenőrzöm.

Az LC_MESSAGES legegyszerűbb ellenőrzése (a fenti LANG beállítás mellett):


touch /tmp/dummy
rm -i /tmp/dummy

Ha az "rm" kérdésére "i"-vel (és nem "y"-nal) válaszolsz, letörli a file-t?

Hm, kösz a tippet. A locale -k FreeBSD-n paramétert vár. Ellenben az rm -es kérdésed talált. Már csak az a furcsa, hogy vagy 15 éve én csináltam meg a FreeBSD hu locale-ját, és tudom, hogy akkor még volt benne yesstr és nostr :-) Persze az is lehet, hogy simán az rm nincs felkészítve a locale kezelésére. Erre utal ez is:

$ locale -k yesstr
yesstr="igen"
$ locale -k nostr
nostr="nem"
$

Már csak arra nem emlékszem, mi a neve a rövid yesstr/nostr változóknak. (Pár locale-t lekérdezve, elég kevésben van ez a kettő implementálva. Szégyen.)

Kosz, valoban. Es mit ad isten, most megneztem ezt az egeszet 9.0-s FreeBSD-n. Immar hu_HU.UTF-8 a locale, a magyaritas jo is, yesstr/nostr/yesexpr/noexpr mind gyonyoru; g++ ugyanaz, de immar 3.0-as clang/llvm. Es a hibauzenet is ugyanaz, szoval valami mast hianyolunk abbol a locale-bol, nem az igen es nem szavakat.