From 1105e38414fff26d6b1e278ee3bf19b9b981299c Mon Sep 17 00:00:00 2001
From: inmarket <andrewh@inmarket.com.au>
Date: Fri, 15 Aug 2014 00:31:32 +1000
Subject: Separate GFILE into separate source files to prevent future name and
 include file conflicts.

---
 src/gfile/gfile.c         | 385 +++++++++++++++++-----------------------------
 src/gfile/gfile_fs.h      |  72 +++++++++
 src/gfile/inc_chibiosfs.c |  17 +-
 src/gfile/inc_fatfs.c     |  20 ++-
 src/gfile/inc_memfs.c     |  17 +-
 src/gfile/inc_nativefs.c  |  43 ++++--
 src/gfile/inc_printg.c    |  48 +-----
 src/gfile/inc_ramfs.c     |  27 +++-
 src/gfile/inc_romfs.c     |  19 +--
 src/gfile/inc_scang.c     |  33 +---
 src/gfile/inc_stdio.c     |  10 +-
 src/gfile/inc_strings.c   |  83 +++++++++-
 src/gfile/sys_defs.h      |   9 +-
 src/gfile/sys_make.mk     |  10 ++
 14 files changed, 408 insertions(+), 385 deletions(-)
 create mode 100644 src/gfile/gfile_fs.h

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;
-};
-
-struct gfileList {
-	const struct GFILEVMT *	vmt;
-	bool_t					dirs;
-};
-
-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);
+#include "gfile_fs.h"
 
 /**
- * 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.
+ * 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.
  */
-
-/********************************************************
- * 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"
+	extern const GFILEVMT FsROMVMT;
 #endif
-
-/********************************************************
- * Printg Routines
- ********************************************************/
-#if GFILE_NEED_PRINTG
-	#include "src/gfile/inc_printg.c"
+#if GFILE_NEED_NATIVEFS
+	extern const GFILEVMT FsNativeVMT;
 #endif
-
-/********************************************************
- * Scang Routines
- ********************************************************/
-#if GFILE_NEED_SCANG
-	#include "src/gfile/inc_scang.c"
+#if GFILE_NEED_FATFS
+	extern const GFILEVMT FsFatFSVMT;
 #endif
-
-/********************************************************
- * Stdio Emulation Routines
- ********************************************************/
-#if GFILE_NEED_STDIO
-	#include "src/gfile/inc_stdio.c"
+#if GFILE_NEED_RAMFS
+	extern const GFILEVMT FsRAMVMT;
 #endif
 
-/********************************************************
- * IO routines
- ********************************************************/
 
 /**
- * The chain of file systems.
+ * The order of the file-systems below determines the order
+ * that they are searched to find a file.
  */
-static const GFILEVMT const * FsChain = GFILE_CHAINHEAD;
+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 table of GFILE's
+ */
+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,69 +78,122 @@ void _gfileDeinit(void)
 	/* ToDo */
 }
 
+/**
+ * Internal routine to find an empty GFILE slot and interpret flags.
+ */
+GFILE *_gfileFindSlot(const char *mode) {
+	GFILE *			f;
+
+	// First find an available GFILE slot.
+	for (f = gfileArr; f < &gfileArr[GFILE_MAX_GFILES]; f++) {
+		if (!(f->flags & GFILEFLG_OPEN)) {
+			// Get the flags
+			switch(mode[0]) {
+			case 'r':
+				f->flags = GFILEFLG_READ|GFILEFLG_MUSTEXIST;
+				while (*++mode) {
+					switch(mode[0]) {
+					case '+':	f->flags |= GFILEFLG_WRITE;			break;
+					case 'b':	f->flags |= GFILEFLG_BINARY;		break;
+					}
+				}
+				break;
+			case 'w':
+				f->flags = GFILEFLG_WRITE|GFILEFLG_TRUNC;
+				while (*++mode) {
+					switch(mode[0]) {
+					case '+':	f->flags |= GFILEFLG_READ;			break;
+					case 'b':	f->flags |= GFILEFLG_BINARY;		break;
+					case 'x':	f->flags |= GFILEFLG_MUSTNOTEXIST;	break;
+					}
+				}
+				break;
+			case 'a':
+				f->flags = GFILEFLG_WRITE|GFILEFLG_APPEND;
+				while (*++mode) {
+					switch(mode[0]) {
+					case '+':	f->flags |= GFILEFLG_READ;			break;
+					case 'b':	f->flags |= GFILEFLG_BINARY;		break;
+					case 'x':	f->flags |= GFILEFLG_MUSTNOTEXIST;	break;
+					}
+				}
+				break;
+			default:
+				return 0;
+			}
+			return f;
+		}
+	}
+	return 0;
+}
+
+/********************************************************
+ * IO routines
+ ********************************************************/
+
 bool_t gfileExists(const char *fname) {
-	const GFILEVMT *p;
+	const GFILEVMT * const *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);
+			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 = FsChain; p; p = p->next) {
-		if (p->exists && p->exists(fname))
+	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;
+	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);
+			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 = FsChain; p; p = p->next) {
-		if (p->del && p->del(fname))
+	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 *p;
+	const GFILEVMT * const *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;
+			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 = FsChain; p; p = p->next) {
-		if (p->filesize && (res = p->filesize(fname)) != -1)
+	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 *p;
+	const GFILEVMT * const *p;
 
 	#if GFILE_ALLOW_DEVICESPECIFIC
 		if ((oldname[0] && oldname[1] == '|') || (newname[0] && newname[1] == '|')) {
@@ -277,67 +212,21 @@ bool_t gfileRename(const char *oldname, const char *newname) {
 				ch = newname[0];
 				newname += 2;
 			}
-			for(p = FsChain; p; p = p->next) {
-				if (p->prefix == ch)
-					return p->ren && p->ren(oldname, newname);
+			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 = FsChain; p; p = p->next) {
-		if (p->ren && p->ren(oldname,newname))
+	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 GFILE *findemptyfile(const char *mode) {
-	GFILE *			f;
-
-	// First find an available GFILE slot.
-	for (f = gfileArr; f < &gfileArr[GFILE_MAX_GFILES]; f++) {
-		if (!(f->flags & GFILEFLG_OPEN)) {
-			// Get the flags
-			switch(mode[0]) {
-			case 'r':
-				f->flags = GFILEFLG_READ|GFILEFLG_MUSTEXIST;
-				while (*++mode) {
-					switch(mode[0]) {
-					case '+':	f->flags |= GFILEFLG_WRITE;			break;
-					case 'b':	f->flags |= GFILEFLG_BINARY;		break;
-					}
-				}
-				break;
-			case 'w':
-				f->flags = GFILEFLG_WRITE|GFILEFLG_TRUNC;
-				while (*++mode) {
-					switch(mode[0]) {
-					case '+':	f->flags |= GFILEFLG_READ;			break;
-					case 'b':	f->flags |= GFILEFLG_BINARY;		break;
-					case 'x':	f->flags |= GFILEFLG_MUSTNOTEXIST;	break;
-					}
-				}
-				break;
-			case 'a':
-				f->flags = GFILEFLG_WRITE|GFILEFLG_APPEND;
-				while (*++mode) {
-					switch(mode[0]) {
-					case '+':	f->flags |= GFILEFLG_READ;			break;
-					case 'b':	f->flags |= GFILEFLG_BINARY;		break;
-					case 'x':	f->flags |= GFILEFLG_MUSTNOTEXIST;	break;
-					}
-				}
-				break;
-			default:
-				return 0;
-			}
-			return f;
-		}
-	}
-	return 0;
-}
-
 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 <string.h>
 
 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 <stdio.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 //#include <unistd.h>
 
-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 <stdarg.h>
 
 #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 <string.h>
 
 // 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 <string.h>
 
 // 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
-- 
cgit v1.2.3