Files
dusk/.claude/locale.md
T
2026-06-16 10:15:59 -05:00

2.5 KiB

Locale System

Source: src/dusk/locale/, asset loader at src/dusk/asset/loader/locale/

Overview

The locale system loads Gettext PO files from the asset archive and provides string lookup with plural-form support and printf-style argument substitution. Locale files live in locale/ inside dusk.dsk.

Global state

extern localemanager_t LOCALE;
// LOCALE.locale  -- currently active localeinfo_t
// LOCALE.entry   -- locked assetentry_t for the current PO file

Initialise and switch locale

errorret_t localeManagerInit();
// Defaults to LOCALE_EN_US (locale/en_US.po).

errorret_t localeManagerSetLocale(const localeinfo_t *locale);
// Unlocks the old entry, loads and locks the new one.
// Blocks until the new PO file is fully parsed.

void localeManagerDispose();

Getting a localised string

// Variadic (printf-style args):
localeManagerGetText(id, buffer, bufferSize, plural, ...);

// With a pre-built args array:
localeManagerGetTextArgs(id, buffer, bufferSize, plural, args, argCount);

Both are macros that delegate to assetLocaleGetStringWithVA / assetLocaleGetStringWithArgs.

  • id -- message ID string (the English key in the PO file)
  • plural -- plural index (0 for singular, 1+ per PO plural rules)
  • buffer -- destination char_t array
  • bufferSize -- size of the destination buffer
  • ... -- format arguments matching %s, %d, %f placeholders

Locale descriptors (localeinfo_t)

typedef struct {
  const char_t *name;  // e.g. "en-US"
  const char_t *file;  // path inside dusk.dsk, e.g. "locale/en_US.po"
} localeinfo_t;

The built-in descriptor is:

static const localeinfo_t LOCALE_EN_US = {
  .name = "en-US",
  .file = "locale/en_US.po",
};

Add new locales by declaring another localeinfo_t constant and shipping the corresponding .po file in the asset archive.

PO file format notes

The loader (assetlocaleloader) parses standard Gettext PO syntax:

  • msgid / msgstr pairs
  • msgid_plural / msgstr[n] for plural forms
  • The Plural-Forms: header (e.g. nplurals=2; plural=(n != 1);) is parsed and evaluated at lookup time

Argument substitution uses %s, %d, %f placeholders (not standard Gettext %1 positional args).

Adding a new locale

  1. Create locale/<lang_COUNTRY>.po with a valid Plural-Forms: header and the translated msgid/msgstr entries.
  2. Pack it into dusk.dsk.
  3. Add a localeinfo_t constant in localeinfo.h.
  4. Call localeManagerSetLocale() with the new descriptor to activate.