mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-03-03 07:29:23 +00:00
Scan fixed-width integers in vcscanf (#424)
When a format string like %2x is provided, the width parameter was read correctly as 2, but it was not used when decoding the number from the input string (ie instead of reading 2 characters from the input string, vcscanf read all the characters). This change uses the value of width within the number decoding loop to read fixed number of digits correctly. if width is zero (not provided), the default of width is set as bits. Fixes #423
This commit is contained in:
parent
32eec7df4c
commit
a6f65eea7c
2 changed files with 11 additions and 1 deletions
|
@ -177,9 +177,11 @@ int vcscanf(int callback(void *), int unget(int, void *), void *arg,
|
||||||
DecodeNumber:
|
DecodeNumber:
|
||||||
if (c != -1) {
|
if (c != -1) {
|
||||||
number = 0;
|
number = 0;
|
||||||
|
width = !width ? bits : width;
|
||||||
do {
|
do {
|
||||||
diglet = kBase36[(unsigned char)c];
|
diglet = kBase36[(unsigned char)c];
|
||||||
if (1 <= diglet && diglet <= base) {
|
if (1 <= diglet && diglet <= base) {
|
||||||
|
width -= 1;
|
||||||
number *= base;
|
number *= base;
|
||||||
number += diglet - 1;
|
number += diglet - 1;
|
||||||
} else if (thousands && diglet == ',') {
|
} else if (thousands && diglet == ',') {
|
||||||
|
@ -187,7 +189,7 @@ int vcscanf(int callback(void *), int unget(int, void *), void *arg,
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while ((c = callback(arg)) != -1);
|
} while ((c = callback(arg)) != -1 && width > 0);
|
||||||
if (!discard) {
|
if (!discard) {
|
||||||
uint128_t bane = (uint128_t)1 << (bits - 1);
|
uint128_t bane = (uint128_t)1 << (bits - 1);
|
||||||
if (!(number & ~((bane - 1) | (issigned ? 0 : bane))) ||
|
if (!(number & ~((bane - 1) | (issigned ? 0 : bane))) ||
|
||||||
|
|
|
@ -141,3 +141,11 @@ TEST(sscanf, testDiscard_notIncludedInCount) {
|
||||||
ASSERT_EQ(1, sscanf("hello there", "%*s %8s", buf));
|
ASSERT_EQ(1, sscanf("hello there", "%*s %8s", buf));
|
||||||
EXPECT_STREQ("there", buf);
|
EXPECT_STREQ("there", buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(sscanf, testFixedWidthFormat_Integer) {
|
||||||
|
int r, g, b;
|
||||||
|
ASSERT_EQ(3, sscanf("#321030", "#%2x%2b%2d", &r, &g, &b));
|
||||||
|
ASSERT_EQ(0x32, r);
|
||||||
|
ASSERT_EQ(2, g);
|
||||||
|
ASSERT_EQ(30, b);
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue