liblzma: Mark string conversion messages as translatable

This commit is contained in:
Lasse Collin 2025-01-20 16:31:49 +02:00
parent f49d7413d9
commit f2e2b267ca
No known key found for this signature in database
GPG Key ID: 38EE757D69184620
2 changed files with 59 additions and 38 deletions

View File

@ -15,3 +15,4 @@ src/xz/suffix.c
src/xz/util.c src/xz/util.c
src/lzmainfo/lzmainfo.c src/lzmainfo/lzmainfo.c
src/common/tuklib_exit.c src/common/tuklib_exit.c
src/liblzma/common/string_conversion.c

View File

@ -12,6 +12,11 @@
#include "filter_common.h" #include "filter_common.h"
// liblzma itself doesn't use gettext to translate messages.
// Mark the strings still so that xz can translate them.
#define N_(msgid) msgid
///////////////////// /////////////////////
// String building // // String building //
///////////////////// /////////////////////
@ -319,7 +324,7 @@ parse_lzma12_preset(const char **const str, const char *str_end,
assert(*str < str_end); assert(*str < str_end);
if (!(**str >= '0' && **str <= '9')) if (!(**str >= '0' && **str <= '9'))
return "Unsupported preset"; return N_("Unsupported preset");
*preset = (uint32_t)(**str - '0'); *preset = (uint32_t)(**str - '0');
@ -331,7 +336,7 @@ parse_lzma12_preset(const char **const str, const char *str_end,
break; break;
default: default:
return "Unsupported flag in the preset"; return N_("Unsupported flag in the preset");
} }
} }
@ -350,7 +355,7 @@ set_lzma12_preset(const char **const str, const char *str_end,
lzma_options_lzma *opts = filter_options; lzma_options_lzma *opts = filter_options;
if (lzma_lzma_preset(opts, preset)) if (lzma_lzma_preset(opts, preset))
return "Unsupported preset"; return N_("Unsupported preset");
return NULL; return NULL;
} }
@ -442,7 +447,7 @@ parse_lzma12(const char **const str, const char *str_end, void *filter_options)
return errmsg; return errmsg;
if (opts->lc + opts->lp > LZMA_LCLP_MAX) if (opts->lc + opts->lp > LZMA_LCLP_MAX)
return "The sum of lc and lp must not exceed 4"; return N_("The sum of lc and lp must not exceed 4");
return NULL; return NULL;
} }
@ -578,21 +583,21 @@ parse_options(const char **const str, const char *str_end,
// Fail if the '=' wasn't found or the option name is missing // Fail if the '=' wasn't found or the option name is missing
// (the first char is '='). // (the first char is '=').
if (equals_sign == NULL || **str == '=') if (equals_sign == NULL || **str == '=')
return "Options must be 'name=value' pairs separated " return N_("Options must be 'name=value' pairs "
"with commas"; "separated with commas");
// Reject a too long option name so that the memcmp() // Reject a too long option name so that the memcmp()
// in the loop below won't read past the end of the // in the loop below won't read past the end of the
// string in optmap[i].name. // string in optmap[i].name.
const size_t name_len = (size_t)(equals_sign - *str); const size_t name_len = (size_t)(equals_sign - *str);
if (name_len > NAME_LEN_MAX) if (name_len > NAME_LEN_MAX)
return "Unknown option name"; return N_("Unknown option name");
// Find the option name from optmap[]. // Find the option name from optmap[].
size_t i = 0; size_t i = 0;
while (true) { while (true) {
if (i == optmap_size) if (i == optmap_size)
return "Unknown option name"; return N_("Unknown option name");
if (memcmp(*str, optmap[i].name, name_len) == 0 if (memcmp(*str, optmap[i].name, name_len) == 0
&& optmap[i].name[name_len] == '\0') && optmap[i].name[name_len] == '\0')
@ -609,7 +614,7 @@ parse_options(const char **const str, const char *str_end,
// string so check it here. // string so check it here.
const size_t value_len = (size_t)(name_eq_value_end - *str); const size_t value_len = (size_t)(name_eq_value_end - *str);
if (value_len == 0) if (value_len == 0)
return "Option value cannot be empty"; return N_("Option value cannot be empty");
// LZMA1/2 preset has its own parsing function. // LZMA1/2 preset has its own parsing function.
if (optmap[i].type == OPTMAP_TYPE_LZMA_PRESET) { if (optmap[i].type == OPTMAP_TYPE_LZMA_PRESET) {
@ -630,14 +635,14 @@ parse_options(const char **const str, const char *str_end,
// in the loop below won't read past the end of the // in the loop below won't read past the end of the
// string in optmap[i].u.map[j].name. // string in optmap[i].u.map[j].name.
if (value_len > NAME_LEN_MAX) if (value_len > NAME_LEN_MAX)
return "Invalid option value"; return N_("Invalid option value");
const name_value_map *map = optmap[i].u.map; const name_value_map *map = optmap[i].u.map;
size_t j = 0; size_t j = 0;
while (true) { while (true) {
// The array is terminated with an empty name. // The array is terminated with an empty name.
if (map[j].name[0] == '\0') if (map[j].name[0] == '\0')
return "Invalid option value"; return N_("Invalid option value");
if (memcmp(*str, map[j].name, value_len) == 0 if (memcmp(*str, map[j].name, value_len) == 0
&& map[j].name[value_len] && map[j].name[value_len]
@ -651,7 +656,8 @@ parse_options(const char **const str, const char *str_end,
} else if (**str < '0' || **str > '9') { } else if (**str < '0' || **str > '9') {
// Note that "max" isn't supported while it is // Note that "max" isn't supported while it is
// supported in xz. It's not useful here. // supported in xz. It's not useful here.
return "Value is not a non-negative decimal integer"; return N_("Value is not a non-negative "
"decimal integer");
} else { } else {
// strtoul() has locale-specific behavior so it cannot // strtoul() has locale-specific behavior so it cannot
// be relied on to get reproducible results since we // be relied on to get reproducible results since we
@ -665,13 +671,13 @@ parse_options(const char **const str, const char *str_end,
v = 0; v = 0;
do { do {
if (v > UINT32_MAX / 10) if (v > UINT32_MAX / 10)
return "Value out of range"; return N_("Value out of range");
v *= 10; v *= 10;
const uint32_t add = (uint32_t)(*p - '0'); const uint32_t add = (uint32_t)(*p - '0');
if (UINT32_MAX - add < v) if (UINT32_MAX - add < v)
return "Value out of range"; return N_("Value out of range");
v += add; v += add;
++p; ++p;
@ -696,9 +702,9 @@ parse_options(const char **const str, const char *str_end,
if ((optmap[i].flags & OPTMAP_USE_BYTE_SUFFIX) if ((optmap[i].flags & OPTMAP_USE_BYTE_SUFFIX)
== 0) { == 0) {
*str = multiplier_start; *str = multiplier_start;
return "This option does not " return N_("This option does not "
"support any multiplier " "support any multiplier "
"suffixes"; "suffixes");
} }
uint32_t shift; uint32_t shift;
@ -721,8 +727,13 @@ parse_options(const char **const str, const char *str_end,
default: default:
*str = multiplier_start; *str = multiplier_start;
return "Invalid multiplier suffix "
"(KiB, MiB, or GiB)"; // TRANSLATORS: Don't translate the
// suffixes "KiB", "MiB", or "GiB"
// because a user can only specify
// untranslated suffixes.
return N_("Invalid multiplier suffix "
"(KiB, MiB, or GiB)");
} }
++p; ++p;
@ -741,19 +752,19 @@ parse_options(const char **const str, const char *str_end,
// Now we must have no chars remaining. // Now we must have no chars remaining.
if (p < name_eq_value_end) { if (p < name_eq_value_end) {
*str = multiplier_start; *str = multiplier_start;
return "Invalid multiplier suffix " return N_("Invalid multiplier suffix "
"(KiB, MiB, or GiB)"; "(KiB, MiB, or GiB)");
} }
if (v > (UINT32_MAX >> shift)) if (v > (UINT32_MAX >> shift))
return "Value out of range"; return N_("Value out of range");
v <<= shift; v <<= shift;
} }
if (v < optmap[i].u.range.min if (v < optmap[i].u.range.min
|| v > optmap[i].u.range.max) || v > optmap[i].u.range.max)
return "Value out of range"; return N_("Value out of range");
} }
// Set the value in filter_options. Enums are handled // Set the value in filter_options. Enums are handled
@ -815,15 +826,15 @@ parse_filter(const char **const str, const char *str_end, lzma_filter *filter,
// string in filter_name_map[i].name. // string in filter_name_map[i].name.
const size_t name_len = (size_t)(name_end - *str); const size_t name_len = (size_t)(name_end - *str);
if (name_len > NAME_LEN_MAX) if (name_len > NAME_LEN_MAX)
return "Unknown filter name"; return N_("Unknown filter name");
for (size_t i = 0; i < ARRAY_SIZE(filter_name_map); ++i) { for (size_t i = 0; i < ARRAY_SIZE(filter_name_map); ++i) {
if (memcmp(*str, filter_name_map[i].name, name_len) == 0 if (memcmp(*str, filter_name_map[i].name, name_len) == 0
&& filter_name_map[i].name[name_len] == '\0') { && filter_name_map[i].name[name_len] == '\0') {
if (only_xz && filter_name_map[i].id if (only_xz && filter_name_map[i].id
>= LZMA_FILTER_RESERVED_START) >= LZMA_FILTER_RESERVED_START)
return "This filter cannot be used in " return N_("This filter cannot be used in "
"the .xz format"; "the .xz format");
// Allocate the filter-specific options and // Allocate the filter-specific options and
// initialize the memory with zeros. // initialize the memory with zeros.
@ -831,7 +842,7 @@ parse_filter(const char **const str, const char *str_end, lzma_filter *filter,
filter_name_map[i].opts_size, filter_name_map[i].opts_size,
allocator); allocator);
if (options == NULL) if (options == NULL)
return "Memory allocation failed"; return N_("Memory allocation failed");
// Filter name was found so the input string is good // Filter name was found so the input string is good
// at least this far. // at least this far.
@ -851,7 +862,7 @@ parse_filter(const char **const str, const char *str_end, lzma_filter *filter,
} }
} }
return "Unknown filter name"; return N_("Unknown filter name");
} }
@ -870,8 +881,8 @@ str_to_filters(const char **const str, lzma_filter *filters, uint32_t flags,
++*str; ++*str;
if (**str == '\0') if (**str == '\0')
return "Empty string is not allowed, " return N_("Empty string is not allowed, "
"try '6' if a default value is needed"; "try '6' if a default value is needed");
// Detect the type of the string. // Detect the type of the string.
// //
@ -894,7 +905,7 @@ str_to_filters(const char **const str, lzma_filter *filters, uint32_t flags,
// there are no chars other than spaces. // there are no chars other than spaces.
for (size_t i = 1; str_end[i] != '\0'; ++i) for (size_t i = 1; str_end[i] != '\0'; ++i)
if (str_end[i] != ' ') if (str_end[i] != ' ')
return "Unsupported preset"; return N_("Unsupported preset");
} else { } else {
// There are no trailing spaces. Use the whole string. // There are no trailing spaces. Use the whole string.
str_end = *str + str_len; str_end = *str + str_len;
@ -907,11 +918,11 @@ str_to_filters(const char **const str, lzma_filter *filters, uint32_t flags,
lzma_options_lzma *opts = lzma_alloc(sizeof(*opts), allocator); lzma_options_lzma *opts = lzma_alloc(sizeof(*opts), allocator);
if (opts == NULL) if (opts == NULL)
return "Memory allocation failed"; return N_("Memory allocation failed");
if (lzma_lzma_preset(opts, preset)) { if (lzma_lzma_preset(opts, preset)) {
lzma_free(opts, allocator); lzma_free(opts, allocator);
return "Unsupported preset"; return N_("Unsupported preset");
} }
filters[0].id = LZMA_FILTER_LZMA2; filters[0].id = LZMA_FILTER_LZMA2;
@ -935,7 +946,7 @@ str_to_filters(const char **const str, lzma_filter *filters, uint32_t flags,
size_t i = 0; size_t i = 0;
do { do {
if (i == LZMA_FILTERS_MAX) { if (i == LZMA_FILTERS_MAX) {
errmsg = "The maximum number of filters is four"; errmsg = N_("The maximum number of filters is four");
goto error; goto error;
} }
@ -957,7 +968,7 @@ str_to_filters(const char **const str, lzma_filter *filters, uint32_t flags,
// Inputs that have "--" at the end or "-- " in the middle // Inputs that have "--" at the end or "-- " in the middle
// will result in an empty filter name. // will result in an empty filter name.
if (filter_end == *str) { if (filter_end == *str) {
errmsg = "Filter name is missing"; errmsg = N_("Filter name is missing");
goto error; goto error;
} }
@ -984,8 +995,8 @@ str_to_filters(const char **const str, lzma_filter *filters, uint32_t flags,
const lzma_ret ret = lzma_validate_chain(temp_filters, &dummy); const lzma_ret ret = lzma_validate_chain(temp_filters, &dummy);
assert(ret == LZMA_OK || ret == LZMA_OPTIONS_ERROR); assert(ret == LZMA_OK || ret == LZMA_OPTIONS_ERROR);
if (ret != LZMA_OK) { if (ret != LZMA_OK) {
errmsg = "Invalid filter chain " errmsg = N_("Invalid filter chain "
"('lzma2' missing at the end?)"; "('lzma2' missing at the end?)");
goto error; goto error;
} }
} }
@ -1013,17 +1024,26 @@ lzma_str_to_filters(const char *str, int *error_pos, lzma_filter *filters,
if (error_pos != NULL) if (error_pos != NULL)
*error_pos = 0; *error_pos = 0;
if (str == NULL || filters == NULL) if (str == NULL || filters == NULL) {
// Don't translate this because it's only shown in case of
// a programming error.
return "Unexpected NULL pointer argument(s) " return "Unexpected NULL pointer argument(s) "
"to lzma_str_to_filters()"; "to lzma_str_to_filters()";
}
// Validate the flags. // Validate the flags.
const uint32_t supported_flags const uint32_t supported_flags
= LZMA_STR_ALL_FILTERS = LZMA_STR_ALL_FILTERS
| LZMA_STR_NO_VALIDATION; | LZMA_STR_NO_VALIDATION;
if (flags & ~supported_flags) if (flags & ~supported_flags) {
// This message is possible only if the caller uses flags
// that are only supported in a newer liblzma version (or
// the flags are simply buggy). Don't translate this at least
// when liblzma itself doesn't use gettext; xz and liblzma
// are usually upgraded at the same time.
return "Unsupported flags to lzma_str_to_filters()"; return "Unsupported flags to lzma_str_to_filters()";
}
const char *used = str; const char *used = str;
const char *errmsg = str_to_filters(&used, filters, flags, allocator); const char *errmsg = str_to_filters(&used, filters, flags, allocator);