Writing Localized Applications

locale.library (V38+) provides the AmigaOS internationalization system. This article covers the practical pattern for making an application multilingual.

Why localize?

Without system-level localization support, you need separate binary builds for each language. locale.library lets you write one binary that adapts to any user-selected language/country. The system ships with language and country preferences; your app reads translations from catalog files at runtime.

The localization pattern

struct Library *LocaleBase;
struct Locale  *locale;
struct Catalog *catalog;

LocaleBase = OpenLibrary("locale.library", 38);
locale   = OpenLocale(NULL);                          /* system default */
catalog  = OpenCatalog(locale, "myapp.catalog",
                       OC_BuiltInLanguage, "english",
                       OC_Version,        1,
                       TAG_DONE);

/* In code: */
STRPTR title = GetCatalogStr(catalog, MSG_APP_TITLE, "My Application");
STRPTR ok    = GetCatalogStr(catalog, MSG_OK_BUTTON, "OK");

Key rule: GetCatalogStr() always has an English fallback string. If the catalog isn't found (e.g., V37 system without locale.library), the app still works in English.

Catalog files

  1. Write a .cd (catalog description) file listing all strings with numbers and English text.
  2. Use CatComp (in NDK_3.1/SWToolkit3/CatComp) to compile .cd.catalog files for each language.
  3. Install catalogs in LOCALE:Catalogs/<language>/myapp.catalog.
  4. Generate C header with #define constants from the .cd file (CatComp does this).
; Example .cd file
;
MSG_APP_TITLE (1) "My Application"
MSG_OK_BUTTON (2) "OK"
MSG_FILE_MENU (3) "Project"

Self-loading catalogs on V37

The tutorial notes that locale.library is V38+, but you can add code to self-load catalogs on V37 machines. Check LocaleBase — if NULL, use English fallbacks throughout. See the NDK_3.1/Examples1/locale/ directory for a self-loading code example.

Character classification

locale-aware versions of standard C character functions:

LONG IsAlpha(LONG c);   /* locale-aware */
LONG IsDigit(LONG c);
LONG IsLower(LONG c);
LONG IsUpper(LONG c);
/* ... IsAlNum, IsCntrl, IsGraph, IsPrint, IsPunct, IsSpace, IsXDigit */

LONG ConvToLower(LONG c);
LONG ConvToUpper(LONG c);

All accept 32-bit characters, allowing future multi-byte character set support (Unicode, Cyrillic, etc.).

Date and string formatting

ULONG FormatDate(struct Locale *locale, STRPTR fmtString,
                  struct DateStamp *date, struct TagItem *tags);
ULONG FormatString(struct Locale *locale, STRPTR fmtString,
                   APTR dataStream, struct Hook *putCharFunc);

FormatDate supports locale-specific date formats. GetLocaleStr() returns built-in strings like day names, month names ("Sunday" through "Saturday", "January" through "December"), and system messages.

V40+ environment variable

Starting V40, locale.library maintains the Language environment variable containing the current default language name. Shell: Echo $Language.

See Also


Sources: Commodore-Amiga, Inc., "Locale Library" tutorial (1991-1993); David N. Junod, "DataTypes" tutorial. Raw: raw/tutorials/locale-datatypes-bullet.md Updated: 2026-08-04