Translation & Localization
Translation & Localization System
Developer guide for the Bus Pirate translation system — how strings are managed, translated, and selected at runtime.
How T_ Constants Work
Every user-facing string in Bus Pirate firmware is represented by a T_ constant defined in the auto-generated src/translation/base.h. These constants are members of the enum T_translations:
enum T_translations{
T_ON=0,
T_OFF,
T_GND,
T_INPUT,
T_OUTPUT,
T_EXIT,
// ... hundreds of T_ constants ...
T_LAST_ITEM_ALWAYS_AT_THE_END // compiler sentinel
};Do NOT edit
base.hdirectly. It is auto-generated byjson2h.pyfrom parsingsrc/translation/en-us.hand the templatesrc/translation/templates/base.ht.
At runtime, GET_T(T_CONSTANT) retrieves the localized string for the currently selected language:
printf("%s%s%s\r\n", ui_term_color_info(), GET_T(T_USE_PREVIOUS_SETTINGS), ui_term_color_reset());The GET_T() implementation (in src/translation/base.c) provides automatic fallback — if a translation is missing (NULL), the English string is returned instead:
const char* GET_T(enum T_translations index) {
const char* result = NULL;
if (index < T_LAST_ITEM_ALWAYS_AT_THE_END) {
translation_table_t* table = translation_tables[current_language];
result = (*table)[index];
}
// fallback to en-US if no translated string was provided
if (result == NULL) {
translation_table_t* table = translation_tables[language_idx_en_us];
result = (*table)[index];
}
return result;
}Adding a New String
Add the string to
src/translation/en-us.h— this is the English source of truth. Each entry maps aT_constant to its English text:static char const * const en_us[]={ [T_ON]="ON", [T_OFF]="OFF", [T_USE_PREVIOUS_SETTINGS]="Use previous settings?", // add your new string here: [T_YOUR_NEW_KEY]="Your new user-facing string", };Run
json2h.pyfrom the translation directory to regeneratebase.h:cd src/translation && python json2h.pyThis parses
en-us.h, extracts allT_keys, and regeneratesbase.h(fromtemplates/base.ht) with the updated enum.Use
GET_T(T_YOUR_NEW_KEY)in your code wherever the string should appear.
Translations for other languages are optional — GET_T() will fall back to the English string automatically.
The 0 Placeholder Convention
When defining bp_val_constraint_t structs during development, use 0 for translation key fields that don’t have a real T_ constant yet:
static const bp_val_constraint_t dummy1_speed_range = {
.type = BP_VAL_UINT32,
.u = { .min = 1, .max = 1000, .def = 100 },
.prompt = 0, // T_ key placeholder — add real key later
.hint = 0, // T_ key placeholder — add real key later
};This is safe — since T_ON=0 is a valid enum value, the system handles it gracefully. The same convention applies to choice labels:
static const bp_val_choice_t dummy1_output_choices[] = {
{ "push-pull", "pp", 0, 0 }, // label=0 → placeholder
{ "open-drain", "od", 0, 1 },
};Replace 0 with a real T_ key once the translation string is finalized.
Adding a New Language
The full process is documented in src/translation/base.c. Here is a summary:
Add a language name string to
en-us.h. The enum name must begin withT_CONFIG_LANGUAGE_:[T_CONFIG_LANGUAGE_ESPERANTO] = "Lingvo - esperanto (Mondo)",Create a
.jsontranslation file insrc/translation/templates/using the IETF language tag (e.g.,eo-001.json). Start from an existing file as a template. Untranslated entries can be omitted or set tonull— they will fall back to English.Add the language index to
base.ht(src/translation/templates/base.ht):typedef enum _language_idx_t { language_idx_en_us, language_idx_pl_pl, language_idx_bs_latn_ba, language_idx_it_it, language_idx_eo_001, // new language COUNT_OF_LANGUAGE_IDX, } language_idx_t;Run
json2h.pyto regeneratebase.hand produce the new.hfile from the.json:cd src/translation && python json2h.pyRegister the language in
base.c. Include the generated header and add entries to the translation table andget_language_name():#include "translation/eo-001.h" static const translation_table_t* translation_tables[COUNT_OF_LANGUAGE_IDX] = { [language_idx_en_us] = &en_us, [language_idx_pl_pl] = &pl_pl, [language_idx_bs_latn_ba] = &bs_ba, [language_idx_it_it] = &it_it, [language_idx_eo_001] = &eo_001, // new };Build and test to verify the new language compiles and displays correctly.
Translation Toolchain
| Tool | Location | Purpose |
|---|---|---|
json2h.py | src/translation/json2h.py | Parses en-us.h, generates en-us.json, regenerates base.h from base.ht, and converts each .json translation to a .h file |
check_translations.py | check_translations.py | Validates all translation files match the base definitions |
base.ht | src/translation/templates/base.ht | Template for base.h generation — contains the language_idx_t enum and the %%%enum_list%%% placeholder |
Language Index
The language_idx_t enum in base.h (generated from base.ht) defines the available languages:
typedef enum _language_idx_t {
language_idx_en_us,
language_idx_pl_pl,
language_idx_bs_latn_ba,
language_idx_it_it,
COUNT_OF_LANGUAGE_IDX,
} language_idx_t;| Enum Value | Language |
|---|---|
language_idx_en_us | English (US) |
language_idx_pl_pl | Polish |
language_idx_bs_latn_ba | Bosnian (Latin) |
language_idx_it_it | Italian |
- Language selection is stored in
system_config.terminal_language translation_set()switches the active language at runtimeGET_T()indexes into the correct translation table based oncurrent_language- Each translation table is a
const char* constarray indexed byT_enum values, stored in ROM
Translation File Structure
Each language has a header file that defines a translation array:
// en-us.h — English source of truth
#include "translation/base.h"
static char const * const en_us[]={
[T_ON]="ON",
[T_OFF]="OFF",
[T_GND]="GND",
[T_INPUT]="INPUT",
[T_OUTPUT]="OUTPUT",
[T_EXIT]="Exit",
// ...
};For non-English languages, the generated .h file has the same structure but with translated values. Missing entries are left as NULL and GET_T() falls back to the English string.
Related Documentation
- new_command_guide.md — Adding new commands to Bus Pirate
- new_mode_guide.md — Adding new protocol modes
- bp_cmd_data_types.md — Command data types and constraints
- Source:
src/translation/base.h,src/translation/en-us.h,src/translation/base.c,check_translations.py