Treat all integer multiplier suffixes as base-2.
Originally both base-2 and base-10 were supported, but since there seems to be little need for base-10 in XZ Utils, treat everything as base-2 and also be more relaxed about the case of the first letter of the suffix. Now xz will accept e.g. KiB, Ki, k, K, kB, and KB, and interpret them all as 1024. The recommended spelling of the suffixes are still KiB, MiB, and GiB.
This commit is contained in:
parent
00fc1211ae
commit
cf38da00a1
@ -65,39 +65,32 @@ str_to_uint64(const char *name, const char *value, uint64_t min, uint64_t max)
|
|||||||
} while (*value >= '0' && *value <= '9');
|
} while (*value >= '0' && *value <= '9');
|
||||||
|
|
||||||
if (*value != '\0') {
|
if (*value != '\0') {
|
||||||
// Look for suffix.
|
// Look for suffix. Originally this supported both base-2
|
||||||
static const struct {
|
// and base-10, but since there seems to be little need
|
||||||
const char name[4];
|
// for base-10 in this program, treat everything as base-2
|
||||||
uint64_t multiplier;
|
// and also be more relaxed about the case of the first
|
||||||
} suffixes[] = {
|
// letter of the suffix.
|
||||||
{ "k", UINT64_C(1000) },
|
|
||||||
{ "kB", UINT64_C(1000) },
|
|
||||||
{ "M", UINT64_C(1000000) },
|
|
||||||
{ "MB", UINT64_C(1000000) },
|
|
||||||
{ "G", UINT64_C(1000000000) },
|
|
||||||
{ "GB", UINT64_C(1000000000) },
|
|
||||||
{ "Ki", UINT64_C(1024) },
|
|
||||||
{ "KiB", UINT64_C(1024) },
|
|
||||||
{ "Mi", UINT64_C(1048576) },
|
|
||||||
{ "MiB", UINT64_C(1048576) },
|
|
||||||
{ "Gi", UINT64_C(1073741824) },
|
|
||||||
{ "GiB", UINT64_C(1073741824) }
|
|
||||||
};
|
|
||||||
|
|
||||||
uint64_t multiplier = 0;
|
uint64_t multiplier = 0;
|
||||||
for (size_t i = 0; i < ARRAY_SIZE(suffixes); ++i) {
|
if (*value == 'k' || *value == 'K')
|
||||||
if (strcmp(value, suffixes[i].name) == 0) {
|
multiplier = UINT64_C(1) << 10;
|
||||||
multiplier = suffixes[i].multiplier;
|
else if (*value == 'm' || *value == 'M')
|
||||||
break;
|
multiplier = UINT64_C(1) << 20;
|
||||||
}
|
else if (*value == 'g' || *value == 'G')
|
||||||
}
|
multiplier = UINT64_C(1) << 30;
|
||||||
|
|
||||||
|
++value;
|
||||||
|
|
||||||
|
// Allow also e.g. Ki, KiB, and KB.
|
||||||
|
if (*value != '\0' && strcmp(value, "i") != 0
|
||||||
|
&& strcmp(value, "iB") != 0
|
||||||
|
&& strcmp(value, "B") != 0)
|
||||||
|
multiplier = 0;
|
||||||
|
|
||||||
if (multiplier == 0) {
|
if (multiplier == 0) {
|
||||||
message(V_ERROR, _("%s: Invalid multiplier suffix. "
|
message(V_ERROR, _("%s: Invalid multiplier suffix"),
|
||||||
"Valid suffixes:"), value);
|
value - 1);
|
||||||
message_fatal("`k' (10^3), `M' (10^6), `G' (10^9) "
|
message_fatal(_("Valid suffixes are `KiB' (2^10), "
|
||||||
"`Ki' (2^10), `Mi' (2^20), "
|
"`MiB' (2^20), and `GiB' (2^30)."));
|
||||||
"`Gi' (2^30)");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't overflow here either.
|
// Don't overflow here either.
|
||||||
|
48
src/xz/xz.1
48
src/xz/xz.1
@ -238,28 +238,36 @@ In most places where an integer argument is expected, an optional suffix
|
|||||||
is supported to easily indicate large integers. There must be no space
|
is supported to easily indicate large integers. There must be no space
|
||||||
between the integer and the suffix.
|
between the integer and the suffix.
|
||||||
.TP
|
.TP
|
||||||
.BR k " or " kB
|
.B KiB
|
||||||
The integer is multiplied by 1,000 (10^3). For example,
|
The integer is multiplied by 1,024 (2^10). Also
|
||||||
.B "5k"
|
.BR Ki ,
|
||||||
or
|
.BR k ,
|
||||||
.B "5kB"
|
.BR kB ,
|
||||||
equals
|
.BR K ,
|
||||||
.BR "5000" .
|
and
|
||||||
|
.B KB
|
||||||
|
are accepted as synonyms for
|
||||||
|
.BR KiB .
|
||||||
.TP
|
.TP
|
||||||
.BR Ki " or " KiB
|
.B MiB
|
||||||
The integer is multiplied by 1,024 (2^10).
|
The integer is multiplied by 1,048,576 (2^20). Also
|
||||||
|
.BR Mi ,
|
||||||
|
.BR m ,
|
||||||
|
.BR M ,
|
||||||
|
and
|
||||||
|
.B MB
|
||||||
|
are accepted as synonyms for
|
||||||
|
.BR MiB .
|
||||||
.TP
|
.TP
|
||||||
.BR M " or " MB
|
.B GiB
|
||||||
The integer is multiplied by 1,000,000 (10^6).
|
The integer is multiplied by 1,073,741,824 (2^30). Also
|
||||||
.TP
|
.BR Gi ,
|
||||||
.BR Mi " or " MiB
|
.BR g ,
|
||||||
The integer is multiplied by 1,048,576 (2^20).
|
.BR G ,
|
||||||
.TP
|
and
|
||||||
.BR G " or " GB
|
.B GB
|
||||||
The integer is multiplied by 1,000,000,000 (10^9).
|
are accepted as synonyms for
|
||||||
.TP
|
.BR GiB .
|
||||||
.BR Gi " or " GiB
|
|
||||||
The integer is multiplied by 1,073,741,824 (2^30).
|
|
||||||
.PP
|
.PP
|
||||||
A special value
|
A special value
|
||||||
.B max
|
.B max
|
||||||
|
@ -183,34 +183,24 @@ str_to_uint64(const char *value, uint64_t max)
|
|||||||
|
|
||||||
if (*value != '\0') {
|
if (*value != '\0') {
|
||||||
// Look for suffix.
|
// Look for suffix.
|
||||||
static const struct {
|
uint64_t multiplier = 0;
|
||||||
const char name[4];
|
if (*value == 'k' || *value == 'K')
|
||||||
uint32_t multiplier;
|
multiplier = UINT64_C(1) << 10;
|
||||||
} suffixes[] = {
|
else if (*value == 'm' || *value == 'M')
|
||||||
{ "k", 1000 },
|
multiplier = UINT64_C(1) << 20;
|
||||||
{ "kB", 1000 },
|
else if (*value == 'g' || *value == 'G')
|
||||||
{ "M", 1000000 },
|
multiplier = UINT64_C(1) << 30;
|
||||||
{ "MB", 1000000 },
|
|
||||||
{ "G", 1000000000 },
|
|
||||||
{ "GB", 1000000000 },
|
|
||||||
{ "Ki", 1024 },
|
|
||||||
{ "KiB", 1024 },
|
|
||||||
{ "Mi", 1048576 },
|
|
||||||
{ "MiB", 1048576 },
|
|
||||||
{ "Gi", 1073741824 },
|
|
||||||
{ "GiB", 1073741824 }
|
|
||||||
};
|
|
||||||
|
|
||||||
uint32_t multiplier = 0;
|
++value;
|
||||||
for (size_t i = 0; i < ARRAY_SIZE(suffixes); ++i) {
|
|
||||||
if (strcmp(value, suffixes[i].name) == 0) {
|
// Allow also e.g. Ki, KiB, and KB.
|
||||||
multiplier = suffixes[i].multiplier;
|
if (*value != '\0' && strcmp(value, "i") != 0
|
||||||
break;
|
&& strcmp(value, "iB") != 0
|
||||||
}
|
&& strcmp(value, "B") != 0)
|
||||||
}
|
multiplier = 0;
|
||||||
|
|
||||||
if (multiplier == 0) {
|
if (multiplier == 0) {
|
||||||
my_errorf("%s: Invalid suffix", value);
|
my_errorf("%s: Invalid suffix", value - 1);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user