LibC: Fix *scanf consuming extra characters
This commit is contained in:
parent
5fde2cf91a
commit
2464fccadd
|
@ -2,4 +2,4 @@
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
int scanf_impl(const char* format, va_list arguments, int (*getc_fun)(void*), void* data);
|
int scanf_impl(const char* format, va_list arguments, int (*getc_fun)(bool advance, void*), void* data);
|
||||||
|
|
|
@ -112,9 +112,9 @@ using BASE_TYPE = BAN::integral_constant<int, BASE>;
|
||||||
template<bool UNSIGNED>
|
template<bool UNSIGNED>
|
||||||
using IS_UNSIGNED = BAN::integral_constant<bool, UNSIGNED>;
|
using IS_UNSIGNED = BAN::integral_constant<bool, UNSIGNED>;
|
||||||
|
|
||||||
int scanf_impl(const char* format, va_list arguments, int (*__getc_fun)(void*), void* data)
|
int scanf_impl(const char* format, va_list arguments, int (*__getc_fun)(bool advance, void*), void* data)
|
||||||
{
|
{
|
||||||
static constexpr int DONE = -1;
|
static constexpr int DONE = EOF;
|
||||||
static constexpr int NONE = -2;
|
static constexpr int NONE = -2;
|
||||||
|
|
||||||
int nread = 0;
|
int nread = 0;
|
||||||
|
@ -134,11 +134,9 @@ int scanf_impl(const char* format, va_list arguments, int (*__getc_fun)(void*),
|
||||||
{
|
{
|
||||||
if (in == DONE)
|
if (in == DONE)
|
||||||
return;
|
return;
|
||||||
if (advance || in == NONE)
|
in = __getc_fun(advance, data);
|
||||||
{
|
if (advance)
|
||||||
in = __getc_fun(data);
|
|
||||||
nread++;
|
nread++;
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
auto parse_integer_internal =
|
auto parse_integer_internal =
|
||||||
|
|
|
@ -794,11 +794,10 @@ char* tmpnam(char* storage)
|
||||||
return storage;
|
return storage;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ungetc(int c, FILE* stream)
|
int ungetc_unlocked(int c, FILE* stream)
|
||||||
{
|
{
|
||||||
if (c == EOF)
|
if (c == EOF)
|
||||||
return EOF;
|
return EOF;
|
||||||
ScopeLock _(stream);
|
|
||||||
if (stream->unget_char != EOF)
|
if (stream->unget_char != EOF)
|
||||||
return EOF;
|
return EOF;
|
||||||
stream->unget_char = c;
|
stream->unget_char = c;
|
||||||
|
@ -806,6 +805,12 @@ int ungetc(int c, FILE* stream)
|
||||||
return (unsigned char)c;
|
return (unsigned char)c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ungetc(int c, FILE* stream)
|
||||||
|
{
|
||||||
|
ScopeLock _(stream);
|
||||||
|
return ungetc_unlocked(c, stream);
|
||||||
|
}
|
||||||
|
|
||||||
int vfprintf(FILE* file, const char* format, va_list arguments)
|
int vfprintf(FILE* file, const char* format, va_list arguments)
|
||||||
{
|
{
|
||||||
ScopeLock _(file);
|
ScopeLock _(file);
|
||||||
|
@ -815,7 +820,18 @@ int vfprintf(FILE* file, const char* format, va_list arguments)
|
||||||
int vfscanf(FILE* file, const char* format, va_list arguments)
|
int vfscanf(FILE* file, const char* format, va_list arguments)
|
||||||
{
|
{
|
||||||
ScopeLock _(file);
|
ScopeLock _(file);
|
||||||
return scanf_impl(format, arguments, [](void* file) { return getc_unlocked(static_cast<FILE*>(file)); }, file);
|
return scanf_impl(format, arguments,
|
||||||
|
[](bool advance, void* data)
|
||||||
|
{
|
||||||
|
FILE* fp = static_cast<FILE*>(data);
|
||||||
|
|
||||||
|
if (advance)
|
||||||
|
getc_unlocked(fp);
|
||||||
|
const int ret = getc_unlocked(fp);
|
||||||
|
ungetc_unlocked(ret, fp);
|
||||||
|
return ret;
|
||||||
|
}, file
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
int vprintf(const char* format, va_list arguments)
|
int vprintf(const char* format, va_list arguments)
|
||||||
|
@ -883,12 +899,15 @@ int vsprintf(char* buffer, const char* format, va_list arguments)
|
||||||
int vsscanf(const char* s, const char* format, va_list arguments)
|
int vsscanf(const char* s, const char* format, va_list arguments)
|
||||||
{
|
{
|
||||||
return scanf_impl(format, arguments,
|
return scanf_impl(format, arguments,
|
||||||
[](void* data) -> int
|
[](bool advance, void* data) -> int
|
||||||
{
|
{
|
||||||
char ret = **static_cast<char**>(data);
|
const char** ptr = static_cast<const char**>(data);
|
||||||
(*static_cast<char**>(data))++;
|
|
||||||
|
if (advance)
|
||||||
|
(*ptr)++;
|
||||||
|
const char ret = **ptr;
|
||||||
if (ret == '\0')
|
if (ret == '\0')
|
||||||
return -1;
|
return EOF;
|
||||||
return ret;
|
return ret;
|
||||||
}, &s
|
}, &s
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue