home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 8 / CDACTUAL8.iso / docs / mini / locales < prev    next >
Encoding:
Text File  |  1996-07-11  |  15.2 KB  |  431 lines

  1.   Locales mini-HOWTO
  2.   Peeter Joot, joot@ecf.toronto.edu
  3.   v1.2, 2 May 1996.
  4.  
  5.   This document describes how to set up your Linux machine to use
  6.   locales.
  7.  
  8.   1.  Introduction
  9.  
  10.   This is really a description of what I had to do to get localedef
  11.   installed, compile some locales, and try them out.  I did this just
  12.   for fun, and thought that perhaps some people would be interested in
  13.   trying it out themselves.  Once it is set up you should be able to use
  14.   NLS enabled applications with the locale of your choice.
  15.  
  16.   2.  What is a "locale" anyhow?
  17.  
  18.   Locales encapsulate some of the language/culture specific things that
  19.   you shouldn't hard code in your programs.
  20.  
  21.   If you have various locales installed on your computer then you can
  22.   select via the following list of environment variables how a locale
  23.   sensitive program will behave.  The default locale is the C, or POSIX
  24.   locale which is hard coded in libc.
  25.  
  26.      LANG
  27.         This sets the locale, but can be overridden with any other
  28.         LC_xxxx environment variables
  29.  
  30.      LC_COLLATE
  31.         Sort order.
  32.  
  33.      LC_CTYPE
  34.         Character definitions, uppercase, lowercase, ...  These are used
  35.         by the functions like toupper, tolower, islower, isdigit, ...
  36.  
  37.      LC_MONETARY
  38.         Contains the information necessary to format money in the
  39.         fashion expected.  It has the definitions of things like the
  40.         thousands separator, decimal separator, and what the monetary
  41.         symbol is and how to position it.
  42.  
  43.      LC_NUMERIC
  44.         Thousands, and decimal separators, and the numeric grouping
  45.         expected.
  46.  
  47.      LC_TIME
  48.         How to specify the time, and date.  This has the things like the
  49.         days of the week, and months of the year in abbreviated, and non
  50.         abbreviated form.
  51.  
  52.      LC_MESSAGES
  53.         Yes, and No expressions.
  54.  
  55.      LC_ALL
  56.         This sets the locale, and overrides any other LC_xxxx
  57.         environment variables.
  58.  
  59.   Here are some other locales, and there are lots more.
  60.  
  61.      en_CA
  62.         English Canadian.
  63.  
  64.      en_US
  65.         US English.
  66.  
  67.      de_DE
  68.         Germany's German.
  69.  
  70.      fr_FR
  71.         France's French.
  72.  
  73.   If you are writing a program, and want to to be usable internationally
  74.   you should utilize locales.  The most glaring reason for this is that
  75.   not everybody is going to use the same character set/code page as you.
  76.  
  77.   Make sure in your programs that you don't do things like
  78.  
  79.        /* bad test for alphabetical character */
  80.        if ( c >= 'a' && c <= 'Z' )
  81.  
  82.        /* even worse test : don't do this ! */
  83.        if ( c >= 0x41 && c <= 0x7a )
  84.  
  85.   Instead you should use the locale sensitive functions like isalpha.
  86.  
  87.   The basic idea is different people speak different languages, expect
  88.   different sorting orders, use different code pages, and live in
  89.   different countries.  Your programs should respect such things, and
  90.   handle them accordingly.  It is not really much extra work to do so,
  91.   it just requires a slightly different frame of mind when writing
  92.   programs.
  93.  
  94.   3.  Notes.
  95.  
  96.   ╖  In order to set up locales on my machine I had to upgrade a few
  97.      things.  Apparently ftp.tu-clausthal.de:/pub/linux/SLT/nls contains
  98.      a a.out version of locale and localedef (in the file
  99.      nlsutils-0.5.tar.gz), so if you don't have an ELF system, or don't
  100.      want one you can use the above.  There is probably a copy of the
  101.      nlsutils package some other place, but I have not looked for it.  I
  102.      hadn't known that there was a stand alone version of locale and
  103.      localedef, and kind of figured that you would have to have the
  104.      corresponding libc installed.  Because of this a lot of this HOWTO
  105.      is just a log of what I had to do to upgrade libc and family.  If
  106.      you do this, as I have you, will need to be running an ELF system,
  107.      or upgrade to one as you set up your locales.
  108.  
  109.   ╖  The sorts of system upgrades that I did are the same sort of
  110.      upgrades that have to be done to upgrade from a.out to ELF.  If you
  111.      haven't done this, or if you have upgraded to ELF by reinstalling
  112.      Linux then you should get the resent ELF HOWTO from a sunsite
  113.      mirror.  This is an excellent guide, and gives additional guidance
  114.      for installing libc, ld.so, and other ELF system upgrades.
  115.  
  116.   ╖  For anything that you install, read the appropriate release notes,
  117.      or README type files.  If you mess up your system by
  118.      misinterpreting something that I say here, or ( hopefully not ) by
  119.      doing something that I say in here, please don't blame me.
  120.  
  121.   ╖  Mis-installing a new libc, and ld.so, could leave you with an
  122.      unbootable system.  You probably ought to have a boot disk handy,
  123.      and make sure any critical, non-replaceable, data is backed up.
  124.  
  125.   4.  What you need.
  126.  
  127.   A few things need to be down loaded from various places.  Everything
  128.   here except for the locale source files can be obtained from
  129.   sunsite.unc.edu, tsx-11.mit.edu, or, preferably, a local mirror of
  130.   these sites.
  131.  
  132.   ╖  locale, and charmap sources --- These are what you compile using
  133.      localedef.
  134.  
  135.   ╖  libc-5.2.18.bin.tar.gz --- the ELF shared libraries for the c and
  136.      math libraries.
  137.  
  138.   ╖  libc-5.2.18.tar.gz --- the source code for the ELF shared
  139.      libraries.  You will need this to compile localedef.
  140.  
  141.   ╖  make-3.74.tar.gz --- you may need to compile make to incorporate a
  142.      patch to fix the dirent bug.
  143.  
  144.   ╖  release.libc-5.2.18 --- these release notes have the patch to make
  145.      make.
  146.  
  147.   ╖  ld.so-1.7.12+ --- the dynamic linker.
  148.  
  149.   ╖  ELF gcc-2.7.2+ --- to compile things.
  150.  
  151.   ╖  ELF kernel 1.1.92+, or ELF kernel 1.3.40+ --- to compile things.
  152.  
  153.   ╖  binutils 2.6.0.2+ --- to compile things.
  154.  
  155.   There are probably lots of places that you can get locale sources.  I
  156.   have found public domain locale and charmap sources at
  157.   dkuug.dk:/i18n/WG15-collection/locales
  158.   <ftp://dkuug.dk/i18n/WG15-collection/locales> and
  159.   dkuug.dk:/i18n/WG15-collection/charmaps
  160.   <ftp://dkuug.dk/i18n/WG15-collection/charmaps>  respectively.
  161.  
  162.   5.  Installing everything.
  163.  
  164.   This is what I did to install everything.  I already had an ELF system
  165.   ( compiler, kernel, ... ) installed before I did this.
  166.  
  167.   1. First I installed the binutils package.  tar xzf
  168.      binutils-2.6.0.2.bin.tar.gz -C /
  169.  
  170.   2. Next I installed the dynamic linker:
  171.  
  172.        tar zxf ld.so-1.7.12.tar.gz -C /usr/src
  173.        cd /usr/src/ld.so-1.7.12
  174.        sh instldso.sh
  175.  
  176.   3. Next I installed the libc binaries.  See release.libc-5.2.18 for
  177.      more instructions.
  178.  
  179.        rm -f /usr/lib/libc.so /usr/lib/libm.so
  180.        rm -f /usr/include/iolibio.h /usr/include/iostdio.h
  181.        rm -f /usr/include/ld_so_config.h /usr/include/localeinfo.h
  182.        rm -rf /usr/include/netinet /usr/include/net /usr/include/pthread
  183.        tar -xzf libc-5.2.18.bin.tar.gz -C /
  184.  
  185.   4. Now ldconfig must be run to locate the new shared libraries.
  186.      ldconfig -v.
  187.  
  188.   5. There is a bug that was fixed in libc that breaks make, and some
  189.      other programs.  Here is what I did in order to rebuild and install
  190.      make.
  191.  
  192.        tar zxf make-3.74.tar.gz -C /usr/src
  193.        cd /usr/src/make-3.74
  194.        patch < /whereever_you_put_it/release.libc-5.2.18
  195.        configure --prefix=/usr
  196.        sh build.sh
  197.         ../make install
  198.        cd ..
  199.        rm -rf make-2.74
  200.  
  201.   6. Now localedef can be compiled and installed.
  202.  
  203.        mkdir /usr/src/libc
  204.        tar zxf libc-5.2.18.tar.gz -C /usr/src/libc
  205.        cd /usr/src/libc
  206.        cd include
  207.        ln -s /usr/src/linux/include/asm .
  208.        ln -s /usr/src/linux/include/linux .
  209.        cd ../libc
  210.         ../configure
  211.        # I am not sure if these two makes are necessary, but just to be safe :
  212.        make clean ; make depend
  213.        cd locale
  214.        make programs
  215.        mv localedef /usr/local/bin
  216.        mv locale /usr/local/bin
  217.  
  218.   7. Put the charmaps where localedef will find them.  This uses the
  219.      charmaps and locale sources which I down loaded from dkuug.dk ftp
  220.      site as charmaps.tar, and locales.tar respectively.
  221.  
  222.   tar xf charmaps.tar -C /tmp
  223.   mkdir /usr/share/nls
  224.   mkdir /usr/share/nls/charmap
  225.   mkdir /usr/share/locale
  226.   mv /tmp/charmaps/* /usr/share/nls/charmap
  227.   rm -rf /tmp/charmaps
  228.   tar xf locales.tar -C /usr/share # put these where you want.
  229.  
  230.   # Some of the locale sources use `copy' and thus
  231.   # have dependencies on other locales.  I did some
  232.   # grep'ping, cut'ting, and sed'ding to
  233.   # make a makefile to make the following
  234.   # list of commands.  This will create all the
  235.   # locale objects within the /usr/share/locale
  236.   # directory.
  237.   #
  238.   localedef -ci locales/en_DK -f ISO_8859-1:1987 en_DK
  239.   localedef -ci locales/sv_SE -f ISO_8859-1:1987 sv_SE
  240.   localedef -ci locales/fi_FI -f ISO_8859-1:1987 fi_FI
  241.   localedef -ci locales/sv_FI -f ISO_8859-1:1987 sv_FI
  242.   localedef -ci locales/ro_RO -f ISO_8859-1:1987 ro_RO
  243.   localedef -ci locales/pt_PT -f ISO_8859-1:1987 pt_PT
  244.   localedef -ci locales/no_NO -f ISO_8859-1:1987 no_NO
  245.   localedef -ci locales/nl_NL -f ISO_8859-1:1987 nl_NL
  246.   localedef -ci locales/fr_BE -f ISO_8859-1:1987 fr_BE
  247.   localedef -ci locales/nl_BE -f ISO_8859-1:1987 nl_BE
  248.   localedef -ci locales/da_DK -f ISO_8859-1:1987 da_DK
  249.   localedef -ci locales/kl_GL -f ISO_8859-1:1987 kl_GL
  250.   localedef -ci locales/it_IT -f ISO_8859-1:1987 it_IT
  251.   localedef -ci locales/is_IS -f ISO_8859-1:1987 is_IS
  252.   localedef -ci locales/fr_LU -f ISO_8859-1:1987 fr_LU
  253.   localedef -ci locales/fr_FR -f ISO_8859-1:1987 fr_FR
  254.   localedef -ci locales/de_DE -f ISO_8859-1:1987 de_DE
  255.   localedef -ci locales/de_CH -f ISO_8859-1:1987 de_CH
  256.   localedef -ci locales/fr_CH -f ISO_8859-1:1987 fr_CH
  257.   localedef -ci locales/en_CA -f ISO_8859-1:1987 en_CA
  258.   localedef -ci locales/fr_CA -f ISO_8859-1:1987 fr_CA
  259.   localedef -ci locales/fo_FO -f ISO_8859-1:1987 fo_FO
  260.   localedef -ci locales/et_EE -f ISO_8859-1:1987 et_EE
  261.   localedef -ci locales/es_ES -f ISO_8859-1:1987 es_ES
  262.   localedef -ci locales/en_US -f ISO_8859-1:1987 en_US
  263.   localedef -ci locales/en_GB -f ISO_8859-1:1987 en_GB
  264.   localedef -ci locales/en_IE -f ISO_8859-1:1987 en_IE
  265.   localedef -ci locales/de_LU -f ISO_8859-1:1987 de_LU
  266.   localedef -ci locales/de_BE -f ISO_8859-1:1987 de_BE
  267.   localedef -ci locales/de_AT -f ISO_8859-1:1987 de_AT
  268.   localedef -ci locales/sl_SI -f ISO_8859-2:1987 sl_SI
  269.   localedef -ci locales/ru_RU -f ISO_8859-5:1988 ru_RU
  270.   localedef -ci locales/pl_PL -f ISO_8859-2:1987 pl_PL
  271.   localedef -ci locales/lv_LV -f BALTIC lv_LV
  272.   localedef -ci locales/lt_LT -f BALTIC lt_LT
  273.   localedef -ci locales/iw_IL -f ISO_8859-8:1988 iw_IL
  274.   localedef -ci locales/hu_HU -f ISO_8859-2:1987 hu_HU
  275.   localedef -ci locales/hr_HR -f ISO_8859-4:1988 hr_HR
  276.   localedef -ci locales/gr_GR -f ISO_8859-7:1987 gr_GR
  277.  
  278.   6.  Now what.
  279.  
  280.   After doing all the stuff above you should now be able to use the
  281.   locales that have been created.  Here is a simple example program.
  282.  
  283.        /* test.c : a simple test to see if the locales can be loaded, and
  284.         * used */
  285.        #include <locale.h>
  286.        #include <stdio.h>
  287.        #include <time.h>
  288.  
  289.        main(){
  290.                time_t t;
  291.                struct tm * _t;
  292.                char buf[256];
  293.  
  294.                time(&t);
  295.                _t = gmtime(&t);
  296.  
  297.                setlocale(LC_TIME,"");
  298.                strftime(buf,256,"%c",_t);
  299.  
  300.                printf("%s\n",buf);
  301.        }
  302.  
  303.   You can use the locale program to see what your current locale
  304.   environment variable settings are.
  305.  
  306.        $ # compile the simple test program above, and run it with
  307.        $ # some different locale settings
  308.        $ gcc -s -o Test test.c
  309.        $ # see what the current locale is :
  310.        $ locale
  311.        LANG=POSIX
  312.        LC_COLLATE="POSIX"
  313.        LC_CTYPE="POSIX"
  314.        LC_MONETARY="POSIX"
  315.        LC_NUMERIC="POSIX"
  316.        LC_TIME="POSIX"
  317.        LC_MESSAGES="POSIX"
  318.        LC_ALL=
  319.        $ # Ho, hum... we're using the boring C locale
  320.        $ # let's change to English Canadian:
  321.        $ export LC_TIME=en_CA
  322.        $ Test
  323.        Sat 23 Mar 1996 07:51:49 PM
  324.        $ # let's try French Canadian:
  325.        $ export LC_TIME=fr_CA
  326.        $ Test
  327.        sam 23 mar 1996 19:55:27
  328.  
  329.   7.  catopen bug fix.
  330.  
  331.   Installing the locales fixes a bug (feature ?)  that is in the catopen
  332.   command in Linux libc.  Say you create a program that uses message
  333.   catalogs, and you create an German catalog and put it in
  334.   /home/peeter/catalogs/de_DE.
  335.  
  336.   Now upon doing the following, without the de_DE locale installed :
  337.  
  338.   export LC_MESSAGES=de_DE
  339.   export NLSPATH=/home/peeter/catalogs/%L/%N.cat:$NLSPATH
  340.  
  341.   the German message catalog does not get opened, and the default mes¡
  342.   sages in the catgets calls are used.
  343.  
  344.   This is because catopen does a setlocale call to get the right message
  345.   category, the setlocale fails even though the environment variable has
  346.   been set.  catopen then attempts to load the message catalog
  347.   substituting "C" for all the "%L"'s in the NLSPATH.
  348.  
  349.   You can still use your message catalog without installing the locale,
  350.   but you would have to explicitly set the "%L" part of the NLSPATH like
  351.  
  352.        export NLSPATH=/home/peeter/catalogs/de_DE/%N.cat:$NLSPATH
  353.  
  354.   , but this defeats the whole purpose of the locale catagory environ¡
  355.   ment variables.
  356.  
  357.   8.  Questions and Answers.
  358.  
  359.   This section could grow into a FAQ, but isn't really one yet.
  360.  
  361.   8.1.  msgcat question
  362.  
  363.   I am an user of LINUX, and have written the following test program:
  364.  
  365.        --------------------------------------------------------------------
  366.        #include <stdio.h>
  367.        #include <locale.h>
  368.        #include <features.h>
  369.        #include <nl_types.h>
  370.  
  371.        main(int argc, char ** argv)
  372.        {
  373.                nl_catd catd;
  374.  
  375.                setlocale(LC_MESSAGES, "");
  376.                catd = catopen("msg", MCLoadBySet);
  377.                fprintf(stderr,catgets(catd, 1, 1, "locale message fail\n"));
  378.                catclose(catd);
  379.        }
  380.        --------------------------------------------------------------------
  381.        $ msg.m
  382.        $set 1
  383.  
  384.        1 locale message pass\n
  385.        --------------------------------------------------------------------
  386.  
  387.   If I use absolute path in catopen like
  388.   catopen("/etc/locale/msg.cat",MCLoadBySet); ,I got the right result.
  389.   But,if I use above example,catopen return -1 (failure).
  390.  
  391.   8.2.  msgcat answer
  392.  
  393.   This question is sort of answered in the previous section, but here is
  394.   some additional information.
  395.  
  396.   There are a number of valid places where you can put your message
  397.   catalogs.  Even though you may not have NLSPATH explicitly defined in
  398.   your environment settings it is defined in libc as follows :
  399.  
  400.        $ strings /lib/libc.so.5.2.18 | grep locale | grep %L
  401.        /etc/locale/%L/%N.cat:/usr/lib/locale/%L/%N.cat:/usr
  402.        /lib/locale/%N/%L:/usr/share/locale/%L/%N.cat:/usr/
  403.        local/share/locale/%L/%N.cat
  404.  
  405.   so you if you have done one of :
  406.  
  407.        $ export LC_MESSAGES=en_CA
  408.        $ export LC_ALL=en_CA
  409.        $ export LANG=en_CA
  410.  
  411.   With the NLSPATH above and the specified environment , the
  412.   catopen("msg", MCLoadBySet); should work if your message catalog has
  413.   been copied to any one of :
  414.  
  415.        /etc/locale/en_CA/msg.cat
  416.        /usr/lib/locale/en_CA/msg.cat
  417.        /usr/lib/locale/msg/en_CA
  418.        /usr/share/locale/en_CA/msg.cat
  419.        /usr/local/share/locale/en_CA/msg.cat
  420.  
  421.   This, however, will not work if you don't have the en_CA locale
  422.   installed because the setlocale will fail, and "C" will be substituted
  423.   for "%L" in the catopen routine ( rather than "en_CA" ).
  424.  
  425.   9.  Finale
  426.  
  427.   Well that's it.  Hopefully this guide has been some to you, and you
  428.   should be ready to write and use internationalized (i18n) applications
  429.   on Linux.
  430.  
  431.