Prusa-Firmware/Firmware/language.h

191 lines
6.2 KiB
C
Raw Normal View History

/** @file */
//language.h
2016-07-22 13:28:01 +00:00
#ifndef LANGUAGE_H
#define LANGUAGE_H
2018-06-21 17:58:13 +00:00
#include "config.h"
2020-09-11 13:12:49 +00:00
#include "macros.h"
#include <inttypes.h>
2020-01-31 13:47:44 +00:00
#ifdef DEBUG_SEC_LANG
#include <stdio.h>
#endif //DEBUG_SEC_LANG
2016-07-22 13:28:01 +00:00
#define PROTOCOL_VERSION "1.0"
#ifndef CUSTOM_MENDEL_NAME
2016-07-22 13:28:01 +00:00
#define MACHINE_NAME "Mendel"
#endif
#ifndef MACHINE_UUID
#define MACHINE_UUID "00000000-0000-0000-0000-000000000000"
#endif
#if (LANG_MODE == 0) //primary language only
#define PROGMEM_I2 __attribute__((section(".progmem0")))
#define PROGMEM_I1 __attribute__((section(".progmem1")))
#define PROGMEM_N1 __attribute__((section(".progmem2")))
#define _I(s) (__extension__({static const char __c[] PROGMEM_I1 = s; &__c[0];}))
#define ISTR(s) (s) // declare a translatable string
#define _i(s) _I(s) // declare a translatable string and return the translated form
#define _T(s) (s) // return translated string from reference
#define _O(s) (s) // return original (untranslated) string from reference
#else //(LANG_MODE == 0)
// section .loc_sec (originaly .progmem0) will be used for localized translated strings
#define PROGMEM_I2 __attribute__((section(".loc_sec")))
// section .loc_pri (originaly .progmem1) will be used for localized strings in english
#define PROGMEM_I1 __attribute__((section(".loc_pri")))
// section .noloc (originaly progmem2) will be used for not localized strings in english
#define PROGMEM_N1 __attribute__((section(".noloc")))
2018-05-30 13:07:24 +00:00
#define _I(s) (__extension__({static const char __c[] PROGMEM_I1 = "\xff\xff" s; &__c[0];}))
2018-05-30 12:53:14 +00:00
#define ISTR(s) "\xff\xff" s
#define _i(s) lang_get_translation(_I(s))
#define _T(s) lang_get_translation(s)
#define _O(s) (s + 2)
#endif //(LANG_MODE == 0)
#define _N(s) (__extension__({static const char __c[] PROGMEM_N1 = s; &__c[0];}))
#define _n(s) _N(s) // declare and return untranslated string
#define _R(s) (s) // return reference to translatable string (for warning suppression)
/** @brief lang_table_header_t structure - (size= 16byte) */
typedef struct
{
uint32_t magic; //+0
uint16_t size; //+4
uint16_t count; //+6
uint16_t checksum; //+8
uint16_t code; //+10
uint32_t signature; //+12
} lang_table_header_t;
/** @brief lang_table_t structure - (size= 16byte + 2*count) */
typedef struct
{
lang_table_header_t header;
uint16_t table[];
} lang_table_t;
/** @name Language indices into their particular symbol tables.*/
///@{
#define LANG_ID_PRI 0
#define LANG_ID_SEC 1
///@}
/** @def LANG_ID_FORCE_SELECTION
* @brief Language is not defined and it shall be selected from the menu.*/
#define LANG_ID_FORCE_SELECTION 254
/** @def LANG_ID_UNDEFINED
* @brief Language is not defined on a virgin RAMBo board. */
#define LANG_ID_UNDEFINED 255
2016-07-22 13:28:01 +00:00
/** @def LANG_ID_DEFAULT
* @brief Default language ID, if no language is selected. */
#define LANG_ID_DEFAULT LANG_ID_PRI
2016-07-22 13:28:01 +00:00
/** @def LANG_MAGIC
* @brief Magic number at begin of lang table. */
#define LANG_MAGIC 0x4bb45aa5
/** @name Language codes (ISO639-1)*/
///@{
#define LANG_CODE_XX 0x3f3f //!<'??'
#define LANG_CODE_EN 0x656e //!<'en'
#define LANG_CODE_CZ 0x6373 //!<'cs'
#define LANG_CODE_DE 0x6465 //!<'de'
#define LANG_CODE_ES 0x6573 //!<'es'
#define LANG_CODE_FR 0x6672 //!<'fr'
#define LANG_CODE_IT 0x6974 //!<'it'
#define LANG_CODE_PL 0x706c //!<'pl'
#ifdef COMMUNITY_LANGUAGE_SUPPORT //Community language support
#ifdef COMMUNITY_LANG_GROUP1_NL
#define LANG_CODE_NL 0x6e6c //!<'nl'
#endif // COMMUNITY_LANG_GROUP1_NL
2021-12-21 13:33:35 +00:00
#ifdef COMMUNITY_LANG_GROUP1_SV
#define LANG_CODE_SV 0x7376 //!<'sv'
#endif // COMMUNITY_LANG_GROUP1_SV
2022-02-22 10:56:01 +00:00
#ifdef COMMUNITY_LANG_GROUP1_NO
#define LANG_CODE_NO 0x6E6F //!<'no'
#endif // COMMUNITY_LANG_GROUP1_NO
2021-12-21 14:15:23 +00:00
#ifdef COMMUNITY_LANG_GROUP1_DA
#define LANG_CODE_DA 0x6461 //!<'da'
#endif // COMMUNITY_LANG_GROUP1_DA
2021-12-21 14:24:06 +00:00
#ifdef COMMUNITY_LANG_GROUP1_SL
#define LANG_CODE_SL 0x736C //!<'sl'
#endif // COMMUNITY_LANG_GROUP1_SL
2021-12-21 14:28:33 +00:00
#ifdef COMMUNITY_LANG_GROUP1_HU
#define LANG_CODE_HU 0x6875 //!<'hu'
#endif // COMMUNITY_LANG_GROUP1_HU
2021-12-21 14:32:54 +00:00
#ifdef COMMUNITY_LANG_GROUP1_LB
#define LANG_CODE_LB 0x6C62 //!<'lb'
#endif // COMMUNITY_LANG_GROUP1_LB
2021-12-21 14:36:34 +00:00
#ifdef COMMUNITY_LANG_GROUP1_HR
#define LANG_CODE_HR 0x6872 //!<'hr'
#endif // COMMUNITY_LANG_GROUP1_HR
2022-01-03 14:00:45 +00:00
#ifdef COMMUNITY_LANG_GROUP1_LT
#define LANG_CODE_LT 0x6C74 //!<'lt'
#endif // COMMUNITY_LANG_GROUP1_LT
2022-02-10 18:01:04 +00:00
#ifdef COMMUNITY_LANG_GROUP1_SK
#define LANG_CODE_SK 0x736b //!<'sk'
#endif // COMMUNITY_LANG_GROUP1_SK
2022-01-12 09:09:01 +00:00
#ifdef COMMUNITY_LANG_GROUP1_RO
#define LANG_CODE_RO 0x726F //!<'ro'
#endif // COMMUNITY_LANG_GROUP1_RO
//Use the 3 lines below as a template and replace 'QR', '0X7172' and 'qr'
//#ifdef COMMUNITY_LANG_GROUP1_QR
//#define LANG_CODE_QR 0x7172 //!<'qr'
//#endif // COMMUNITY_LANG_GROUP1_QR
#endif // COMMUNITY_LANGUAGE_SUPPORT
///@}
2016-07-22 13:28:01 +00:00
#if defined(__cplusplus)
extern "C" {
#endif //defined(__cplusplus)
/** @brief Currectly active language selection.*/
extern uint8_t lang_selected;
#if (LANG_MODE != 0)
extern const char _SEC_LANG[LANG_SIZE_RESERVED];
extern const char* lang_get_translation(const char* s);
New PO-based language translation support (#3471) * lang: Add a PO language extractor with FW metadata support Implement a straight-to-po language extractor which supports our custom language requirements: - _i/_I/ISTR for text string definitions - _T for catalog translations (with back-reference support) - //// EOL comments with: - MSG_ catalog entry name identifiers - c=X r=Y annotations for screen dimensioning checks - Crude support for commented lines All source locations are correctly referenced in the PO, with the metadata colleted in the comment for further processing. Several checks are implemented already during extraction: - Correct catalog name assignment (no duplicates) - Metadata checks for each entry Further checks will be implemented by directly checking the translated PO file. Requires "polib" and "regex" python modules. * lang: Adapt lang-check to work directly on PO/POT files * lang: Allow lang-extract to generate stable (pre-sorted) output directly * lang: Further extend lang-extract consistency/error checking - Do not parse inside preprocessor conditionals - Distinguish between references and definitions - Warn about missing references and definitions * lang: lang-extract: warn about incorrect PROGMEM assignments Check that ISTR is used along with PROGMEM_I1 in an attempt to spot useless translated catalogs. * lang: lang-extract: Improved handling of same-line translations Correctly reference metadata on same-line translations. * lang: lang-extract: Handle _O as a cat-ref https://github.com/prusa3d/Prusa-Firmware/pull/3434 * lang: lang-extract: Warn about unused catalog definitions * lang: lang-extract: Allow propagating translation comments via // The definition: code //// definition [// comment] will check [definition] as before, but blindly accumulate // comment. The comment is then re-appended back into the PO files for translators with the form: definition comment comment... * lang: Fix incorrect display definitions * lang: lang-extract: Check source encoding/charmap * lang: Translate the degree symbol * lang: Unbreak/cleanup DEBUG_SEC_LANG * lang: Improve meaning of comment * lang: Split charset conversions into an aux lib for future use * lang: Implement lang-map.py to extract the translation symbol map - Extracts the translatable symbol map for further use - Computes a stable "language signature" from the map itself - Optionally patches the binary update the symbols * lang: Check for translation recoding problems * lang: Implement a transliteration map to post-process translations TRANS_CHARS is now used to replace unavailable symbols to the source encoding, only while producing the language catalog. * lang: Handle/check character replacements in lang-check Filter the translation through TRANS_CHARS, so that the preview and length check are performed correctly for expanding replacements such as 'ß' to 'ss'. * lang: Implement lang-build.py to generate the final language catalog * Cleanup .gitignore * lang: Drop txt language files * lang: Remove outdated translation scripts and obsolete docs * lang: Update build scripts for new infrastructure * lang: [no] Integrate accents from po/new/no.po We now support accents natively * lang: Remove redundant directory po/new/ * lang: Fix encoding of LCD characters in PO files * lang: [hr] Fix wrapping in MSG_CRASH_DET_ONLY_IN_NORMAL * lang: Sort and reformat PO files for further massaging * lang: Switch to developer (dot) comments for PO metadata * lang: Allow the IGNORE annotation to skip extraction * lang: Fix missing/broken language metadata in sources * lang: Add update-pot.sh and regenerate po/Firmware.pot * lang: Add update-po.sh and refresh all PO files * lang: Add summary documentation about the new translation workflow * Add more ignored files * CI: Add new required dependencies to travis * lang: lang-build: Improve warning message "referenced" was really meaning that data is being duplicated. * lang: Respect the language order as defined in config.sh This correctly splits normal and community-made entries during language selection. * lang: More typos in the documentation * lang: Check for the maximum size of each language Each table needs to fit within LANG_SIZE_RESERVED * lang: Properly align _SEC_LANG to page boundaries ... instead of relying on _SEC_LANG_TABLE to calculate the offset * lang: Build support for dual-language hex files Detect the printer type by checking the current variant type. On printers with no xflash (MK2*), generate one hex file for each additional language file by patching the built-in secondary language table during the build process * lang: Mention lang-patchsec.py * lang: Use color() instead of tput for clarity * lang: Allow disabling terminal colors with NO_COLOR/TERM=dumb * lang: Consistent use of redirection in config.sh * lang: Stricter variant-type check for xflash support * lang: Output size stats when building double-language hex files * lang: Respect NO_COLOR in lang-check.py * lang: Check for repeated/incorrect annotations Catch errors such as "c=1 c=2" * lang: Correct MSG_SLIGHT_SKEW/MSG_SEVERE_SKEW annotations * lang: [it] Improve MSG_*_SKEW translation * lang: Use INTLHEX instead of OUTHEX_P/S for configuration We already have OUTHEX which is the compiled firmware. Use INTLHEX for the final internationalized firmware, which is less confusing. Also, assume it being a prefix for all generated hex files, which reduces the number of variables set. * lang: Move lang_map to lib.io for further use * lang: lang-check: Accept a firmware map file to suppress unused string warnings * lang: Use the map file to reduce useless warnings during fw-build * lang: lang-check: Also suppress unused empty annotations * lang: Fix MSG_MOVE_CARRIAGE_TO_THE_TOP_Z annotation Refresh pot file * lang: lang-check: Do not warn about same-word translations by default Do not warn when one-word translations such as "No" result in "No" also in other languages, since this is common in latin languages. Allow to re-enable the warning with --warn-same * lang: lang-build: Handle same-source/translation efficiently * lang: [it] Explicitly add On/Off/Reset/Wizard to suppress warnings Instead of displaying a warning, supress the warning and explicitly translate each entry using english (which is the common/acceptable word in these cases). * lang: [it] Suppress more warnings * lang: lang-check: Add intermediate "suggest" warning category Warnings in the "suggest" category as shown as [S] as based on pure speculation from the checking tool, such as the translation being significantly shorter than the original. As a result, they can be suppressed with --no-suggest * lang: Return translation status from lang-check - 0 if the translation only contains suggestions - 1 if the translation contains warnings or errors Check for the exit status in fw-build.sh, but do nothing at the moment except printing a non-fatal error. * lang: Remove "trim_trailing_whitespace=false" for po files PO files got cleaned up/rewritten. We can now ensure they stay consistent. * lang: [sv] Re-integrate changes from 70c73cb * lang: [no] Reintegrate changes from @pkg2000
2022-06-16 13:03:30 +00:00
#define _SEC_LANG_TABLE ((uint16_t)&_SEC_LANG)
#endif //(LANG_MODE != 0)
/** @brief selects language, eeprom is updated in case of success */
extern uint8_t lang_select(uint8_t lang);
/** @brief performs checksum test of secondary language data */
extern uint8_t lang_check(uint16_t addr);
/** @return total number of languages (primary + all in xflash) */
extern uint8_t lang_get_count(void);
/** @brief reads lang table header and offset in xflash or progmem */
extern uint8_t lang_get_header(uint8_t lang, lang_table_header_t* header, uint32_t* offset);
/** @brief reads lang code from xflash or progmem */
extern uint16_t lang_get_code(uint8_t lang);
/** @return localized language name (text for menu item) */
extern const char* lang_get_name_by_code(uint16_t code);
/** @brief reset language to "LANG_ID_FORCE_SELECTION", epprom is updated */
extern void lang_reset(void);
/** @retval 1 language is selected */
extern uint8_t lang_is_selected(void);
#ifdef DEBUG_SEC_LANG
extern const char* lang_get_sec_lang_str_by_id(uint16_t id);
extern uint16_t lang_print_sec_lang(FILE* out);
#endif //DEBUG_SEC_LANG
extern void lang_boot_update_start(uint8_t lang);
#if defined(__cplusplus)
}
#endif //defined(__cplusplus)
#define CAT2(_s1, _s2) _s1
#define CAT4(_s1, _s2, _s3, _s4) _s1
#include "messages.h"
2016-07-22 13:28:01 +00:00
#endif //LANGUAGE_H