Aros/Developer/Docs/Libraries/Locale
Introduction
edithere is a global environment variable (Language) that holds the current active language.
You can check this yourself by typing "getenv language" (without the quotes) into a shell. Or it can be used in a script as variable $Language.
It can also be done programming using the OpenLocale() function (with NULL as parameter to return the current locale information in struct Locale)
System
editThe locale.library provides us tools to localize applications. Localized strings are stored in separate languages catalogs files, under Catalogs directories. AROS Development Environment macros can build the required files. This document gives you a work-flow to localize applications or localize existing applications or create catalogs files for existing localized applications.
For each language supported, the system has a LOCALE:Languages/ file:
LOCALE:Languages/klingon.language
System translations are in LOCALE:Catalogs/ language directories:
LOCALE:Catalogs/klingon/
Each application needs its proper Catalogs directory:
my_app/Catalogs/
Translation files are in languages directories:
my_app/Catalogs/klingon/my_app.catalog
Appplications
editEach application supporting localization has its own catalogs directory:
AROS/Contrib/my_app/catalogs
Strings are initially stored in a catalog description file:
AROS/Contrib/my_app/catalogs/my_app.cd
This file is structured as: ; MSG_TITLE (//) My Application ; MSG_MY_MESSAGE (//) My application message ; ...
Translations are stored in catalog translation files:
AROS/Contrib/my_app/catalogs/klingon.ct
Structured as:
## version $VER: my_app.catalog 1.0 (23.05.2004) ## language klingon ## codeset 0 ; MSG_TITLE tlhIngan maH ; MSG_MY_MESSAGE Sujatlh 'e' yImev ; ...
The catalogs build file
Localization is provided by:
AROS/Contrib/my_app/locale.c
AROS/contrib/my_app/locale.h
Application: _(MSG_MY_TITLE)
As STRPTR.
Or with: __(MSG_MY_MESSAGE)
As IPTR (1) The application source file
In AROS/Contrib/my_app/my_app.c, initialize locale with:
...
#include "locale.h"
main()
{
...
Use the strings names from the .cd file. For instance, on a Zune application: MUIA_Application_Title, __(MSG_TITLE), ... } The application build file
Add the locale file target to the FILE section of AROS/Contrib/my_app/mmakefile.src: FILES := my_app \ ... locale Add the pre-requisite target for locale: #MM- my_app: \ ... #MM my_app-catalogs Build the locale AROS/ To build the application and locale files: make my_app To update the translation (.ct) files: make my_app-catalogsWarning: If you are updating the description (.cd) files, build my_app target to update its strings file.
Build System
editAROS Metamake builds required files with its build file present as:
AROS/Contrib/my_app/catalogs/mmakefile.src
# Copyright © 2004, The AROS Development Team. All rights reserved.
# $Id: mmakefile.src,v 1.2 2004/02/19 22:05:38 john doe Exp $
include $(TOP)/config/make.cfg
%build_catalogs mmake=my_app-catalogs \
name=My_App \
subdir= \
dir=$(AROSDIR)/Extras/My_App/Catalogs
Application directory
AROS/Contrib/my_app/
FlexCat
editFlexCat is a tool to create Amiga localization catalogs, as well as source and header files, out of catalog descriptions.
The version in AROS/tools is 2.4, with a developers.readme saying to treat it as freeware with source code, but not to fork it. The history file tells us that version 2.4 is from 28 November 1999. Not all websites referred to in the documentation still exist, but flexcat indeed supports the 2.4 version, with no mention of further development. Is a port a fork? If not, does a former port become a fork e.g. just because AROS becomes 68k? What if there originally was only one port, but someone else does another one - who is the forker? Maybe the author was just too imprecise and should have provided a definition of fork...
1 The AROS project stamps are for 7 March 2009, so there may well have been changes for the AROS version over the last decade.
2 The last release on Aminet is version 2.7 on 29 June 2010, by the project, which claims a copyright starting in 2002.
The original homepage is outdated. It's now a GPL licensed product which is maintained here. Of course the 2.7 distribution does not contain the source code, because the project is Open Source and the source code is available for everybody. The release archives contain binaries only for all supported platforms.
- Update the sources in AROS from a stable release of FlexCat
- Make it buildable again, perhaps my merging in commits from prior commits.
- C_h_orig.sd is no longer available in current FlexCat. Find a replacement which works with the AROS build-system.
- Bring back all fixes for AROS to the current trunk of FlexCat. Either bei joining the project on Sourceforge or sending it to the maintainer.
We would appreciate if you would join the team and commit the changes to the SVN repository on sourceforge.net. Just ask Jens Langer (damato#light-speed.de) to add you the list of developers.
Optionally: wait till the "vendor" branch is available in AROS repository and work with that.
Examples
edit/*
Copyright © 1995-2004, The AROS Development Team. All rights reserved.
$Id: locale.c 30794 2009-03-08 02:19:07Z neil $
*/
#include <exec/types.h>
#include <proto/locale.h>
#define CATCOMP_ARRAY
#include "strings.h"
#define CATALOG_NAME "AiRcOS.catalog"
#define CATALOG_VERSION 0
/*** Variables **************************************************************/
struct Catalog *catalog;
/*** Functions **************************************************************/
/* Main *********************************************************************/
CONST_STRPTR _(ULONG id)
{
if (LocaleBase != NULL && catalog != NULL)
{
return GetCatalogStr(catalog, id, CatCompArray[id].cca_Str);
}
else
{
return CatCompArray[id].cca_Str;
}
}
/* Setup ********************************************************************/
VOID Locale_Initialize(VOID)
{
if (LocaleBase != NULL)
{
catalog = OpenCatalog
(
NULL, CATALOG_NAME, OC_Version, CATALOG_VERSION, TAG_DONE
);
}
else
{
catalog = NULL;
}
}
VOID Locale_Deinitialize(VOID)
{
if(LocaleBase != NULL && catalog != NULL) CloseCatalog(catalog);
}
#ifndef _LOCALE_H_ #define _LOCALE_H_ /* Copyright © 2003-2004, The AROS Development Team. All rights reserved. $Id: locale.h 30794 2009-03-08 02:19:07Z neil $ */ #include <exec/types.h> #define CATCOMP_NUMBERS #include "strings.h" /*** Prototypes *************************************************************/ /* Main *********************************************************************/ CONST_STRPTR _(ULONG ID); /* Get a message, as a STRPTR */ #define __(id) ((IPTR) _(id)) /* Get a message, as an IPTR */ /* Setup ********************************************************************/ VOID Locale_Initialize(VOID); VOID Locale_Deinitialize(VOID); #endif /* _LOCALE_H_ */
References
edit/* constants for GetLocaleStr() */ #define DAY_1 1 /* Sunday */ #define DAY_2 2 /* Monday */ #define DAY_3 3 /* Tuesday */ #define DAY_4 4 /* Wednesday */ #define DAY_5 5 /* Thursday */ #define DAY_6 6 /* Friday */ #define DAY_7 7 /* Saturday */ #define ABDAY_1 8 /* Sun */ #define ABDAY_2 9 /* Mon */ #define ABDAY_3 10 /* Tue */ #define ABDAY_4 11 /* Wed */ #define ABDAY_5 12 /* Thu */ #define ABDAY_6 13 /* Fri */ #define ABDAY_7 14 /* Sat */ #define MON_1 15 /* January */ #define MON_2 16 /* February */ #define MON_3 17 /* March */ #define MON_4 18 /* April */ #define MON_5 19 /* May */ #define MON_6 20 /* June */ #define MON_7 21 /* July */ #define MON_8 22 /* August */ #define MON_9 23 /* September */ #define MON_10 24 /* October */ #define MON_11 25 /* November */ #define MON_12 26 /* December */ #define ABMON_1 27 /* Jan */ #define ABMON_2 28 /* Feb */ #define ABMON_3 29 /* Mar */ #define ABMON_4 30 /* Apr */ #define ABMON_5 31 /* May */ #define ABMON_6 32 /* Jun */ #define ABMON_7 33 /* Jul */ #define ABMON_8 34 /* Aug */ #define ABMON_9 35 /* Sep */ #define ABMON_10 36 /* Oct */ #define ABMON_11 37 /* Nov */ #define ABMON_12 38 /* Dec */ #define YESSTR 39 /* affirmative response for yes/no queries */ #define NOSTR 40 /* negative response for yes/no queries */ #define AM_STR 41 /* AM */ #define PM_STR 42 /* PM */ #define SOFTHYPHEN 43 /* soft hyphenation */ #define HARDHYPHEN 44 /* hard hyphenation */ #define OPENQUOTE 45 /* start of quoted block */ #define CLOSEQUOTE 46 /* end of quoted block */ #define YESTERDAYSTR 47 /* Yesterday */ #define TODAYSTR 48 /* Today */ #define TOMORROWSTR 49 /* Tomorrow */ #define FUTURESTR 50 /* Future */ #define MAXSTRMSG 51 /* current number of defined strings */ /* This structure must only be allocated by locale.library and is READ-ONLY! */ struct Locale { STRPTR loc_LocaleName; /* locale's name */ STRPTR loc_LanguageName; /* language of this locale */ STRPTR loc_PrefLanguages[10]; /* preferred languages */ ULONG loc_Flags; /* always 0 for now */ ULONG loc_CodeSet; /* always 0 for now */ ULONG loc_CountryCode; /* user's country code */ ULONG loc_TelephoneCode; /* country's telephone code */ LONG loc_GMTOffset; /* minutes from GMT */ UBYTE loc_MeasuringSystem; /* what measuring system? */ UBYTE loc_CalendarType; /* what calendar type? */ UBYTE loc_Reserved0[2]; STRPTR loc_DateTimeFormat; /* regular date & time format */ STRPTR loc_DateFormat; /* date format by itself */ STRPTR loc_TimeFormat; /* time format by itself */ STRPTR loc_ShortDateTimeFormat; /* short date & time format */ STRPTR loc_ShortDateFormat; /* short date format by itself */ STRPTR loc_ShortTimeFormat; /* short time format by itself */ /* for numeric values */ STRPTR loc_DecimalPoint; /* character before the decimals */ STRPTR loc_GroupSeparator; /* separates groups of digits */ STRPTR loc_FracGroupSeparator; /* separates groups of digits */ UBYTE *loc_Grouping; /* size of each group */ UBYTE *loc_FracGrouping; /* size of each group */ /* for monetary values */ STRPTR loc_MonDecimalPoint; STRPTR loc_MonGroupSeparator; STRPTR loc_MonFracGroupSeparator; UBYTE *loc_MonGrouping; UBYTE *loc_MonFracGrouping; UBYTE loc_MonFracDigits; /* digits after the decimal point */ UBYTE loc_MonIntFracDigits; /* for international representation */ UBYTE loc_Reserved1[2]; /* for currency symbols */ STRPTR loc_MonCS; /* currency symbol */ STRPTR loc_MonSmallCS; /* symbol for small amounts */ STRPTR loc_MonIntCS; /* international (ISO 4217) code */ /* for positive monetary values */ STRPTR loc_MonPositiveSign; /* indicate positive money value */ UBYTE loc_MonPositiveSpaceSep; /* determine if separated by space */ UBYTE loc_MonPositiveSignPos; /* position of positive sign */ UBYTE loc_MonPositiveCSPos; /* position of currency symbol */ UBYTE loc_Reserved2; /* for negative monetary values */ STRPTR loc_MonNegativeSign; /* indicate negative money value */ UBYTE loc_MonNegativeSpaceSep; /* determine if separated by space */ UBYTE loc_MonNegativeSignPos; /* position of negative sign */ UBYTE loc_MonNegativeCSPos; /* position of currency symbol */ UBYTE loc_Reserved3; }; /* constants for Locale.loc_MeasuringSystem */ #define MS_ISO 0 /* international metric system */ #define MS_AMERICAN 1 /* american system */ #define MS_IMPERIAL 2 /* imperial system */ #define MS_BRITISH 3 /* british system */ /* constants for Locale.loc_CalendarType */ #define CT_7SUN 0 /* 7 days a week, Sunday is the first day */ #define CT_7MON 1 /* 7 days a week, Monday is the first day */ #define CT_7TUE 2 /* 7 days a week, Tuesday is the first day */ #define CT_7WED 3 /* 7 days a week, Wednesday is the first day */ #define CT_7THU 4 /* 7 days a week, Thursday is the first day */ #define CT_7FRI 5 /* 7 days a week, Friday is the first day */ #define CT_7SAT 6 /* 7 days a week, Saturday is the first day */ /* constants for Locale.loc_MonPositiveSpaceSep and Locale.loc_MonNegativeSpaceSep */ #define SS_NOSPACE 0 /* cur. symbol is NOT separated from value with a space */ #define SS_SPACE 1 /* cur. symbol IS separated from value with a space */ /* constants for Locale.loc_MonPositiveSignPos and Locale.loc_MonNegativeSignPos */ #define SP_PARENS 0 /* () surround the quantity and currency_symbol */ #define SP_PREC_ALL 1 /* sign string comes before amount and symbol */ #define SP_SUCC_ALL 2 /* sign string comes after amount and symbol */ #define SP_PREC_CURR 3 /* sign string comes right before currency symbol */ #define SP_SUCC_CURR 4 /* sign string comes right after currency symbol */ /* constants for Locale.loc_MonPositiveCSPos and Locale.loc_MonNegativeCSPos */ #define CSP_PRECEDES 0 /* currency symbol comes before value */ #define CSP_SUCCEEDS 1 /* currency symbol comes after value */ /* elements of the byte arrays pointed to by: * Locale.loc_Grouping * Locale.loc_FracGrouping * Locale.loc_MonGrouping * Locale.loc_MonFracGrouping * are interpreted as follows: * * 255 indicates that no further grouping is to be performed * 0 indicates that the previous element is to be repeatedly used for the remainder of the digits * <other> the number of digits that comprises the current group */ /* This structure must only be allocated by locale.library and is READ-ONLY! */ struct Catalog { struct Node cat_Link; /* for internal linkage */ UWORD cat_Pad; /* to longword align */ STRPTR cat_Language; /* language of the catalog */ ULONG cat_CodeSet; /* currently always 0 */ UWORD cat_Version; /* version of the catalog */ UWORD cat_Revision; /* revision of the catalog */ };
void CloseCatalog(struct Catalog *catalog) (A0) void CloseLocale(struct Locale *locale) (A0) ULONG ConvToLower(const struct Locale *locale, ULONG character) (A0, D0) ULONG ConvToUpper(const struct Locale *locale, ULONG character) (A0, D0) void FormatDate(const struct Locale *locale, CONST_STRPTR formatString, const struct DateStamp *date, const struct Hook *hook) (A0, A1, A2, A3) APTR FormatString(const struct Locale *locale, CONST_STRPTR fmtTemplate, CONST_APTR dataStream, const struct Hook *putCharFunc) (A0, A1, A2, A3) CONST_STRPTR GetCatalogStr(const struct Catalog *catalog, ULONG stringNum, CONST_STRPTR defaultString) (A0, D0, A1) CONST_STRPTR GetLocaleStr(const struct Locale *locale, ULONG stringNum) (A0, D0) ULONG IsAlNum(const struct Locale *locale, ULONG character) (A0, D0) ULONG IsAlpha(const struct Locale *locale, ULONG character) (A0, D0) ULONG IsCntrl(const struct Locale *locale, ULONG character) (A0, D0) ULONG IsDigit(const struct Locale *locale, ULONG character) (A0, D0) ULONG IsGraph(const struct Locale *locale, ULONG character) (A0, D0) ULONG IsLower(const struct Locale *locale, ULONG character) (A0, D0) ULONG IsPrint(const struct Locale *locale, ULONG character) (A0, D0) ULONG IsPunct(const struct Locale *locale, ULONG character) (A0, D0) ULONG IsSpace(const struct Locale *locale, ULONG character) (A0, D0) ULONG IsUpper(const struct Locale *locale, ULONG character) (A0, D0) ULONG IsXDigit(const struct Locale *locale, ULONG character) (A0, D0) struct Catalog *OpenCatalogA(const struct Locale *locale, CONST_STRPTR name, const struct TagItem *tags) (A0, A1, A2) struct Locale *OpenLocale(CONST_STRPTR name) (A0) BOOL ParseDate(struct Locale *locale, struct DateStamp *date, CONST_STRPTR fmtTemplate, struct Hook *getCharFunc) (A0, A1, A2, A3) struct Locale *LocalePrefsUpdate(struct Locale *locale) (A0) ULONG StrConvert(const struct Locale *locale, CONST_STRPTR string, APTR buffer, ULONG bufferSize, ULONG type) (A0, A1, A2, D0, D1) LONG StrnCmp(const struct Locale *locale, CONST_STRPTR string1, CONST_STRPTR string2, LONG length, ULONG type) (A0, A1, A2, D0, D1) private APTR LocRawDoFmt(CONST_STRPTR FormatString, APTR DataStream, VOID_FUNC PutChProc, APTR PutChData) (A0, A1, A2, A3) LONG LocStrnicmp(CONST_STRPTR string1, CONST_STRPTR string2, LONG length) (A0, A1, D0) LONG LocStricmp(CONST_STRPTR string1, CONST_STRPTR string2) (A0, A1) ULONG LocToLower(ULONG character) (D0) ULONG LocToUpper(ULONG character) (D0) LONG LocDateToStr(struct DateTime *datetime) (D1) LONG LocStrToDate(struct DateTime *datetime) (D1) CONST_STRPTR LocDosGetLocalizedString(LONG stringNum) (D1)