aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/gfile/gfile.h75
-rw-r--r--src/gfile/gfile.c233
2 files changed, 264 insertions, 44 deletions
diff --git a/include/gfile/gfile.h b/include/gfile/gfile.h
index bc476956..9d171050 100644
--- a/include/gfile/gfile.h
+++ b/include/gfile/gfile.h
@@ -82,32 +82,6 @@ extern GFILE *gfileStdOut;
/* External declarations. */
/*===========================================================================*/
-//TODO
-//FILE * tmpfile ( void ); // Auto-deleting
-//char * tmpnam ( char * str );
-//L_tmpnam - Minimum length for temporary file name
-//FILENAME_MAX - Maximum length of file names (constant )
-// FOPEN_MAX - Potential limit of simultaneous open streams (constant )
-// TMP_MAX - Number of temporary files (constant )
-//FILE * freopen ( const char * filename, const char * mode, FILE * stream );
-//setbuf
-//setvbuf
-//fflush
-//fscanf
-//scanf
-//sscanf
-//vscanf
-//vsscanf
-//fgetc
-//fgets
-//fputc
-//fputs
-//getc
-//getchar
-//puts
-//ungetc
-//void perror (const char * str);
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -136,13 +110,32 @@ extern "C" {
#if GFILE_NEED_STRINGS
int vsnprintg(char *buf, int maxlen, const char *fmt, va_list arg);
int snprintg(char *buf, int maxlen, const char *fmt, ...);
- #define vsprintg(s,m,a) vsnprintg(s,0,m,a)
- #define sprintg(s,m,...) snprintg(s,0,m,...)
+ #define vsprintg(s,m,a) vsnprintg(s,0,m,a)
+ #define sprintg(s,m,...) snprintg(s,0,m,...)
#endif
#endif
+ #if GFILE_NEED_SCANG
+ int vfscang(GFILE *f, const char *fmt, va_list arg);
+ int fscang(GFILE *f, const char *fmt, ...);
+ #define vscang(f,a) vfscang(gfileStdIn,f,a)
+ #define scang(f,...) fscang(gfileStdIn,f,...)
+
+ #if GFILE_NEED_STRINGS
+ int vsscang(const char *buf, const char *fmt, va_list arg);
+ int sscang(const char *buf, const char *fmt, ...);
+ #endif
+ #endif
#if GFILE_NEED_STDIO && !defined(GFILE_IMPLEMENTATION)
+ #define stdin gfileStdIn
+ #define stdout gfileStdOut
+ #define stderr gfileStdErr
+ #define FILENAME_MAX 256 // Use a relatively small number for an embedded platform
+ #define L_tmpnam FILENAME_MAX
+ #define FOPEN_MAX GFILE_MAX_GFILES
+ #define TMP_MAX GFILE_MAX_GFILES
+ #define P_tmpdir "/tmp/"
#define FILE GFILE
#define fopen(n,m) gfileOpen(n,m)
#define fclose(f) gfileClose(f)
@@ -164,9 +157,7 @@ extern "C" {
#define fgetpos(f,pos) gstdioGetpos(f,pos)
#define fsetpos(f, pos) (!gfileSetPos(f, *pos))
#define rewind(f) gfileSetPos(f, 0);
- #define clearerr(f) (0)
#define feof(f) gfileEOF(f)
- //#define ferror(f) (0)
#define vfprintf(f,m,a) vfnprintg(f,0,m,a)
#define fprintf(f,m,...) fnprintg(f,0,m,...)
@@ -176,6 +167,30 @@ extern "C" {
#define snprintf(s,n,m,...) snprintg(s,n,m,...)
#define vsprintf(s,m,a) vsnprintg(s,0,m,a)
#define sprintf(s,m,...) snprintg(s,0,m,...)
+ //TODO
+ //void clearerr ( FILE * stream );
+ //int ferror ( FILE * stream );
+ //FILE * tmpfile ( void ); // Auto-deleting
+ //char * tmpnam ( char * str );
+ //char * mktemp (char *template);
+ //FILE * freopen ( const char * filename, const char * mode, FILE * stream );
+ //setbuf
+ //setvbuf
+ //fflush
+ //fscanf
+ //scanf
+ //sscanf
+ //vscanf
+ //vsscanf
+ //fgetc
+ //fgets
+ //fputc
+ //fputs
+ //getc
+ //getchar
+ //puts
+ //ungetc
+ //void perror (const char * str);
#endif
#ifdef __cplusplus
diff --git a/src/gfile/gfile.c b/src/gfile/gfile.c
index 59dade1f..f9c306e4 100644
--- a/src/gfile/gfile.c
+++ b/src/gfile/gfile.c
@@ -68,8 +68,10 @@ GFILE *gfileStdErr;
*/
static const GFILEVMT const * FsChain = GFILE_CHAINHEAD;
-void _gfileInit(void)
-{
+/**
+ * The init routine
+ */
+void _gfileInit(void) {
#if GFILE_NEED_NATIVEFS
NativeStdIn.flags = GFILEFLG_OPEN|GFILEFLG_READ;
NativeStdIn.vmt = &FsNativeVMT;
@@ -296,7 +298,7 @@ GFILE *gfileOpen(const char *fname, const char *mode) {
}
void gfileClose(GFILE *f) {
- if (!(f->flags & GFILEFLG_OPEN))
+ if (!f || !(f->flags & GFILEFLG_OPEN))
return;
if (f->vmt->close)
f->vmt->close(f);
@@ -306,7 +308,7 @@ void gfileClose(GFILE *f) {
size_t gfileRead(GFILE *f, char *buf, size_t len) {
size_t res;
- if ((f->flags & (GFILEFLG_OPEN|GFILEFLG_READ)) != (GFILEFLG_OPEN|GFILEFLG_READ))
+ if (!f || (f->flags & (GFILEFLG_OPEN|GFILEFLG_READ)) != (GFILEFLG_OPEN|GFILEFLG_READ))
return 0;
if (!f->vmt->read)
return 0;
@@ -319,7 +321,7 @@ size_t gfileRead(GFILE *f, char *buf, size_t len) {
size_t gfileWrite(GFILE *f, const char *buf, size_t len) {
size_t res;
- if ((f->flags & (GFILEFLG_OPEN|GFILEFLG_WRITE)) != (GFILEFLG_OPEN|GFILEFLG_WRITE))
+ if (!f || (f->flags & (GFILEFLG_OPEN|GFILEFLG_WRITE)) != (GFILEFLG_OPEN|GFILEFLG_WRITE))
return 0;
if (!f->vmt->write)
return 0;
@@ -330,13 +332,13 @@ size_t gfileWrite(GFILE *f, const char *buf, size_t len) {
}
long int gfileGetPos(GFILE *f) {
- if (!(f->flags & GFILEFLG_OPEN))
+ if (!f || !(f->flags & GFILEFLG_OPEN))
return 0;
return f->pos;
}
bool_t gfileSetPos(GFILE *f, long int pos) {
- if (!(f->flags & GFILEFLG_OPEN))
+ if (!f || !(f->flags & GFILEFLG_OPEN))
return FALSE;
if (!f->vmt->setpos || !f->vmt->setpos(f, pos))
return FALSE;
@@ -344,7 +346,7 @@ bool_t gfileSetPos(GFILE *f, long int pos) {
}
long int gfileGetSize(GFILE *f) {
- if (!(f->flags & GFILEFLG_OPEN))
+ if (!f || !(f->flags & GFILEFLG_OPEN))
return 0;
if (!f->vmt->getsize)
return 0;
@@ -352,7 +354,7 @@ long int gfileGetSize(GFILE *f) {
}
bool_t gfileEOF(GFILE *f) {
- if (!(f->flags & GFILEFLG_OPEN))
+ if (!f || !(f->flags & GFILEFLG_OPEN))
return TRUE;
if (!f->vmt->eof)
return TRUE;
@@ -367,12 +369,16 @@ bool_t gfileEOF(GFILE *f) {
// Special String VMT
static int StringRead(GFILE *f, char *buf, int size) {
- memcpy(buf, (char *)f->obj+f->pos, size);
- return size;
+ // size must be 1 for a complete read
+ if (!((char *)f->obj)[f->pos])
+ return 0;
+ buf[0] = ((char *)f->obj)[f->pos];
+ return 1;
}
static int StringWrite(GFILE *f, const char *buf, int size) {
- memcpy((char *)f->obj+f->pos, buf, size);
- return size;
+ // size must be 1 for a complete write
+ ((char *)f->obj)[f->pos] = buf[0];
+ return 1;
}
static const GFILEVMT StringVMT = {
0, // next
@@ -640,7 +646,206 @@ bool_t gfileEOF(GFILE *f) {
* scang routines
********************************************************/
#if GFILE_NEED_SCANG
- #error "GFILE-SCANG: Not implemented yet"
+ int fscang(GFILE *f, const char *fmt, ...) {
+ int res;
+ va_list ap;
+
+ va_start(ap, fmt);
+ res = vfscang(f, fmt, ap);
+ va_end(ap);
+ return res;
+ }
+
+ int vfscang(GFILE *f, const char *fmt, va_list arg) {
+ int res, width, size, base;
+ char c;
+ bool_t assign;
+ void *p;
+
+ for(res = 0; *fmt; fmt++) {
+ switch(*fmt) {
+ case ' ': case '\t': case '\r': case '\n': case '\v': case '\f':
+ break;
+
+ case '%':
+ fmt++;
+ assign = TRUE;
+ width = 0;
+ size = 1;
+
+ if (*fmt == '*') {
+ fmt++;
+ assign = FALSE;
+ }
+ while(*fmt >= '0' && *fmt <= '9')
+ width = width * 10 + (*fmt++ - '0');
+ if (*fmt == 'h') {
+ fmt++;
+ size = 0;
+ } else if (*fmt == 'l') {
+ fmt++;
+ size = 2;
+ } else if (*fmt == 'L') {
+ fmt++;
+ size = 3;
+ }
+ switch(*fmt) {
+ case 0:
+ return res;
+ case '%':
+ goto matchchar;
+ case 'c':
+ if (!width) {
+ while(1) {
+ if (!gfileRead(f, &c, 1)) return res;
+ switch(c) {
+ case ' ': case '\t': case '\r':
+ case '\n': case '\v': case '\f': continue;
+ }
+ break;
+ }
+ width = 1;
+ } else {
+ if (!gfileRead(f, &c, 1)) return res;
+ }
+ if (assign) {
+ p = va_arg(ap, char *);
+ res++;
+ *((char *)p)++ = c;
+ }
+ while(--width) {
+ if (!gfileRead(f, &c, 1)) return res;
+ if (assign) *((char *)p)++ = c;
+ }
+ break;
+ case 's':
+ while(1) {
+ if (!gfileRead(f, &c, 1)) return res;
+ switch(c) {
+ case ' ': case '\t': case '\r':
+ case '\n': case '\v': case '\f': continue;
+ }
+ break;
+ }
+ if (assign) {
+ p = va_arg(ap, char *);
+ res++;
+ *((char *)p)++ = c;
+ }
+ if (width) {
+ while(--width) {
+ if (!gfileRead(f, &c, 1)) {
+ if (assign) *((char *)p) = 0;
+ return res;
+ }
+ if (assign) *((char *)p)++ = c;
+ }
+ } else {
+ while(1) {
+ if (!gfileRead(f, &c, 1)) {
+ if (assign) *((char *)p) = 0;
+ return res;
+ }
+ switch(c) {
+ case ' ': case '\t': case '\r':
+ case '\n': case '\v': case '\f': break;
+ default:
+ if (assign) *((char *)p)++ = c;
+ continue;
+ }
+ break;
+ }
+ //ungetch(c);
+ }
+ if (assign) *((char *)p) = 0;
+ break;
+ case 'd':
+ case 'i':
+ case 'o':
+ case 'u':
+ case 'x':
+ case 'b':
+ /*
+ while (isspace (*buf))
+ buf++;
+ if (*s == 'd' || *s == 'u')
+ base = 10;
+ else if (*s == 'x')
+ base = 16;
+ else if (*s == 'o')
+ base = 8;
+ else if (*s == 'b')
+ base = 2;
+ if (!width) {
+ if (isspace (*(s + 1)) || *(s + 1) == 0)
+ width = strcspn (buf, ISSPACE);
+ else
+ width = strchr (buf, *(s + 1)) - buf;
+ }
+ strncpy (tmp, buf, width);
+ tmp[width] = '\0';
+ buf += width;
+ if (!noassign)
+ atob (va_arg (ap, u_int32_t *), tmp, base);
+ }
+ if (!noassign)
+ count++;
+ */
+
+ #if GFILE_ALLOW_FLOATS
+ case 'e': case 'f': case 'g':
+ #endif
+ default:
+ return res;
+ }
+
+ break;
+
+ default:
+ matchchar:
+ while(1) {
+ if (!gfileRead(f, &c, 1)) return res;
+ switch(c) {
+ case ' ': case '\t': case '\r':
+ case '\n': case '\v': case '\f': continue;
+ }
+ break;
+ }
+ if (c != *fmt) return res;
+ break;
+ }
+ }
+ return res;
+ }
+
+ #if GFILE_NEED_STRINGS
+ int sscang(const char *buf, const char *fmt, ...) {
+ int res;
+ GFILE f;
+ va_list ap;
+
+ f.flags = GFILEFLG_OPEN|GFILEFLG_READ;
+ f.vmt = &StringVMT;
+ f.pos = 0;
+ f.obj = buf;
+ va_start(ap, fmt);
+ res = vfscang(&f, fmt, ap);
+ va_end(ap);
+ return res;
+ }
+
+ int vsscang(const char *buf, const char *fmt, va_list arg) {
+ int res;
+ GFILE f;
+
+ f.flags = GFILEFLG_OPEN|GFILEFLG_READ;
+ f.vmt = &StringVMT;
+ f.pos = 0;
+ f.obj = buf;
+ res = vfscang(&f, fmt, arg);
+ return res;
+ }
+ #endif
#endif
/********************************************************