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 /********************************************************