update xfile.h. close #40

This commit is contained in:
Yuichi Nishiwaki 2014-09-19 17:47:55 +09:00
parent c425815313
commit 1ff327b11f
1 changed files with 77 additions and 33 deletions

View File

@ -1,5 +1,5 @@
#ifndef XFILE_H__ #ifndef XFILE_H
#define XFILE_H__ #define XFILE_H
#if defined(__cplusplus) #if defined(__cplusplus)
extern "C" { extern "C" {
@ -56,11 +56,11 @@ static inline int xfgetc(xFILE *);
static inline char *xfgets(char *, int, xFILE *); static inline char *xfgets(char *, int, xFILE *);
static inline int xfputc(int, xFILE *); static inline int xfputc(int, xFILE *);
static inline int xfputs(const char *, xFILE *); static inline int xfputs(const char *, xFILE *);
static inline char xgetc(xFILE *); static inline int xgetc(xFILE *);
static inline int xgetchar(void); static inline int xgetchar(void);
static inline int xputc(int, xFILE *); static inline int xputc(int, xFILE *);
static inline int xputchar(int); static inline int xputchar(int);
static inline int xputs(char *); static inline int xputs(const char *);
static inline int xungetc(int, xFILE *); static inline int xungetc(int, xFILE *);
/* formatted I/O */ /* formatted I/O */
@ -69,9 +69,9 @@ static inline int xfprintf(xFILE *, const char *, ...);
static inline int xvfprintf(xFILE *, const char *, va_list); static inline int xvfprintf(xFILE *, const char *, va_list);
/* standard I/O */ /* standard I/O */
#define xstdin (xstdin__()) #define xstdin (xstdin_())
#define xstdout (xstdout__()) #define xstdout (xstdout_())
#define xstderr (xstderr__()) #define xstderr (xstderr_())
/* private */ /* private */
@ -105,21 +105,10 @@ xfunopen(void *cookie, int (*read)(void *, char *, int), int (*write)(void *, co
* Derieved xFILE Classes * Derieved xFILE Classes
*/ */
static inline FILE *
xf_unpack(void *cookie)
{
switch ((long)cookie) {
default: return cookie;
case 0: return stdin;
case 1: return stdout;
case -1: return stderr;
}
}
static inline int static inline int
xf_file_read(void *cookie, char *ptr, int size) xf_file_read(void *cookie, char *ptr, int size)
{ {
FILE *file = xf_unpack(cookie); FILE *file = cookie;
int r; int r;
r = fread(ptr, 1, size, file); r = fread(ptr, 1, size, file);
@ -135,7 +124,7 @@ xf_file_read(void *cookie, char *ptr, int size)
static inline int static inline int
xf_file_write(void *cookie, const char *ptr, int size) xf_file_write(void *cookie, const char *ptr, int size)
{ {
FILE *file = xf_unpack(cookie); FILE *file = cookie;
int r; int r;
r = fwrite(ptr, 1, size, file); r = fwrite(ptr, 1, size, file);
@ -148,19 +137,19 @@ xf_file_write(void *cookie, const char *ptr, int size)
static inline long static inline long
xf_file_seek(void *cookie, long pos, int whence) xf_file_seek(void *cookie, long pos, int whence)
{ {
return fseek(xf_unpack(cookie), pos, whence); return fseek(cookie, pos, whence);
} }
static inline int static inline int
xf_file_flush(void *cookie) xf_file_flush(void *cookie)
{ {
return fflush(xf_unpack(cookie)); return fflush(cookie);
} }
static inline int static inline int
xf_file_close(void *cookie) xf_file_close(void *cookie)
{ {
return fclose(xf_unpack(cookie)); return fclose(cookie);
} }
static inline xFILE * static inline xFILE *
@ -179,27 +168,36 @@ xfpopen(FILE *fp)
#define XF_FILE_VTABLE xf_file_read, xf_file_write, xf_file_seek, xf_file_flush, xf_file_close #define XF_FILE_VTABLE xf_file_read, xf_file_write, xf_file_seek, xf_file_flush, xf_file_close
static inline xFILE * static inline xFILE *
xstdin__() xstdin_()
{ {
static xFILE xfile_stdin = { -1, 0, { (void *)0, XF_FILE_VTABLE } }; static xFILE x = { -1, 0, { NULL, XF_FILE_VTABLE } };
return &xfile_stdin; if (! x.vtable.cookie) {
x.vtable.cookie = stdin;
}
return &x;
} }
static inline xFILE * static inline xFILE *
xstdout__() xstdout_()
{ {
static xFILE xfile_stdout = { -1, 0, { (void *)1, XF_FILE_VTABLE } }; static xFILE x = { -1, 0, { NULL, XF_FILE_VTABLE } };
return &xfile_stdout; if (! x.vtable.cookie) {
x.vtable.cookie = stdout;
}
return &x;
} }
static inline xFILE * static inline xFILE *
xstderr__() xstderr_()
{ {
static xFILE xfile_stderr = { -1, 0, { (void *)-1, XF_FILE_VTABLE } }; static xFILE x = { -1, 0, { NULL, XF_FILE_VTABLE } };
return &xfile_stderr; if (! x.vtable.cookie) {
x.vtable.cookie = stderr;
}
return &x;
} }
struct xf_membuf { struct xf_membuf {
@ -438,13 +436,41 @@ xfgetc(xFILE *file)
xfread(buf, 1, 1, file); xfread(buf, 1, 1, file);
if (xfeof(file)) { if (xfeof(file) || xferror(file)) {
return EOF; return EOF;
} }
return buf[0]; return buf[0];
} }
static inline int
xgetc(xFILE *file)
{
return xfgetc(file);
}
static inline char *
xfgets(char *str, int size, xFILE *file)
{
int c = EOF, i;
for (i = 0; i < size - 1 && c != '\n'; ++i) {
if ((c = xfgetc(file)) == EOF) {
break;
}
str[i] = c;
}
if (i == 0 && c == EOF) {
return NULL;
}
if (xferror(file)) {
return NULL;
}
str[i] = '\0';
return str;
}
static inline int static inline int
xungetc(int c, xFILE *file) xungetc(int c, xFILE *file)
{ {
@ -469,9 +495,18 @@ xfputc(int c, xFILE *file)
buf[0] = c; buf[0] = c;
xfwrite(buf, 1, 1, file); xfwrite(buf, 1, 1, file);
if (xferror(file)) {
return EOF;
}
return buf[0]; return buf[0];
} }
static inline int
xputc(int c, xFILE *file)
{
return xfputc(c, file);
}
static inline int static inline int
xputchar(int c) xputchar(int c)
{ {
@ -486,9 +521,18 @@ xfputs(const char *str, xFILE *file)
len = strlen(str); len = strlen(str);
xfwrite(str, len, 1, file); xfwrite(str, len, 1, file);
if (xferror(file)) {
return EOF;
}
return 0; return 0;
} }
static inline int
xputs(const char *s)
{
return xfputs(s, xstdout);
}
static inline int static inline int
xprintf(const char *fmt, ...) xprintf(const char *fmt, ...)
{ {