diff --git a/src/gfile/gfile.c b/src/gfile/gfile.c index caf7f22f..595bba1f 100644 --- a/src/gfile/gfile.c +++ b/src/gfile/gfile.c @@ -11,183 +11,65 @@ * */ -#define GFILE_IMPLEMENTATION - #include "gfx.h" #if GFX_USE_GFILE -struct GFILE { - const struct GFILEVMT * vmt; - uint16_t flags; - #define GFILEFLG_OPEN 0x0001 // File is open - #define GFILEFLG_READ 0x0002 // Read the file - #define GFILEFLG_WRITE 0x0004 // Write the file - #define GFILEFLG_APPEND 0x0008 // Append on each write - #define GFILEFLG_BINARY 0x0010 // Treat as a binary file - #define GFILEFLG_DELONCLOSE 0x0020 // Delete on close - #define GFILEFLG_CANSEEK 0x0040 // Seek operations are valid - #define GFILEFLG_FAILONBLOCK 0x0080 // Fail on a blocking call - #define GFILEFLG_MUSTEXIST 0x0100 // On open file must exist - #define GFILEFLG_MUSTNOTEXIST 0x0200 // On open file must not exist - #define GFILEFLG_TRUNC 0x0400 // On open truncate the file - void * obj; - long int pos; -}; +#include "gfile_fs.h" -struct gfileList { - const struct GFILEVMT * vmt; - bool_t dirs; -}; +/** + * Define the VMT's for the file-systems we want to search for files. + * Virtual file-systems that have special open() calls do not need to + * be in this list. + */ +#if GFILE_NEED_ROMFS + extern const GFILEVMT FsROMVMT; +#endif +#if GFILE_NEED_NATIVEFS + extern const GFILEVMT FsNativeVMT; +#endif +#if GFILE_NEED_FATFS + extern const GFILEVMT FsFatFSVMT; +#endif +#if GFILE_NEED_RAMFS + extern const GFILEVMT FsRAMVMT; +#endif -typedef struct GFILEVMT { - const struct GFILEVMT * next; - uint8_t flags; - #define GFSFLG_WRITEABLE 0x0001 - #define GFSFLG_CASESENSITIVE 0x0002 - #define GFSFLG_SEEKABLE 0x0004 - #define GFSFLG_FAST 0x0010 - #define GFSFLG_SMALL 0x0020 - #define GFSFLG_TEXTMODES 0x0040 - char prefix; - bool_t (*del) (const char *fname); - bool_t (*exists) (const char *fname); - long int (*filesize) (const char *fname); - bool_t (*ren) (const char *oldname, const char *newname); - bool_t (*open) (GFILE *f, const char *fname); - void (*close) (GFILE *f); - int (*read) (GFILE *f, void *buf, int size); - int (*write) (GFILE *f, const void *buf, int size); - bool_t (*setpos) (GFILE *f, long int pos); - long int (*getsize) (GFILE *f); - bool_t (*eof) (GFILE *f); - bool_t (*mount) (const char *drive); - bool_t (*unmount) (const char *drive); - bool_t (*sync) (GFILE *f); - #if GFILE_NEED_FILELISTS - gfileList * (*flopen) (const char *path, bool_t dirs); - const char *(*flread) (gfileList *pfl); - void (*flclose) (gfileList *pfl); - #endif -} GFILEVMT; - -// The chain of FileSystems -#define GFILE_CHAINHEAD 0 - -// The table of GFILE's -static GFILE gfileArr[GFILE_MAX_GFILES]; -GFILE *gfileStdIn; -GFILE *gfileStdOut; -GFILE *gfileStdErr; - -// Forward definition used by some special open calls -static GFILE *findemptyfile(const char *mode); /** * The order of the file-systems below determines the order * that they are searched to find a file. - * The last defined is the first searched. */ +static const GFILEVMT const * FsArray[] = { + #if GFILE_NEED_ROMFS + &FsROMVMT, + #endif + #if GFILE_NEED_NATIVEFS + &FsNativeVMT, + #endif + #if GFILE_NEED_FATFS + &FsFatFSVMT, + #endif + #if GFILE_NEED_RAMFS + &FsRAMVMT, + #endif +}; -/******************************************************** - * The ChibiOS BaseFileStream VMT - ********************************************************/ -#if GFILE_NEED_CHIBIOSFS && GFX_USE_OS_CHIBIOS - #include "src/gfile/inc_chibiosfs.c" -#endif - -/******************************************************** - * The Memory Pointer VMT - ********************************************************/ -#if GFILE_NEED_MEMFS - #include "src/gfile/inc_memfs.c" -#endif - -/******************************************************** - * The RAM file-system VMT - ********************************************************/ -#if GFILE_NEED_RAMFS - #include "src/gfile/inc_ramfs.c" -#endif - -/******************************************************** - * The FAT file-system VMT - ********************************************************/ -#if GFILE_NEED_FATFS - #include "src/gfile/inc_fatfs.c" -#endif - -/******************************************************** - * The native file-system - ********************************************************/ -#if GFILE_NEED_NATIVEFS - #include "src/gfile/inc_nativefs.c" -#endif - -/******************************************************** - * The ROM file-system VMT - ********************************************************/ -#if GFILE_NEED_ROMFS - #include "src/gfile/inc_romfs.c" -#endif - -/******************************************************** - * The virtual string file VMT - ********************************************************/ -#if GFILE_NEED_STRINGS - #include "src/gfile/inc_strings.c" -#endif - -/******************************************************** - * Printg Routines - ********************************************************/ -#if GFILE_NEED_PRINTG - #include "src/gfile/inc_printg.c" -#endif - -/******************************************************** - * Scang Routines - ********************************************************/ -#if GFILE_NEED_SCANG - #include "src/gfile/inc_scang.c" -#endif - -/******************************************************** - * Stdio Emulation Routines - ********************************************************/ -#if GFILE_NEED_STDIO - #include "src/gfile/inc_stdio.c" -#endif - -/******************************************************** - * IO routines - ********************************************************/ - -/** - * The chain of file systems. +/* + * The table of GFILE's */ -static const GFILEVMT const * FsChain = GFILE_CHAINHEAD; +static GFILE gfileArr[GFILE_MAX_GFILES]; +GFILE *gfileStdIn; +GFILE *gfileStdOut; +GFILE *gfileStdErr; /** * The init routine */ void _gfileInit(void) { #if GFILE_NEED_NATIVEFS - NativeStdIn.flags = GFILEFLG_OPEN|GFILEFLG_READ; - NativeStdIn.vmt = &FsNativeVMT; - NativeStdIn.obj = (void *)stdin; - NativeStdIn.pos = 0; - gfileStdIn = &NativeStdIn; - NativeStdOut.flags = GFILEFLG_OPEN|GFILEFLG_WRITE|GFILEFLG_APPEND; - NativeStdOut.vmt = &FsNativeVMT; - NativeStdOut.obj = (void *)stdout; - NativeStdOut.pos = 0; - gfileStdOut = &NativeStdOut; - NativeStdErr.flags = GFILEFLG_OPEN|GFILEFLG_WRITE|GFILEFLG_APPEND; - NativeStdErr.vmt = &FsNativeVMT; - NativeStdErr.obj = (void *)stderr; - NativeStdErr.pos = 0; - gfileStdErr = &NativeStdErr; + extern void _gfileNativeAssignStdio(void); + _gfileNativeAssignStdio(); #endif } @@ -196,103 +78,10 @@ void _gfileDeinit(void) /* ToDo */ } -bool_t gfileExists(const char *fname) { - const GFILEVMT *p; - - #if GFILE_ALLOW_DEVICESPECIFIC - if (fname[0] && fname[1] == '|') { - for(p = FsChain; p; p = p->next) { - if (p->prefix == fname[0]) - return p->exists && p->exists(fname+2); - } - return FALSE; - } - #endif - - for(p = FsChain; p; p = p->next) { - if (p->exists && p->exists(fname)) - return TRUE; - } - return FALSE; -} - -bool_t gfileDelete(const char *fname) { - const GFILEVMT *p; - - #if GFILE_ALLOW_DEVICESPECIFIC - if (fname[0] && fname[1] == '|') { - for(p = FsChain; p; p = p->next) { - if (p->prefix == fname[0]) - return p->del && p->del(fname+2); - } - return FALSE; - } - #endif - - for(p = FsChain; p; p = p->next) { - if (p->del && p->del(fname)) - return TRUE; - } - return FALSE; -} - -long int gfileGetFilesize(const char *fname) { - const GFILEVMT *p; - long int res; - - #if GFILE_ALLOW_DEVICESPECIFIC - if (fname[0] && fname[1] == '|') { - for(p = FsChain; p; p = p->next) { - if (p->prefix == fname[0]) - return p->filesize ? p->filesize(fname+2) : -1; - } - return -1; - } - #endif - - for(p = FsChain; p; p = p->next) { - if (p->filesize && (res = p->filesize(fname)) != -1) - return res; - } - return -1; -} - -bool_t gfileRename(const char *oldname, const char *newname) { - const GFILEVMT *p; - - #if GFILE_ALLOW_DEVICESPECIFIC - if ((oldname[0] && oldname[1] == '|') || (newname[0] && newname[1] == '|')) { - char ch; - - if (oldname[0] && oldname[1] == '|') { - ch = oldname[0]; - oldname += 2; - if (newname[0] && newname[1] == '|') { - if (newname[0] != ch) - // Both oldname and newname are fs specific but different ones. - return FALSE; - newname += 2; - } - } else { - ch = newname[0]; - newname += 2; - } - for(p = FsChain; p; p = p->next) { - if (p->prefix == ch) - return p->ren && p->ren(oldname, newname); - } - return FALSE; - } - #endif - - for(p = FsChain; p; p = p->next) { - if (p->ren && p->ren(oldname,newname)) - return TRUE; - } - return FALSE; -} - -static GFILE *findemptyfile(const char *mode) { +/** + * Internal routine to find an empty GFILE slot and interpret flags. + */ +GFILE *_gfileFindSlot(const char *mode) { GFILE * f; // First find an available GFILE slot. @@ -338,6 +127,106 @@ static GFILE *findemptyfile(const char *mode) { return 0; } +/******************************************************** + * IO routines + ********************************************************/ + +bool_t gfileExists(const char *fname) { + const GFILEVMT * const *p; + + #if GFILE_ALLOW_DEVICESPECIFIC + if (fname[0] && fname[1] == '|') { + for(p = FsArray; p < &FsArray[sizeof(FsArray)/sizeof(FsArray[0])]; p++) { + if (p[0]->prefix == fname[0]) + return p[0]->exists && p[0]->exists(fname+2); + } + return FALSE; + } + #endif + + for(p = FsArray; p < &FsArray[sizeof(FsArray)/sizeof(FsArray[0])]; p++) { + if (p[0]->exists && p[0]->exists(fname)) + return TRUE; + } + return FALSE; +} + +bool_t gfileDelete(const char *fname) { + const GFILEVMT **p; + + #if GFILE_ALLOW_DEVICESPECIFIC + if (fname[0] && fname[1] == '|') { + for(p = FsArray; p < &FsArray[sizeof(FsArray)/sizeof(FsArray[0])]; p++) { + if (p[0]->prefix == fname[0]) + return p[0]->del && p[0]->del(fname+2); + } + return FALSE; + } + #endif + + for(p = FsArray; p < &FsArray[sizeof(FsArray)/sizeof(FsArray[0])]; p++) { + if (p[0]->del && p[0]->del(fname)) + return TRUE; + } + return FALSE; +} + +long int gfileGetFilesize(const char *fname) { + const GFILEVMT * const *p; + long int res; + + #if GFILE_ALLOW_DEVICESPECIFIC + if (fname[0] && fname[1] == '|') { + for(p = FsArray; p < &FsArray[sizeof(FsArray)/sizeof(FsArray[0])]; p++) { + if (p[0]->prefix == fname[0]) + return p[0]->filesize ? p[0]->filesize(fname+2) : -1; + } + return -1; + } + #endif + + for(p = FsArray; p < &FsArray[sizeof(FsArray)/sizeof(FsArray[0])]; p++) { + if (p[0]->filesize && (res = p[0]->filesize(fname)) != -1) + return res; + } + return -1; +} + +bool_t gfileRename(const char *oldname, const char *newname) { + const GFILEVMT * const *p; + + #if GFILE_ALLOW_DEVICESPECIFIC + if ((oldname[0] && oldname[1] == '|') || (newname[0] && newname[1] == '|')) { + char ch; + + if (oldname[0] && oldname[1] == '|') { + ch = oldname[0]; + oldname += 2; + if (newname[0] && newname[1] == '|') { + if (newname[0] != ch) + // Both oldname and newname are fs specific but different ones. + return FALSE; + newname += 2; + } + } else { + ch = newname[0]; + newname += 2; + } + for(p = FsArray; p < &FsArray[sizeof(FsArray)/sizeof(FsArray[0])]; p++) { + if (p[0]->prefix == ch) + return p[0]->ren && p[0]->ren(oldname, newname); + } + return FALSE; + } + #endif + + for(p = FsArray; p < &FsArray[sizeof(FsArray)/sizeof(FsArray[0])]; p++) { + if (p[0]->ren && p[0]->ren(oldname,newname)) + return TRUE; + } + return FALSE; +} + static bool_t testopen(const GFILEVMT *p, GFILE *f, const char *fname) { // If we want write but the fs doesn't allow it then return if ((f->flags & GFILEFLG_WRITE) && !(p->flags & GFSFLG_WRITEABLE)) @@ -358,17 +247,17 @@ static bool_t testopen(const GFILEVMT *p, GFILE *f, const char *fname) { GFILE *gfileOpen(const char *fname, const char *mode) { GFILE * f; - const GFILEVMT *p; + const GFILEVMT * const *p; // Get an empty file and set the flags - if (!(f = findemptyfile(mode))) + if (!(f = _gfileFindSlot(mode))) return 0; #if GFILE_ALLOW_DEVICESPECIFIC if (fname[0] && fname[1] == '|') { - for(p = FsChain; p; p = p->next) { - if (p->prefix == fname[0]) - return testopen(p, f, fname+2) ? f : 0; + for(p = FsArray; p < &FsArray[sizeof(FsArray)/sizeof(FsArray[0])]; p++) { + if (p[0]->prefix == fname[0]) + return testopen(p[0], f, fname+2) ? f : 0; } // File not found @@ -376,8 +265,8 @@ GFILE *gfileOpen(const char *fname, const char *mode) { } #endif - for(p = FsChain; p; p = p->next) { - if (testopen(p, f, fname)) + for(p = FsArray; p < &FsArray[sizeof(FsArray)/sizeof(FsArray[0])]; p++) { + if (testopen(p[0], f, fname)) return f; } @@ -451,28 +340,28 @@ bool_t gfileEOF(GFILE *f) { } bool_t gfileMount(char fs, const char* drive) { - const GFILEVMT *p; + const GFILEVMT * const *p; // Find the correct VMT - for(p = FsChain; p; p = p->next) { - if (p->prefix == fs) { - if (!p->mount) + for(p = FsArray; p < &FsArray[sizeof(FsArray)/sizeof(FsArray[0])]; p++) { + if (p[0]->prefix == fs) { + if (!p[0]->mount) return FALSE; - return p->mount(drive); + return p[0]->mount(drive); } } return FALSE; } bool_t gfileUnmount(char fs, const char* drive) { - const GFILEVMT *p; + const GFILEVMT * const *p; // Find the correct VMT - for(p = FsChain; p; p = p->next) { - if (p->prefix == fs) { - if (!p->mount) + for(p = FsArray; p < &FsArray[sizeof(FsArray)/sizeof(FsArray[0])]; p++) { + if (p[0]->prefix == fs) { + if (!p[0]->mount) return FALSE; - return p->unmount(drive); + return p[0]->unmount(drive); } } return FALSE; @@ -486,17 +375,17 @@ bool_t gfileSync(GFILE *f) { #if GFILE_NEED_FILELISTS gfileList *gfileOpenFileList(char fs, const char *path, bool_t dirs) { - const GFILEVMT *p; + const GFILEVMT * const *p; gfileList * pfl; // Find the correct VMT - for(p = FsChain; p; p = p->next) { - if (p->prefix == fs) { - if (!p->flopen) + for(p = FsArray; p < &FsArray[sizeof(FsArray)/sizeof(FsArray[0])]; p++) { + if (p[0]->prefix == fs) { + if (!p[0]->flopen) return 0; - pfl = p->flopen(path, dirs); + pfl = p[0]->flopen(path, dirs); if (pfl) { - pfl->vmt = p; + pfl->vmt = p[0]; pfl->dirs = dirs; } return pfl; diff --git a/src/gfile/gfile_fs.h b/src/gfile/gfile_fs.h new file mode 100644 index 00000000..c2337283 --- /dev/null +++ b/src/gfile/gfile_fs.h @@ -0,0 +1,72 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +/** + * @file src/gfile/gfile_fs.h + * @brief GFILE file system header. + * + */ + +#ifndef _GFILE_FS_H +#define _GFILE_FS_H + +struct GFILE { + const struct GFILEVMT * vmt; + uint16_t flags; + #define GFILEFLG_OPEN 0x0001 // File is open + #define GFILEFLG_READ 0x0002 // Read the file + #define GFILEFLG_WRITE 0x0004 // Write the file + #define GFILEFLG_APPEND 0x0008 // Append on each write + #define GFILEFLG_BINARY 0x0010 // Treat as a binary file + #define GFILEFLG_DELONCLOSE 0x0020 // Delete on close + #define GFILEFLG_CANSEEK 0x0040 // Seek operations are valid + #define GFILEFLG_FAILONBLOCK 0x0080 // Fail on a blocking call + #define GFILEFLG_MUSTEXIST 0x0100 // On open file must exist + #define GFILEFLG_MUSTNOTEXIST 0x0200 // On open file must not exist + #define GFILEFLG_TRUNC 0x0400 // On open truncate the file + void * obj; + long int pos; +}; + +struct gfileList { + const struct GFILEVMT * vmt; + bool_t dirs; +}; + +typedef struct GFILEVMT { + uint8_t flags; + #define GFSFLG_WRITEABLE 0x0001 + #define GFSFLG_CASESENSITIVE 0x0002 + #define GFSFLG_SEEKABLE 0x0004 + #define GFSFLG_FAST 0x0010 + #define GFSFLG_SMALL 0x0020 + #define GFSFLG_TEXTMODES 0x0040 + char prefix; + bool_t (*del) (const char *fname); + bool_t (*exists) (const char *fname); + long int (*filesize) (const char *fname); + bool_t (*ren) (const char *oldname, const char *newname); + bool_t (*open) (GFILE *f, const char *fname); + void (*close) (GFILE *f); + int (*read) (GFILE *f, void *buf, int size); + int (*write) (GFILE *f, const void *buf, int size); + bool_t (*setpos) (GFILE *f, long int pos); + long int (*getsize) (GFILE *f); + bool_t (*eof) (GFILE *f); + bool_t (*mount) (const char *drive); + bool_t (*unmount) (const char *drive); + bool_t (*sync) (GFILE *f); + #if GFILE_NEED_FILELISTS + gfileList * (*flopen) (const char *path, bool_t dirs); + const char *(*flread) (gfileList *pfl); + void (*flclose) (gfileList *pfl); + #endif +} GFILEVMT; + +GFILE *_gfileFindSlot(const char *mode); + +#endif //_GFILE_FS_H diff --git a/src/gfile/inc_chibiosfs.c b/src/gfile/inc_chibiosfs.c index 13ae6cac..72826e28 100644 --- a/src/gfile/inc_chibiosfs.c +++ b/src/gfile/inc_chibiosfs.c @@ -5,14 +5,16 @@ * http://ugfx.org/license.html */ -/** - * This file is included by src/gfile/gfile.c - */ - /******************************************************** - * The ChibiOS BaseFileStream file-system VMT + * The ChibiOS BaseFileStream file-system ********************************************************/ +#include "gfx.h" + +#if GFX_USE_GFILE && GFILE_NEED_CHIBIOSFS && GFX_USE_OS_CHIBIOS + +#include "gfile_fs.h" + static void ChibiOSBFSClose(GFILE *f); static int ChibiOSBFSRead(GFILE *f, void *buf, int size); static int ChibiOSBFSWrite(GFILE *f, const void *buf, int size); @@ -21,7 +23,6 @@ static long int ChibiOSBFSGetsize(GFILE *f); static bool_t ChibiOSBFSEof(GFILE *f); static const GFILEVMT FsCHIBIOSVMT = { - 0, // next GFSFLG_SEEKABLE|GFSFLG_WRITEABLE, // flags 0, // prefix 0, 0, 0, 0, @@ -53,7 +54,7 @@ GFILE * gfileOpenBaseFileStream(void *BaseFileStreamPtr, const char *mode) { GFILE * f; // Get an empty file and set the flags - if (!(f = findemptyfile(mode))) + if (!(f = _gfileFindSlot(mode))) return 0; // File is open - fill in all the details @@ -63,3 +64,5 @@ GFILE * gfileOpenBaseFileStream(void *BaseFileStreamPtr, const char *mode) { f->flags |= GFILEFLG_OPEN|GFILEFLG_CANSEEK; return f; } + +#endif //GFX_USE_GFILE && GFILE_NEED_CHIBIOSFS && GFX_USE_OS_CHIBIOS diff --git a/src/gfile/inc_fatfs.c b/src/gfile/inc_fatfs.c index 11df1055..b5eee725 100644 --- a/src/gfile/inc_fatfs.c +++ b/src/gfile/inc_fatfs.c @@ -5,10 +5,15 @@ * http://ugfx.org/license.html */ -/** - * This file is included by src/gfile/gfile.c - */ +/******************************************************** + * The FATFS file-system + ********************************************************/ +#include "gfx.h" + +#if GFX_USE_GFILE && GFILE_NEED_FATFS + +#include "gfile_fs.h" #include "fatfs_wrapper.h" /******************************************************** @@ -35,8 +40,7 @@ static bool_t fatfsSync(GFILE* f); static void fatfsFlClose(gfileList *pfl); #endif -static const GFILEVMT FsFatFSVMT = { - GFILE_CHAINHEAD, +const GFILEVMT FsFatFSVMT = { GFSFLG_WRITEABLE | GFSFLG_SEEKABLE, 'F', fatfsDel, @@ -60,9 +64,6 @@ static const GFILEVMT FsFatFSVMT = { #endif }; -#undef GFILE_CHAINHEAD -#define GFILE_CHAINHEAD &FsFatFSVMT - // Our directory list structure typedef struct fatfsList { gfileList fl; // This must be the first element. @@ -319,3 +320,6 @@ static bool_t fatfsSync(GFILE *f) } #endif + +#endif //GFX_USE_GFILE && GFILE_NEED_FATFS + diff --git a/src/gfile/inc_memfs.c b/src/gfile/inc_memfs.c index 6177b7d8..150220b8 100644 --- a/src/gfile/inc_memfs.c +++ b/src/gfile/inc_memfs.c @@ -5,14 +5,16 @@ * http://ugfx.org/license.html */ -/** - * This file is included by src/gfile/gfile.c - */ - /******************************************************** - * The Memory pointer file-system VMT + * The virtual memory file-system ********************************************************/ +#include "gfx.h" + +#if GFX_USE_GFILE && GFILE_NEED_MEMFS + +#include "gfile_fs.h" + #include static int MEMRead(GFILE *f, void *buf, int size); @@ -20,7 +22,6 @@ static int MEMWrite(GFILE *f, const void *buf, int size); static bool_t MEMSetpos(GFILE *f, long int pos); static const GFILEVMT FsMemVMT = { - 0, // next GFSFLG_SEEKABLE|GFSFLG_WRITEABLE, // flags 0, // prefix 0, 0, 0, 0, @@ -50,7 +51,7 @@ GFILE * gfileOpenMemory(void *memptr, const char *mode) { GFILE *f; // Get an empty file and set the flags - if (!(f = findemptyfile(mode))) + if (!(f = _gfileFindSlot(mode))) return 0; // File is open - fill in all the details @@ -60,3 +61,5 @@ GFILE * gfileOpenMemory(void *memptr, const char *mode) { f->flags |= GFILEFLG_OPEN|GFILEFLG_CANSEEK; return f; } + +#endif //GFX_USE_GFILE && GFILE_NEED_MEMFS diff --git a/src/gfile/inc_nativefs.c b/src/gfile/inc_nativefs.c index 8c28480b..b8441ac7 100644 --- a/src/gfile/inc_nativefs.c +++ b/src/gfile/inc_nativefs.c @@ -5,23 +5,21 @@ * http://ugfx.org/license.html */ -/** - * This file is included by src/gfile/gfile.c - */ - /******************************************************** * The native file-system ********************************************************/ +#include "gfx.h" + +#if GFX_USE_GFILE && GFILE_NEED_NATIVEFS + +#include "gfile_fs.h" + #include #include #include //#include -static GFILE NativeStdIn; -static GFILE NativeStdOut; -static GFILE NativeStdErr; - static bool_t NativeDel(const char *fname); static bool_t NativeExists(const char *fname); static long int NativeFilesize(const char *fname); @@ -39,8 +37,7 @@ static bool_t NativeEof(GFILE *f); static void NativeFlClose(gfileList *pfl); #endif -static const GFILEVMT FsNativeVMT = { - GFILE_CHAINHEAD, // next +const GFILEVMT FsNativeVMT = { #if defined(WIN32) || GFX_USE_OS_WIN32 GFSFLG_TEXTMODES| #else @@ -56,8 +53,28 @@ static const GFILEVMT FsNativeVMT = { NativeFlOpen, NativeFlRead, NativeFlClose #endif }; -#undef GFILE_CHAINHEAD -#define GFILE_CHAINHEAD &FsNativeVMT + +void _gfileNativeAssignStdio(void) { + static GFILE NativeStdIn; + static GFILE NativeStdOut; + static GFILE NativeStdErr; + + NativeStdIn.flags = GFILEFLG_OPEN|GFILEFLG_READ; + NativeStdIn.vmt = &FsNativeVMT; + NativeStdIn.obj = (void *)stdin; + NativeStdIn.pos = 0; + gfileStdIn = &NativeStdIn; + NativeStdOut.flags = GFILEFLG_OPEN|GFILEFLG_WRITE|GFILEFLG_APPEND; + NativeStdOut.vmt = &FsNativeVMT; + NativeStdOut.obj = (void *)stdout; + NativeStdOut.pos = 0; + gfileStdOut = &NativeStdOut; + NativeStdErr.flags = GFILEFLG_OPEN|GFILEFLG_WRITE|GFILEFLG_APPEND; + NativeStdErr.vmt = &FsNativeVMT; + NativeStdErr.obj = (void *)stderr; + NativeStdErr.pos = 0; + gfileStdErr = &NativeStdErr; +} static void Native_flags2mode(char *buf, uint16_t flags) { if (flags & GFILEFLG_MUSTEXIST) @@ -214,3 +231,5 @@ static long int NativeGetsize(GFILE *f) { } #endif #endif + +#endif //GFX_USE_GFILE && GFILE_NEED_NATIVEFS diff --git a/src/gfile/inc_printg.c b/src/gfile/inc_printg.c index 8d24b347..33db8bc8 100644 --- a/src/gfile/inc_printg.c +++ b/src/gfile/inc_printg.c @@ -5,14 +5,14 @@ * http://ugfx.org/license.html */ -/** - * This file is included by src/gfile/gfile.c - */ - /******************************************************** * Printg Routines ********************************************************/ +#include "gfx.h" + +#if GFX_USE_GFILE && GFILE_NEED_PRINTG + #include #define MAX_FILLER 11 @@ -220,42 +220,4 @@ int vfnprintg(GFILE *f, int maxlen, const char *fmt, va_list arg) { return ret; } -#if GFILE_NEED_STRINGS - int snprintg(char *buf, int maxlen, const char *fmt, ...) { - int res; - GFILE f; - va_list ap; - - if (maxlen <= 1) { - if (maxlen == 1) { - *buf = 0; - return 0; - } - maxlen += 1; - } - - f.flags = GFILEFLG_WRITE|GFILEFLG_TRUNC; - gfileOpenStringFromStaticGFILE(&f, buf); - - va_start(ap, fmt); - res = vfnprintg(&f, maxlen-1, fmt, ap); - va_end(ap); - return res; - } - int vsnprintg(char *buf, int maxlen, const char *fmt, va_list arg) { - GFILE f; - - if (maxlen <= 1) { - if (maxlen == 1) { - *buf = 0; - return 0; - } - maxlen += 1; - } - - f.flags = GFILEFLG_WRITE|GFILEFLG_TRUNC; - gfileOpenStringFromStaticGFILE(&f, buf); - - return vfnprintg(&f, maxlen-1, fmt, arg); - } -#endif +#endif //GFX_USE_GFILE && GFILE_NEED_PRINTG diff --git a/src/gfile/inc_ramfs.c b/src/gfile/inc_ramfs.c index b0f0d052..f71eff6c 100644 --- a/src/gfile/inc_ramfs.c +++ b/src/gfile/inc_ramfs.c @@ -5,11 +5,28 @@ * http://ugfx.org/license.html */ -/** - * This file is included by src/gfile/gfile.c - */ - /******************************************************** - * The RAM file-system VMT + * The RAM file-system ********************************************************/ + +#include "gfx.h" + +#if GFX_USE_GFILE && GFILE_NEED_RAMFS + +#include "gfile_fs.h" + #error "GFILE: RAMFS Not implemented yet" + +const GFILEVMT FsRAMVMT = { + 0, // flags + 'R', // prefix + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + #if GFILE_NEED_FILELISTS + 0, 0, 0, + #endif +}; + +#endif //GFX_USE_GFILE && GFILE_NEED_RAMFS diff --git a/src/gfile/inc_romfs.c b/src/gfile/inc_romfs.c index 97d26239..6b7719c7 100644 --- a/src/gfile/inc_romfs.c +++ b/src/gfile/inc_romfs.c @@ -5,14 +5,16 @@ * http://ugfx.org/license.html */ -/** - * This file is included by src/gfile/gfile.c - */ - /******************************************************** - * The ROM file-system VMT + * The ROM file-system ********************************************************/ +#include "gfx.h" + +#if GFX_USE_GFILE && GFILE_NEED_ROMFS + +#include "gfile_fs.h" + #include // What directory file formats do we understand @@ -54,8 +56,7 @@ static bool_t ROMEof(GFILE *f); static void ROMFlClose(gfileList *pfl); #endif -static const GFILEVMT FsROMVMT = { - GFILE_CHAINHEAD, // next +const GFILEVMT FsROMVMT = { GFSFLG_CASESENSITIVE|GFSFLG_SEEKABLE|GFSFLG_FAST, // flags 'S', // prefix 0, ROMExists, ROMFilesize, 0, @@ -66,8 +67,6 @@ static const GFILEVMT FsROMVMT = { ROMFlOpen, ROMFlRead, ROMFlClose #endif }; -#undef GFILE_CHAINHEAD -#define GFILE_CHAINHEAD &FsROMVMT static const ROMFS_DIRENTRY *ROMFindFile(const char *fname) { @@ -175,3 +174,5 @@ static bool_t ROMEof(GFILE *f) gfxFree(pfl); } #endif + +#endif //GFX_USE_GFILE && GFILE_NEED_ROMFS diff --git a/src/gfile/inc_scang.c b/src/gfile/inc_scang.c index 8dcc8d0f..5fac5ce3 100644 --- a/src/gfile/inc_scang.c +++ b/src/gfile/inc_scang.c @@ -5,14 +5,14 @@ * http://ugfx.org/license.html */ -/** - * This file is included by src/gfile/gfile.c - */ - /******************************************************** * Scang Routines ********************************************************/ +#include "gfx.h" + +#if GFX_USE_GFILE && GFILE_NEED_SCANG + int fscang(GFILE *f, const char *fmt, ...) { int res; va_list ap; @@ -231,27 +231,4 @@ int vfscang(GFILE *f, const char *fmt, va_list arg) { return res; } -#if GFILE_NEED_STRINGS - int sscang(const char *buf, const char *fmt, ...) { - int res; - GFILE f; - va_list ap; - - f.flags = GFILEFLG_READ; - gfileOpenStringFromStaticGFILE(&f, (char *)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) { - GFILE f; - - f.flags = GFILEFLG_READ; - gfileOpenStringFromStaticGFILE(&f, (char *)buf); - - return vfscang(&f, fmt, arg); - } -#endif +#endif //GFX_USE_GFILE && GFILE_NEED_SCANG diff --git a/src/gfile/inc_stdio.c b/src/gfile/inc_stdio.c index 8dc44dcb..20169ef2 100644 --- a/src/gfile/inc_stdio.c +++ b/src/gfile/inc_stdio.c @@ -5,14 +5,14 @@ * http://ugfx.org/license.html */ -/** - * This file is included by src/gfile/gfile.c - */ - /******************************************************** * Stdio Emulation Routines ********************************************************/ +#include "gfx.h" + +#if GFX_USE_GFILE && GFILE_NEED_STDIO + size_t gstdioRead(void * ptr, size_t size, size_t count, FILE *f) { return gfileRead(f, ptr, size*count)/size; } @@ -43,3 +43,5 @@ int gstdioGetpos(FILE *f, long int *pos) { *pos = f->pos; return 0; } + +#endif //GFX_USE_GFILE && GFILE_NEED_STDIO diff --git a/src/gfile/inc_strings.c b/src/gfile/inc_strings.c index 692d2dd3..35c1575c 100644 --- a/src/gfile/inc_strings.c +++ b/src/gfile/inc_strings.c @@ -5,14 +5,16 @@ * http://ugfx.org/license.html */ -/** - * This file is included by src/gfile/gfile.c - */ - /******************************************************** - * The virtual string file VMT + * The virtual string file ********************************************************/ +#include "gfx.h" + +#if GFX_USE_GFILE && GFILE_NEED_STRINGS + +#include "gfile_fs.h" + #include // Special String VMT @@ -34,8 +36,8 @@ static int StringWrite(GFILE *f, const void *buf, int size) { ((char *)f->obj)[f->pos+size] = 0; return size; } + static const GFILEVMT StringVMT = { - 0, // next 0, // flags '_', // prefix 0, 0, 0, 0, @@ -60,10 +62,77 @@ GFILE *gfileOpenString(char *str, const char *mode) { GFILE *f; // Get an empty file and set the flags - if (!(f = findemptyfile(mode))) + if (!(f = _gfileFindSlot(mode))) return 0; // File is open - fill in all the details gfileOpenStringFromStaticGFILE(f, str); return f; } + +#if GFILE_NEED_PRINTG + int snprintg(char *buf, int maxlen, const char *fmt, ...) { + int res; + GFILE f; + va_list ap; + + if (maxlen <= 1) { + if (maxlen == 1) { + *buf = 0; + return 0; + } + maxlen += 1; + } + + f.flags = GFILEFLG_WRITE|GFILEFLG_TRUNC; + gfileOpenStringFromStaticGFILE(&f, buf); + + va_start(ap, fmt); + res = vfnprintg(&f, maxlen-1, fmt, ap); + va_end(ap); + return res; + } + int vsnprintg(char *buf, int maxlen, const char *fmt, va_list arg) { + GFILE f; + + if (maxlen <= 1) { + if (maxlen == 1) { + *buf = 0; + return 0; + } + maxlen += 1; + } + + f.flags = GFILEFLG_WRITE|GFILEFLG_TRUNC; + gfileOpenStringFromStaticGFILE(&f, buf); + + return vfnprintg(&f, maxlen-1, fmt, arg); + } +#endif + +#if GFILE_NEED_SCANG + int sscang(const char *buf, const char *fmt, ...) { + int res; + GFILE f; + va_list ap; + + f.flags = GFILEFLG_READ; + gfileOpenStringFromStaticGFILE(&f, (char *)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) { + GFILE f; + + f.flags = GFILEFLG_READ; + gfileOpenStringFromStaticGFILE(&f, (char *)buf); + + return vfscang(&f, fmt, arg); + } +#endif + +#endif //GFX_USE_GFILE && GFILE_NEED_STRINGS diff --git a/src/gfile/sys_defs.h b/src/gfile/sys_defs.h index 81d72ac8..5a2d9845 100644 --- a/src/gfile/sys_defs.h +++ b/src/gfile/sys_defs.h @@ -31,13 +31,8 @@ * @brief A file pointer */ -#ifndef GFILE_IMPLEMENTATION - typedef void GFILE; - typedef void gfileList; -#else - typedef struct GFILE GFILE; - typedef struct gfileList gfileList; -#endif +typedef struct GFILE GFILE; +typedef struct gfileList gfileList; extern GFILE *gfileStdIn; extern GFILE *gfileStdErr; diff --git a/src/gfile/sys_make.mk b/src/gfile/sys_make.mk index c4bab064..ba74a15c 100644 --- a/src/gfile/sys_make.mk +++ b/src/gfile/sys_make.mk @@ -1,3 +1,13 @@ GFXSRC += $(GFXLIB)/src/gfile/gfile.c \ + $(GFXLIB)/src/gfile/inc_nativefs.c \ + $(GFXLIB)/src/gfile/inc_ramfs.c \ + $(GFXLIB)/src/gfile/inc_romfs.c \ + $(GFXLIB)/src/gfile/inc_fatfs.c \ + $(GFXLIB)/src/gfile/inc_memfs.c \ + $(GFXLIB)/src/gfile/inc_chibiosfs.c \ + $(GFXLIB)/src/gfile/inc_strings.c \ + $(GFXLIB)/src/gfile/inc_printg.c \ + $(GFXLIB)/src/gfile/inc_scang.c \ + $(GFXLIB)/src/gfile/inc_stdio.c \ $(GFXLIB)/src/gfile/fatfs_wrapper.c \ $(GFXLIB)/src/gfile/fatfs_chibios_diskio.c