home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 February / CHIP_2_98.iso / doc / HOWTO / mini / Locales < prev    next >
Text File  |  1997-07-31  |  19KB  |  485 lines

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