Poka ya opisyval, kak zastavit' razlichnye programmy ponyat' kirillicu. Obychno kazhdaya programma trebovala, chtoby eto byl ee sobstvennyj metod, kak pravilo, chrezvychajno otlichnyj ot drugih. Krome togo, u nekotoryh programm byla nezavershennaya podderzhka yazykov, otlichnyh ot anglijskogo, ne govorya uzh ob ih nesposobnosti vzaimodejstvovat', ispol'zuya rodnoj yazyk pol'zovatelya vmesto anglijskogo.
Problemy, perechislennye vyshe, sil'no podavlyayut, tak kak programmnoe obespechenie redko sozdaetsya tol'ko dlya mestnogo rynka. Pererabotka sushchestvennyh chastej programmnogo obespecheniya kazhdyj raz pri vhode na novyj mezhdunarodnomu rynok ochen' neeffektivna; a internacional'naya podderzhka, osushchestvlyaemaya sobstvennymi sredstvami programmy, unikal'nym i prisushchim tol'ko ej sposobom, v terminah dolgosrochnogo planirovaniya takzhe ne blestyashchaya ideya.
Sledovatel'no, voznikaet potrebnost' v standartizacii. I standart est'.
Vse svyazannoe s vysheperechislennymi problemami razdeleno v sootvetstvii c dvumya bazisnymi koncepciyami: localization i internationalization. Pod lokalizaciej my imeem v vidu sozdanie programm, sposobnyh obrabatyvat' razlichnye yazykovye soglasheniya dlya razlichnyh stran. Pozvol'te privesti primer. Format daty, vydannyj v Soedinennyh SHtatah - imeet vid MM/DD/GG. Odnako v Rossii naibolee populyarnyj format - DD.MM.GG. Drugie problemy vklyuchayut v sebya predstavlenie vremeni, formaty chisla i predstavleniya valyuty. Krome etogo, odin iz naibolee vazhnyh aspektov lokalizacii - eto opredelenie sootvetstvuyushchih klassov simvolov, to est' opredelenie: kakie simvoly v nabore simvolov yavlyayutsya "kirpichikami" yazyka (bukvami) i kak oni uporyadochivayutsya. S drugoj storony, lokalizaciya ne rabotaet so shriftami.
Internacionalizaciya (ili i18n dlya kratkosti), kak predpolagaetsya, reshaet problemy, svyazannye so sposobnost'yu programmy, vzaimodejstvuya s pol'zovatelem na ego rodnom yazyke.
Obe eti koncepcii dolzhny byt' standartizovany, davaya programmistam neprotivorechivyj put' sozdaniya programm, rabotayushchih v nacional'noj srede.
Hotya standartizaciya eshche v processe, no mnogo ee chastej uzhe fakticheski yavlyayutsya standartom; tak chto oni mogut ispol'zovat'sya bez osobyh problem.
YA opishu obshchuyu shemu sozdaniya programm, ispol'zuyushchih opisannye vyshe vozmozhnosti standartnym sposobom. Tak kak eto zasluzhivaet otdel'nogo dokumenta, ya budu davat' tol'ko ochen' obshchee opisanie i ukazateli na bolee polnye istochniki.
Odno iz osnovnyh ponyatij lokalizacii - locale. Pod locale podrazumevaetsya nabor soglashenij, specificheskih dlya otdel'no vzyatogo yazyka v otdel'no vzyatoj strane. V obshchem sluchae govorit', chto locale opredelyaetsya tol'ko stranoj, nepravil'no. Naprimer, v Kanade mogut byt' opredeleny dva locale- yazyk Kanada / Anglijskij i yazyk Kanada / Francuzskij. Bolee togo, yazyk Kanada / Anglijskij - ne yavlyaetsya ekvivalentom yazyku Velikobritaniya / Anglijskij ili Amerikanskij / Anglijskij, tochno tak zhe Kanada / Francuzskij yazyk - ne ekvivalent yazyku Franciya / Francuzskij ili yazyku SHvejcariya / Francuzskij.
Bolee podrobnoe opisanie problem/vozmozhnostej/dostoinstva lokalizacii na russkom yazyke mozhno najti na stranichke Lokalizaciya, kak ona est'.
Kazhdaya locale - eto special'naya baza dannyh, opredelyayushchaya, po krajnej mere, sleduyushchie pravila i soglasheniya:
Prezhde vsego - podrobnaya dokumentaciya o lokali imeetsya na www.sensi.org/~alec/locale Obrashchajtes' tuda, esli vam nuzhny nestandartnye varianty (naprimer, otklyuchenie russkoyazychnogo interfejsa s sohraneniem pravil'noj sortirovki i t.d.)
Dokumentaciyu po iksovoj lokali mozhno najti po adresu www.tsu.ru/~pascal/x_locale/
Vot instrukciya dlya neterpelivyh (tol'ko dlya glibc):
Vam nuzhno:
/usr/share/locale
i sozdat' tam simlink
ru_RU.KOI8-R,
ukazyvayushchij na ru_SU.
|ta operaciya neobhodima tol'ko dlya glibc < 2.1.2.
/etc/sysconfig/i18n
gde, krome prochego, dolzhna byt' strochka
LANG=ru_RU.KOI8-RV obshchem sluchae mozhno propisat' v
/etc/profile
LANG=<imya-vybrannogo-kataloga>. export LANG
Gorazdo zhe chestnee sdelat' otdel'nyj nastoyashchij katalog:
/usr/share/locale/ru_RU.KOI8-R/
(esli ego konechno net v
dannom distributive).
Nekotorye distributivy nepravil'no vklyuchayut
LANG=ru LC_ALL=ru_RU.KOI8-R
|to NEPRAVILXNO - pochemu tak delat' nel'zya opisano nizhe.
A teper' pogovorim o tom zhe no gorazdo podrobnee, i tak:
Kak vklyuchit' lokalizaciyu?
Esli na UNIX mashine (s POSIX:1996) sredstva locale pravil'no ustanovleny i programmy pravil'no napisany, to lokalizaciya vklyuchaetsya putem zadaniya stroki okruzheniya LANG:
$ export LANG={yazyk}
Esli takoj stroki okruzheniya net, to rabotaet znachenie lokalizacii
po umolchaniyu: LANG="C"
ili LANG="POSIX"
(chto to zhe samoe) - minimal'nyj nabor parametrov, neobhodimyj
dlya funkcionirovaniya programm na ANSI C (ISO 9899:1990), v
kodirovke US-ASCII (7 bit) (
Portable Character Set).
Esli vasha sistema imeet polnyj nabor utilit POSIX.2, to uznat'
ustanovlennye v sisteme i dopustimye znacheniya dlya LANG=
mozhno
komandoj locale
:
$ locale -a
Po novomu standartu (POSIX.2 prilozhenie E (?)) znacheniya lokalizacii zapisyvayutsya v forme:
language_TERRITORY.Codeset
ili formal'no:
language[_TERRITORY[.Codeset[@modyfier]]]
Standart ISO 639
opisyvaet "language names",
ISO 3166
- "territory names". Territorii _SU bolee ne
sushchestvuet (vernee teper' ona oznachaet Sudan), odnako dlya
sovmestimosti nekotorye sistemy prodolzhayut ee
podderzhivat' kak alias : ru_SU --> ru_RU
.
Dlya russkogo yazyka LANG
ustanavlivaetsya, kak pravilo,
ravnym LANG="ru_RU.KOI8-R"
ili LANG="ru_RU.ISO_8859-5"
. To est':
$ export LANG="ru_RU.KOI8-R"
Soglasno standartu dopustimy takzhe korotkie imenovaniya znachenij locale
,
kotorye chasto oformlyayutsya kak aliases
(psevdonimy) polnogo naimenovaniya.
Naprimer "C" --> "POSIX"
.
$ export LANG=ru $ export LANG=ru_RU $ export LANG=ru_RU.KOI8-R
Odnako, esli vy ukazyvaete korotkoe imya, mozhet okazat'sya chto vasha kodirovka okazyvaetsya vovse ne KOI8-R (pochemu sleduet ispol'zovat' imenno koi8-r opisano v razdele Simvoly i kodirovki). Luchshe ne pol'zovat'sya znacheniyami po umolchaniyu, a ukazyvat' tochnoe dlinnoe imya.
Vo FreeBSD 2.x tak i est'. Dlya Linux - zavisit ot distributiva. V kommercheskih realizaciyah (Solaris, SCO, AIX e.t.c.) kak pravilo ispol'zuetsya znachenie LANG="ru_RU", ili ukorochennoe LANG="ru" (i kak pravilo Codeset ISO8859-5 po umolchaniyu).
Nekotorye mogut pozhelat' sdelat' sebe lokalizaciyu v drugom nabore simvolov:
ru_RU.X-CP-866
(ru_RU.IBM866
), ru_RU.x-mac-cyrillic
,
ru_RU.ISO_8859-5
ili dazhe ru_RU.CP1251
- na eto net nikakih
ogranichenij. Vse eti kodirovki sovershenno ravnopravny i
zaregistrirovany (krome x-mac-cyrillic
) v IANA.
Tol'ko ne zabud'te, chto lokalizaciya, vvod-vyvod i otobrazhenie
nacional'nyh simvolov na terminale - eto sovershenno raznye veshchi.
Esli sistema lokalizovana ne polnost'yu i ispol'zovat' polnoe
pereklyuchenie na drugoj yazyk (s pomoshch'yu export LANG={yazyk}
) nel'zya,
mozhno vklyuchit' locale tol'ko dlya funkcij locale API
biblioteki libc
, zadav znachenie kategorij lokalizacii. Mozhno
takzhe prisvaivat' raznye znacheniya raznym kategoriyam, zadavaya ih
imena v strokah okruzheniya :
Esli vas razdrazhayut russkie daty, soobshcheniya i man-y, no nuzhno obrabatyvat' russkie bukvy i t.d., to sdelajte:
$ export LANG="C" $ export LC_CTYPE="ru_RU.KOI8-R" $ export LC_COLLATE="ru_RU.KOI8-R" $ export LC_TIME="C"
Ne rekomenduetsya ispol'zovat' stroku okruzheniya:
$ export LC_ALL={yazyk}
poskol'ku formal'no takoj kategorii lokalizacii net, ona
"virtual'naya" i oboznachaet "odnovremenno vse kategorii". Iz za etogo
vo mnogih realizaciyah locale API
voznikayut problemy.
Problemy mogut vozniknut' takzhe s programmami, rabotayushchimi s
PostScript
: v kategorii LC_NUMERIC
lokalizacii ru_RU
v sootvetstvii so standartom GOST v kachestve
desyatichnogo razdelitelya ispol'zuetsya simvol 'zapyataya' : "," v to vremya,
kak v standarte yazyka PostScript : tochka "." A kategoriya LC_NUMERIC
okazyvaet vliyanie na printf("%f",float);
. Ispol'zujte znachenie
C (POSIX)
dlya LC_NUMERIC
, esli vy rabotaete s PostScript
:
$ export LC_NUMERIC="POSIX"
Posmotret' tekushchie znacheniya kategorij lokalizacii mozhno vse toj zhe utilitoj locale (bez parametrov).
$ locale
PRIMECHANIE: V nekotoryh sovremennyh sistemah nachinaet poyavlyat'sya lokalizaciya v UNICODE. Vklyuchaetsya ona zadaniem stroki okruzheniya LANG="ru_RU.UTF-8" dlya Rossii.
V RedHat Linux (kak, veroyatno, i vo mnogih drugih distributivah Linux),
imeyutsya fakticheski dve bazy
dannyh locale: odna dlya biblioteki C (libc
), a drugaya - dlya X
bibliotek. V ideal'nom sluchae dolzhna imet'sya tol'ko odna baza
dannyh locale dlya vsego.
CHtoby izmenit' znachenie locale po umolchaniyu, obychno
dostatochno ustanovit' sistemnuyu peremennuyu LANG
. Naprimer, kak
eto delaetsya v sh
:
LANG=ru_SU export LANG
Vy mozhete proverit' dejstvie etoj komandy srazu zhe, esli zapustite
komandu date
. Rezul'tatom dolzhen byt' vyvod dnya, nedeli i mesyaca na
russkom yazyke.
RedHat 5.x opredelyaet KOI8-R locale kak ru_SU
.
Bolee ochevidnoe nazvanie ru_RU
ispol'zuetsya
dlya locale, osnovannogo na iso-8859-5
kodirovki.
Inogda vy mozhete zahotet' izmenit' tol'ko odin aspekt locale
bez izmeneniya drugih. Naprimer, vy mozhete zahotet' (Bog znaet
pochemu) pol'zovat'sya s ru_SU
locale, no pechataemye chisla dolzhny
budut sootvetstvovat' standartu POSIX odin. V podobnyh sluchayah
imeetsya nabor sistemnyh peremennyh, kotorye Vy mozhete zadat',
chtoby skonfigurirovat' sootvetstvuyushchie chasti locale. Naprimer, v
nashem sluchae eto by vyglyadelo tak:
LANG=ru_SU LC_NUMERIC=POSIX export LANG LC_NUMERIC
Podrobnee sm. locale(7)
.
Teper' davajte derzhat'sya poblizhe k specifike Linux.
K sozhaleniyu, v Linux libc
versii 5.3.12 (primer: distributiv
RedHat 4.1), otsutstvuet russkaya locale. V dannom sluchae ee nado
skachat' iz Interneta (ya, odnako, ne znayu tochnogo adresa).
CHtoby proverit', dlya kakih yazykov u vas est' locale, vypolnite
'locale -a
'. |to vyvedet spisok vseh locale iz baz dannyh,
dostupnyh libc.
CHto kasaetsya bibliotek X
, to oni imeyut svoyu sobstvennuyu bazu
dannyh locale. V versii XFree86 3.3
uzhe
imeetsya rossijskaya baza dannyh locale. YA ne uveren, est' li ona v
predydushchej versii. V lyubom sluchae vy mozhete proverit' eto,
izuchiv direktoriyu /usr/lib/X11/locale/
(v bol'shinstve sistem). V
moem sluchae uzhe est' podkatalogi, imenovannye koi8-r
i dazhe
iso8859-5
..
S locale programma ne dolzhna znat' o razlichnyh simvol'nyh preobrazovaniyah i pravilah sravneniya, opisannyh vyshe. Vmesto etogo oni ispol'zuyut special'nyj API, kotoryj dejstvuet po pravilam, opredelennym locale. Krome togo, net neobhodimosti dlya programmy pol'zovat'sya tol'ko odnoj locale dlya soblyudeniya vseh pravil - vozmozhno pol'zovat'sya drugimi pravilami, opisannyh v drugih locale (hotya takoj metod ne ochen' horosh).
Iz man setlocale(3)
:
Programma mozhet byt' sdelana perenosimoj dlya vseh locale, vyzyvayasetlocale(LC_ALL, "" )
posle inicializacii programmy, ispol'zuya znacheniya, vozvrashchennye izlocaleconv()
zapros dlya locale - zavisimoj informacii i ispol'zuyastrcoll()
ilistrxfrm()
dlya sravneniya strok.
Dovol'no legko opredelit' chetyre urovnya programmnoj lokalizacii:
setlocale()
. Ona ne delaet kakih-libo predpolozhenij
otnositel'no 8-ogo bita kazhdogo simvola, ispol'zuya
pol'zovatel'skie funkcii iz ctype.h
i ogranicheniya iz limits.h
, a takzhe
zabotitsya otnositel'no signed/unsigned
rezul'tata.
Ochen' vazhno, chtoby programma ne delala kakih-libo predpolozhenij
otnositel'no haraktera nabora simvolov i ih uporyadocheniya. To est'
sleduet vozderzhat'sya ot sleduyushchih konstrukcij pri
programmirovanii:
if (c >= 'A' && c <= 'Z') { ...
ctype.h
.
Naprimer:
if (isalpha(c) && isupper(c)) { ... ili if (isascii(c) && isupper(c))
strcoll()
i strxfrm()
vmesto strcmp()
dlya strok,
ispol'zuet time()
, localtime()
, i strftime()
dlya raboty so
vremenem, i v zaklyuchenie, ispol'zuet localeconv()
dlya
pravil'nogo predstavleniya chisel i valyuty.
gettext()
(Sun/POSIX standart), ili catgets()
(X/Open standart). Podrobnee sm. razdel
i18n
.
char
. Vzamen eto ona ispol'zuet wchar_t
, kotoryj
opredelyaet ob®ekty, dostatochno bol'shie, chtoby soderzhat' simvoly
Unicode. ANSI C opredelyaet etot tip dannyh i sootvetstvuyushchij API.
Dlya vyyasneniya podrobnostej smotrite, naprimer, ( Voropay1 ) ili ( SingleUnix ).
V to vremya kak lokalizaciya opisyvaet, kak adaptirovat' programmu k inostrannomu okruzheniyu, internacionalizaciya (ili i18n dlya kratkosti) detaliziruet sposoby obshcheniya programmy s ne-anglogovoryashchim pol'zovatelem.
Prezhde eto delalos' s pomoshch'yu sozdaniya abstrakcij soobshchenij dlya vyvoda ih iz koda programmy. Teper' takoj mehanizm (bolee ili menee) standartizirovan. I, konechno, est' ego free realizacii!
Proekt GNU, nakonec, stal na put' sozdaniya
internacionalizirovannyh prikladnyh programm. Ulrich Drepper
(drepper@ipd.info.uni-karlsruhe.de
) razrabotal paket gettext
.
|tot paket lezhit vo vseh GNU arhivah, naprimer, v
prep.ai.mit.edu.
On pozvolyaet vam razrabatyvat' programmy v napravlenii, dvigayas'
v kotorom vy mozhete legko zastavit' ih podderzhivat' bol'shee
kolichestvo yazykov. YA ne predpolagayu opisyvat' metody
programmirovaniya eshche i potomu, chto gettext
paket postavlyaetsya s
prevoshodnym rukovodstvom.
Pros'ba o sotrudnichestve: Esli vy hotite izuchit' gettext
paket
i sdelat' svoj vklad v proekt GNU ili prosto sdelat' vklad bez
vsyakogo izucheniya, to vy mozhete sdelat' eto! GNU stanovitsya
mezhdunarodnym, tak chto vse utility delayutsya locale zavisimymi.
Problema sostoit v tom, chtoby perevodit' soobshcheniya s Anglijskogo
yazyka na Russkij (i drugie yazyki, konechno esli zahotite). V
obshchem, chto sleduet sdelat': vy dolzhny poluchit' special'nyj .po
fajl, sostoyashchij iz Anglijskih soobshchenij dlya nekih utilit, i
svyazat' kazhdoe soobshchenie s ego ekvivalentom na russkom. V konechnom
schete, eto zastavit govorit' sistemu po-russki, esli pol'zovatel'
zahochet etogo! Dlya dlya podrobnostej vojdite v kontakt s Ulrich
Drepper (
drepper@ipd.info.uni-karlsruhe.de).