mirror of
https://gitlab.com/sortix/sortix.git
synced 2023-02-13 20:55:38 -05:00
Added ungetc(3).
This commit is contained in:
parent
b2b54d108d
commit
c5c92d9615
3 changed files with 27 additions and 2 deletions
|
@ -6,6 +6,7 @@
|
||||||
#define _FILE_LAST_WRITE (1<<2)
|
#define _FILE_LAST_WRITE (1<<2)
|
||||||
#define _FILE_LAST_READ (1<<3)
|
#define _FILE_LAST_READ (1<<3)
|
||||||
#define _FILE_AUTO_LOCK (1<<4)
|
#define _FILE_AUTO_LOCK (1<<4)
|
||||||
|
#define _FILE_MAX_PUSHBACK 8
|
||||||
typedef struct _FILE
|
typedef struct _FILE
|
||||||
{
|
{
|
||||||
/* This is non-standard, but useful. If you allocate your own FILE and
|
/* This is non-standard, but useful. If you allocate your own FILE and
|
||||||
|
@ -31,5 +32,7 @@ typedef struct _FILE
|
||||||
struct _FILE* next;
|
struct _FILE* next;
|
||||||
int flags;
|
int flags;
|
||||||
size_t bufferused;
|
size_t bufferused;
|
||||||
|
size_t numpushedback;
|
||||||
|
unsigned char pushedback[_FILE_MAX_PUSHBACK];
|
||||||
} FILE;
|
} FILE;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -52,6 +52,18 @@ void funregister(FILE* fp)
|
||||||
|
|
||||||
size_t fread(void* ptr, size_t size, size_t nmemb, FILE* fp)
|
size_t fread(void* ptr, size_t size, size_t nmemb, FILE* fp)
|
||||||
{
|
{
|
||||||
|
if ( fp->numpushedback && size != 1 ) { errno = ENOSYS; return 0; }
|
||||||
|
if ( fp->numpushedback && nmemb )
|
||||||
|
{
|
||||||
|
unsigned char* buf = (unsigned char*) ptr;
|
||||||
|
size_t amount = nmemb < fp->numpushedback ? nmemb : fp->numpushedback;
|
||||||
|
for ( size_t i = 0; i < amount; i++ )
|
||||||
|
{
|
||||||
|
buf[i] = fp->pushedback[--(fp->numpushedback)];
|
||||||
|
}
|
||||||
|
if ( nmemb <= amount ) { return nmemb; }
|
||||||
|
return amount + fread(buf + amount, size, nmemb - amount, fp);
|
||||||
|
}
|
||||||
if ( !fp->read_func ) { errno = EBADF; return 0; }
|
if ( !fp->read_func ) { errno = EBADF; return 0; }
|
||||||
fp->flags &= ~_FILE_LAST_WRITE; fp->flags |= _FILE_LAST_READ;
|
fp->flags &= ~_FILE_LAST_WRITE; fp->flags |= _FILE_LAST_READ;
|
||||||
return fp->read_func(ptr, size, nmemb, fp->user);
|
return fp->read_func(ptr, size, nmemb, fp->user);
|
||||||
|
@ -96,6 +108,7 @@ size_t fwrite(const void* ptr, size_t size, size_t nmemb, FILE* fp)
|
||||||
|
|
||||||
int fseeko(FILE* fp, off_t offset, int whence)
|
int fseeko(FILE* fp, off_t offset, int whence)
|
||||||
{
|
{
|
||||||
|
fp->numpushedback = 0;
|
||||||
return (fp->seek_func) ? fp->seek_func(fp->user, offset, whence) : 0;
|
return (fp->seek_func) ? fp->seek_func(fp->user, offset, whence) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,6 +135,7 @@ int ferror(FILE* fp)
|
||||||
|
|
||||||
int feof(FILE* fp)
|
int feof(FILE* fp)
|
||||||
{
|
{
|
||||||
|
if ( fp->numpushedback ) { return 0; }
|
||||||
if ( !fp->eof_func ) { return 0; }
|
if ( !fp->eof_func ) { return 0; }
|
||||||
return fp->eof_func(fp->user);
|
return fp->eof_func(fp->user);
|
||||||
}
|
}
|
||||||
|
@ -135,7 +149,7 @@ void rewind(FILE* fp)
|
||||||
off_t ftello(FILE* fp)
|
off_t ftello(FILE* fp)
|
||||||
{
|
{
|
||||||
if ( !fp->tell_func ) { errno = EBADF; return -1; }
|
if ( !fp->tell_func ) { errno = EBADF; return -1; }
|
||||||
return fp->tell_func(fp->user);
|
return fp->tell_func(fp->user) - fp->numpushedback;
|
||||||
}
|
}
|
||||||
|
|
||||||
long ftell(FILE* fp)
|
long ftell(FILE* fp)
|
||||||
|
@ -143,6 +157,14 @@ long ftell(FILE* fp)
|
||||||
return (long) ftello(fp);
|
return (long) ftello(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ungetc(int c, FILE* fp)
|
||||||
|
{
|
||||||
|
if ( fp->numpushedback == _FILE_MAX_PUSHBACK ) { errno = ERANGE; return EOF; }
|
||||||
|
unsigned char uc = c;
|
||||||
|
fp->pushedback[fp->numpushedback++] = uc;
|
||||||
|
return uc;
|
||||||
|
}
|
||||||
|
|
||||||
int fflush(FILE* fp)
|
int fflush(FILE* fp)
|
||||||
{
|
{
|
||||||
if ( !fp )
|
if ( !fp )
|
||||||
|
|
|
@ -107,6 +107,7 @@ extern char* sortix_gets(void);
|
||||||
extern int sortix_puts(const char* str);
|
extern int sortix_puts(const char* str);
|
||||||
extern int sprintf(char* restrict s, const char* restrict format, ...);
|
extern int sprintf(char* restrict s, const char* restrict format, ...);
|
||||||
extern int sscanf(const char* restrict s, const char* restrict format, ...);
|
extern int sscanf(const char* restrict s, const char* restrict format, ...);
|
||||||
|
extern int ungetc(int c, FILE* stream);
|
||||||
extern int vfprintf(FILE* restrict stream, const char* restrict format, __gnuc_va_list ap);
|
extern int vfprintf(FILE* restrict stream, const char* restrict format, __gnuc_va_list ap);
|
||||||
extern int vprintf(const char* restrict format, __gnuc_va_list ap);
|
extern int vprintf(const char* restrict format, __gnuc_va_list ap);
|
||||||
extern int vsnprintf(char* restrict, size_t, const char* restrict, __gnuc_va_list);
|
extern int vsnprintf(char* restrict, size_t, const char* restrict, __gnuc_va_list);
|
||||||
|
@ -134,7 +135,6 @@ extern int rename(const char* oldname, const char* newname);
|
||||||
extern int renameat(int oldfd, const char* oldname, int newfd, const char* newname);
|
extern int renameat(int oldfd, const char* oldname, int newfd, const char* newname);
|
||||||
extern int scanf(const char* restrict format, ...);
|
extern int scanf(const char* restrict format, ...);
|
||||||
extern int setvbuf(FILE* restrict stream, char* restrict buf, int type, size_t size);
|
extern int setvbuf(FILE* restrict stream, char* restrict buf, int type, size_t size);
|
||||||
extern int ungetc(int c, FILE* stream);
|
|
||||||
extern int vdprintf(int fildes, const char* restrict format, __gnuc_va_list ap);
|
extern int vdprintf(int fildes, const char* restrict format, __gnuc_va_list ap);
|
||||||
extern int vfscanf(FILE* restrict stream, const char* restrict format, __gnuc_va_list arg);
|
extern int vfscanf(FILE* restrict stream, const char* restrict format, __gnuc_va_list arg);
|
||||||
extern int vscanf(const char* restrict format, __gnuc_va_list arg);
|
extern int vscanf(const char* restrict format, __gnuc_va_list arg);
|
||||||
|
|
Loading…
Reference in a new issue