mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 04:57:44 +00:00
LibC: Teach scanf how to read "%lu" and "%llu" (unsigned long{, long})
This makes the gcc port work again.
This commit is contained in:
parent
2323b6fb74
commit
e438dd3c9b
2 changed files with 43 additions and 0 deletions
|
@ -163,6 +163,40 @@ struct read_element_concrete<unsigned, ApT, kind> {
|
|||
}
|
||||
};
|
||||
|
||||
template<typename ApT, ReadKind kind>
|
||||
struct read_element_concrete<unsigned long long, ApT, kind> {
|
||||
bool operator()(GenericLexer& lexer, va_list* ap)
|
||||
{
|
||||
lexer.ignore_while(isspace);
|
||||
|
||||
auto* ptr = va_arg(*ap, ApT*);
|
||||
unsigned long long value = 0;
|
||||
char* endptr = nullptr;
|
||||
auto nptr = lexer.remaining().characters_without_null_termination();
|
||||
if constexpr (kind == ReadKind::Normal)
|
||||
value = strtoull(nptr, &endptr, 10);
|
||||
if constexpr (kind == ReadKind::Octal)
|
||||
value = strtoull(nptr, &endptr, 8);
|
||||
if constexpr (kind == ReadKind::Hex)
|
||||
value = strtoull(nptr, &endptr, 16);
|
||||
if constexpr (kind == ReadKind::Infer)
|
||||
value = strtoull(nptr, &endptr, 0);
|
||||
|
||||
if (!endptr)
|
||||
return false;
|
||||
|
||||
if (endptr == nptr)
|
||||
return false;
|
||||
|
||||
auto diff = endptr - nptr;
|
||||
ASSERT(diff > 0);
|
||||
lexer.ignore((size_t)diff);
|
||||
|
||||
*ptr = value;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ApT, ReadKind kind>
|
||||
struct read_element_concrete<float, ApT, kind> {
|
||||
bool operator()(GenericLexer& lexer, va_list* ap)
|
||||
|
@ -211,12 +245,16 @@ struct read_element {
|
|||
case Long:
|
||||
if constexpr (IsSame<T, int>::value)
|
||||
return read_element_concrete<T, long, kind> {}(input_lexer, ap);
|
||||
if constexpr (IsSame<T, unsigned>::value)
|
||||
return read_element_concrete<T, unsigned, kind> {}(input_lexer, ap);
|
||||
if constexpr (IsSame<T, float>::value)
|
||||
return read_element_concrete<T, double, kind> {}(input_lexer, ap);
|
||||
return false;
|
||||
case LongLong:
|
||||
if constexpr (IsSame<T, int>::value)
|
||||
return read_element_concrete<T, long long, kind> {}(input_lexer, ap);
|
||||
if constexpr (IsSame<T, unsigned>::value)
|
||||
return read_element_concrete<T, unsigned long long, kind> {}(input_lexer, ap);
|
||||
if constexpr (IsSame<T, float>::value)
|
||||
return read_element_concrete<T, double, kind> {}(input_lexer, ap);
|
||||
return false;
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
typedef long double longdouble;
|
||||
typedef long long longlong;
|
||||
typedef unsigned long unsignedlong;
|
||||
typedef char charstar[32];
|
||||
|
||||
template<typename T>
|
||||
|
@ -143,6 +144,7 @@ DECL_WITH_TYPE(longlong);
|
|||
DECL_WITH_TYPE(float);
|
||||
DECL_WITH_TYPE(double);
|
||||
DECL_WITH_TYPE(longdouble);
|
||||
DECL_WITH_TYPE(unsignedlong);
|
||||
|
||||
#undef DECL_WITH_TYPE
|
||||
|
||||
|
@ -179,6 +181,9 @@ const TestSuite test_suites[] {
|
|||
{ "%u.%u.%u", "3.19", 2, 3, { unsignedarg0, unsignedarg1, unsignedarg2 }, { to_value_t(3u), to_value_t(19u) } },
|
||||
// Failing test case from previous impl:
|
||||
{ "SSH-%d.%d-%[^\n]\n", "SSH-2.0-OpenSSH_8.2p1 Ubuntu-4ubuntu0.1\n", 3, 3, { intarg0, intarg1, charstararg0 }, { to_value_t(2), to_value_t(0), str_to_value_t("OpenSSH_8.2p1 Ubuntu-4ubuntu0.1") } },
|
||||
// GCC failure tests
|
||||
{ "%d.%d.%d", "10.2.0", 3, 3, { intarg0, intarg1, intarg2 }, { to_value_t(10), to_value_t(2), to_value_t(0) } },
|
||||
{ "%lu", "3054 ", 1, 1, { unsignedlongarg0 }, { to_value_t(3054ul) } },
|
||||
};
|
||||
|
||||
bool g_any_failed = false;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue