LibC: Implement ungetc()
I didn't really test this, but I think this implementation does what it needs to :)
This commit is contained in:
parent
39be57424c
commit
25a47f0df3
|
@ -23,6 +23,8 @@ struct FILE
|
|||
|
||||
int pid { -1 };
|
||||
|
||||
int unget_char { EOF };
|
||||
|
||||
unsigned char inline_buffer_storage[BUFSIZ] {};
|
||||
unsigned char* buffer = inline_buffer_storage;
|
||||
uint32_t buffer_size = BUFSIZ;
|
||||
|
@ -149,6 +151,8 @@ int fflush(FILE* file)
|
|||
|
||||
ScopeLock _(file);
|
||||
|
||||
file->unget_char = EOF;
|
||||
|
||||
if (file->buffer_index == 0)
|
||||
return 0;
|
||||
|
||||
|
@ -282,9 +286,16 @@ size_t fread(void* buffer, size_t size, size_t nitems, FILE* file)
|
|||
size_t target = size * nitems;
|
||||
size_t nread = 0;
|
||||
|
||||
if (file->unget_char != EOF)
|
||||
{
|
||||
*static_cast<unsigned char*>(buffer) = file->unget_char;
|
||||
file->unget_char = EOF;
|
||||
nread++;
|
||||
}
|
||||
|
||||
while (nread < target)
|
||||
{
|
||||
ssize_t ret = syscall(SYS_READ, file->fd, (uint8_t*)buffer + nread, target - nread);
|
||||
ssize_t ret = syscall(SYS_READ, file->fd, static_cast<unsigned char*>(buffer) + nread, target - nread);
|
||||
|
||||
if (ret < 0)
|
||||
file->error = true;
|
||||
|
@ -350,6 +361,7 @@ int fseek(FILE* file, long offset, int whence)
|
|||
int fseeko(FILE* file, off_t offset, int whence)
|
||||
{
|
||||
ScopeLock _(file);
|
||||
file->unget_char = EOF;
|
||||
long ret = syscall(SYS_SEEK, file->fd, offset, whence);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
|
@ -373,7 +385,7 @@ off_t ftello(FILE* file)
|
|||
long ret = syscall(SYS_TELL, file->fd);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
return ret;
|
||||
return ret - (file->unget_char != EOF);
|
||||
}
|
||||
|
||||
int ftrylockfile(FILE*)
|
||||
|
@ -413,6 +425,13 @@ int getc_unlocked(FILE* file)
|
|||
if (file->eof)
|
||||
return EOF;
|
||||
|
||||
if (file->unget_char != EOF)
|
||||
{
|
||||
int ch = file->unget_char;
|
||||
file->unget_char = EOF;
|
||||
return (unsigned char)ch;
|
||||
}
|
||||
|
||||
unsigned char c;
|
||||
long ret = syscall(SYS_READ, file->fd, &c, 1);
|
||||
|
||||
|
@ -749,8 +768,14 @@ char* tmpnam(char* storage)
|
|||
|
||||
int ungetc(int c, FILE* stream)
|
||||
{
|
||||
dwarnln("FIXME: ungetc({}, {})", c, stream);
|
||||
ASSERT_NOT_REACHED();
|
||||
if (c == EOF)
|
||||
return EOF;
|
||||
ScopeLock _(stream);
|
||||
if (stream->unget_char != EOF)
|
||||
return EOF;
|
||||
stream->unget_char = c;
|
||||
stream->eof = false;
|
||||
return (unsigned char)c;
|
||||
}
|
||||
|
||||
int vfprintf(FILE* file, const char* format, va_list arguments)
|
||||
|
|
Loading…
Reference in New Issue