Skip to content

Support GNU gettext message catalogs (.mo) in dcgettext(), dcngettext(), and bindtextdomain() #530

Description

@bertysentry

Current state

Since #80 / PR #527, dcgettext(), dcngettext(), and bindtextdomain() exist but perform no actual translation: text is returned untranslated and dcngettext() applies the English plural rule. This matches gawk built without gettext — gawk's own test suite accepts this: its nlstringtest target compares against nlstringtest-nogettext.ok first, and Jawk's GawkLocaleIT.test_nlstringtest passes against that baseline.

Proposed feature

Implement real message catalog support so the i18n functions translate like gawk built with gettext:

  • Parse the GNU .mo binary catalog format (simple: magic 0x950412de, offset tables of original/translated strings, optional hash table).
  • Resolve the catalog path as gettext does: <binding directory>/<locale>/LC_MESSAGES/<domain>.mo, with the binding from bindtextdomain(), the domain from the argument or TEXTDOMAIN, and the locale from the CLI --locale option / JVM default locale (gawk uses GAWKLOCALE/LC_ALL).
  • Plural selection in dcngettext() per the catalog's Plural-Forms: header, which requires evaluating its small C-like expression (e.g. nplurals=2; plural=(n > 1); for French).
  • Note the interaction with Reincorporate Printf4J into Jawk to fully implement AWK's printf #528: translated format strings commonly use positional conversions (%2$s remplace %1$s. in gawk's French catalog), so full fidelity also needs positional printf argument support.
  • Sandbox: catalog loading reads files at runtime, so it must respect SandboxedAwk restrictions (probably disabled under sandbox).

Acceptance test

gawk's own fixture: running nlstringtest.awk with the compiled catalog test/fr/LC_MESSAGES/nlstringtest.mo (from the gawk source tree) under a French locale must produce the translated nlstringtest.ok:

2 morceaux de gateau
%2$s remplace %1$s.
%2$s remplace %1$s.

EUR remplace FF.

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions