91 lines
2.5 KiB
Markdown
91 lines
2.5 KiB
Markdown
# 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
|
|
|
|
```c
|
|
extern localemanager_t LOCALE;
|
|
// LOCALE.locale -- currently active localeinfo_t
|
|
// LOCALE.entry -- locked assetentry_t for the current PO file
|
|
```
|
|
|
|
## Initialise and switch locale
|
|
|
|
```c
|
|
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
|
|
|
|
```c
|
|
// 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`)
|
|
|
|
```c
|
|
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:
|
|
|
|
```c
|
|
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.
|