From 17f4709adeb4d9159359d901b1743de56348e7e4 Mon Sep 17 00:00:00 2001 From: Haru Date: Tue, 17 May 2016 15:11:00 +0200 Subject: Added _$() macro to the script engine to mark a translatable string as format string - Strings passed to sprintf should use the _$() macro instead of _(), to generate the .pot translation template with a directive to correctly handle the % sign. - Strings passed through _() are instead explicitly marked as regular (non format) strings if they contain '%'. Signed-off-by: Haru --- src/map/script.c | 11 +++++++++-- src/map/script.h | 2 ++ src/plugins/generate-translations.c | 25 +++++++++++++++++++++---- 3 files changed, 32 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/map/script.c b/src/map/script.c index 40dafd2a5..926f19bf0 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -810,9 +810,12 @@ const char* parse_callfunc(const char* p, int require_paren, int is_custom) if (script->str_data[func].type == C_FUNC) { script->syntax.nested_call++; if (script->syntax.last_func != -1) { - if( script->str_data[func].val == script->buildin_lang_macro_offset ) { + if (script->str_data[func].val == script->buildin_lang_macro_offset) { script->syntax.lang_macro_active = true; macro = true; + } else if (script->str_data[func].val == script->buildin_lang_macro_fmtstring_offset) { + script->syntax.lang_macro_fmtstring_active = true; + macro = true; } } @@ -907,8 +910,10 @@ const char* parse_callfunc(const char* p, int require_paren, int is_custom) disp_error_message("parse_callfunc: expected ')' to close argument list",p); ++p; - if( script->str_data[func].val == script->buildin_lang_macro_offset ) + if (script->str_data[func].val == script->buildin_lang_macro_offset) script->syntax.lang_macro_active = false; + else if (script->str_data[func].val == script->buildin_lang_macro_fmtstring_offset) + script->syntax.lang_macro_fmtstring_active = false; } if (!macro) { @@ -20272,6 +20277,7 @@ bool script_add_builtin(const struct script_function *buildin, bool override) { else if( strcmp(buildin->name, "mes") == 0 ) script->buildin_mes_offset = script->buildin_count; else if( strcmp(buildin->name, "select") == 0 ) script->buildin_select_offset = script->buildin_count; else if( strcmp(buildin->name, "_") == 0 ) script->buildin_lang_macro_offset = script->buildin_count; + else if( strcmp(buildin->name, "_$") == 0 ) script->buildin_lang_macro_fmtstring_offset = script->buildin_count; offset = script->buildin_count; @@ -20877,6 +20883,7 @@ void script_parse_builtin(void) { BUILDIN_DEF(showscript, "s?"), BUILDIN_DEF(mergeitem,""), BUILDIN_DEF(_,"s"), + BUILDIN_DEF2(_, "_$", "s"), }; int i, len = ARRAYLENGTH(BUILDIN); RECREATE(script->buildin, char *, script->buildin_count + len); // Pre-alloc to speed up diff --git a/src/map/script.h b/src/map/script.h index 133c205a7..7811cd64e 100644 --- a/src/map/script.h +++ b/src/map/script.h @@ -503,6 +503,7 @@ struct script_syntax_data { int last_func; // buildin index of the last parsed function unsigned int nested_call; //Dont really know what to call this bool lang_macro_active; // Used to generate translation strings + bool lang_macro_fmtstring_active; // Used to generate translation strings struct DBMap *translation_db; //non-null if this npc has any translated strings to be linked }; @@ -624,6 +625,7 @@ struct script_interface { int buildin_mes_offset; int buildin_select_offset; int buildin_lang_macro_offset; + int buildin_lang_macro_fmtstring_offset; /* */ struct DBMap *translation_db;/* npc_name => DBMap (strings) */ VECTOR_DECL(uint8 *) translation_buf; diff --git a/src/plugins/generate-translations.c b/src/plugins/generate-translations.c index daa3349fa..7928fec9c 100644 --- a/src/plugins/generate-translations.c +++ b/src/plugins/generate-translations.c @@ -94,6 +94,8 @@ CMDLINEARG(generatetranslations) void script_add_translatable_string_posthook(const struct script_string_buf *string, const char *start_point) { bool duplicate = true; + bool is_translatable_string = false; + bool is_translatable_fmtstring = false; /* When exporting we don't know what is a translation and what isn't */ if (lang_export_fp != NULL && VECTOR_LENGTH(*string) > 1) { @@ -108,13 +110,26 @@ void script_add_translatable_string_posthook(const struct script_string_buf *str } } - if (lang_export_fp != NULL && !duplicate && - ( ( ( script->syntax.last_func == script->buildin_mes_offset || - script->syntax.last_func == script->buildin_select_offset ) - ) || script->syntax.lang_macro_active ) ) { + if (!duplicate) { + if (script->syntax.last_func == script->buildin_mes_offset + || script->syntax.last_func == script->buildin_select_offset + || script->syntax.lang_macro_active + ) { + is_translatable_string = true; + } else if (script->syntax.lang_macro_fmtstring_active) { + is_translatable_fmtstring = true; + } + } + + if (lang_export_fp != NULL && (is_translatable_string || is_translatable_fmtstring)) { const char *line_start = start_point; const char *line_end = start_point; int line_length; + bool has_percent_sign = false; + + if (!is_translatable_fmtstring && strchr(VECTOR_DATA(*string), '%') != NULL) { + has_percent_sign = true; + } while( line_start > script->parser_current_src ) { if( *line_start != '\n' ) @@ -145,11 +160,13 @@ void script_add_translatable_string_posthook(const struct script_string_buf *str fprintf(lang_export_fp, "\n#: %s\n" "# %s\n" "msgctxt \"%s\"\n" + "%s" "msgid \"%s\"\n" "msgstr \"\"\n", script->parser_current_file ? script->parser_current_file : "Unknown File", VECTOR_DATA(lang_export_line_buf), script->parser_current_npc_name ? script->parser_current_npc_name : "Unknown NPC", + is_translatable_fmtstring ? "#, c-format\n" : (has_percent_sign ? "#, no-c-format\n" : ""), VECTOR_DATA(lang_export_escaped_buf) ); VECTOR_TRUNCATE(lang_export_line_buf); -- cgit v1.2.3-70-g09d2