Added ungetc(3).

This commit is contained in:
Jonas 'Sortie' Termansen 2012-05-29 00:04:57 +02:00
parent b2b54d108d
commit c5c92d9615
3 changed files with 27 additions and 2 deletions

View File

@ -6,6 +6,7 @@
#define _FILE_LAST_WRITE (1<<2)
#define _FILE_LAST_READ (1<<3)
#define _FILE_AUTO_LOCK (1<<4)
#define _FILE_MAX_PUSHBACK 8
typedef struct _FILE
{
/* This is non-standard, but useful. If you allocate your own FILE and
@ -31,5 +32,7 @@ typedef struct _FILE
struct _FILE* next;
int flags;
size_t bufferused;
size_t numpushedback;
unsigned char pushedback[_FILE_MAX_PUSHBACK];
} FILE;
#endif

View File

@ -52,6 +52,18 @@ void funregister(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; }
fp->flags &= ~_FILE_LAST_WRITE; fp->flags |= _FILE_LAST_READ;
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)
{
fp->numpushedback = 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)
{
if ( fp->numpushedback ) { return 0; }
if ( !fp->eof_func ) { return 0; }
return fp->eof_func(fp->user);
}
@ -135,7 +149,7 @@ void rewind(FILE* fp)
off_t ftello(FILE* fp)
{
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)
@ -143,6 +157,14 @@ long ftell(FILE* 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)
{
if ( !fp )

View File

@ -107,6 +107,7 @@ extern char* sortix_gets(void);
extern int sortix_puts(const char* str);
extern int sprintf(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 vprintf(const char* restrict format, __gnuc_va_list ap);
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 scanf(const char* restrict format, ...);
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 vfscanf(FILE* restrict stream, const char* restrict format, __gnuc_va_list arg);
extern int vscanf(const char* restrict format, __gnuc_va_list arg);