>From 81d1b557376311f38a5be5bc6f4a7ea0d033c5b4 Mon Sep 17 00:00:00 2001
From: Colomban Wendling <ban@herbesfolles.org>
Date: Sat, 20 Nov 2010 16:59:53 +0100
Subject: [PATCH 1/8] First tagmanager move to MIO I/O

Moved read.c and everything that breaks then.
---
 configure.ac           |    5 ++
 src/Makefile.am        |    4 +-
 tagmanager/Makefile.am |    2 +-
 tagmanager/c.c         |   36 ++--------
 tagmanager/entry.c     |  108 ++++++++++++++++---------------
 tagmanager/entry.h     |   10 ++--
 tagmanager/fortran.c   |   19 ++----
 tagmanager/get.c       |   59 +++--------------
 tagmanager/get.h       |    3 +-
 tagmanager/js.c        |   36 +++--------
 tagmanager/lregex.c    |    9 ++-
 tagmanager/parse.c     |    7 +-
 tagmanager/read.c      |  170 +++++++++++++----------------------------------
 tagmanager/read.h      |   25 ++------
 tagmanager/sort.c      |   47 +++++++-------
 tagmanager/sql.c       |   18 +----
 tagmanager/strlist.c   |    9 ++-
 17 files changed, 195 insertions(+), 372 deletions(-)

diff --git a/configure.ac b/configure.ac
index 2ceef4c..a169ec9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -146,6 +146,11 @@ AC_SUBST(GIO_LIBS)
 if test $have_gio = 1 ; then
     AC_DEFINE(HAVE_GIO, 1, [Whether GIO is available])
 fi
+# MIO checks
+mio_modules="mio >= 0.1"
+PKG_CHECK_MODULES(MIO, [$mio_modules])
+AC_SUBST(MIO_CFLAGS)
+AC_SUBST(MIO_LIBS)
 
 # --disable-deprecated switch for GTK2 purification
 AC_ARG_ENABLE(deprecated, [  --disable-deprecated    Disable deprecated GTK functions. ],
diff --git a/src/Makefile.am b/src/Makefile.am
index 6866ca7..632b604 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -85,7 +85,7 @@ if MINGW
 
 geany_SOURCES = $(SRCS) win32.c win32.h
 
-geany_LDADD = ../scintilla/libscintilla.a ../tagmanager/libtagmanager.a @GTK_LIBS@ @GIO_LIBS@ \
+geany_LDADD = ../scintilla/libscintilla.a ../tagmanager/libtagmanager.a @GTK_LIBS@ @GIO_LIBS@ @MIO_LIBS@ \
 				$(INTLLIBS) -lole32 -luuid -liberty -lwsock32 geany_private.res
 
 AM_CFLAGS = -DGEANY_DATADIR=\"data\" \
@@ -112,7 +112,7 @@ else
 
 geany_SOURCES = $(SRCS) vte.c vte.h
 
-geany_LDADD = ../scintilla/libscintilla.a ../tagmanager/libtagmanager.a @GTK_LIBS@ @GIO_LIBS@ $(INTLLIBS)
+geany_LDADD = ../scintilla/libscintilla.a ../tagmanager/libtagmanager.a @GTK_LIBS@ @GIO_LIBS@ @MIO_LIBS@ $(INTLLIBS)
 
 AM_CFLAGS = -DGEANY_DATADIR=\""$(datadir)"\" \
 			-DGEANY_DOCDIR=\""$(docdir)"\" \
diff --git a/tagmanager/Makefile.am b/tagmanager/Makefile.am
index dd6ac89..cca1091 100644
--- a/tagmanager/Makefile.am
+++ b/tagmanager/Makefile.am
@@ -2,7 +2,7 @@
 # $Id$
 
 SUBDIRS = include
-INCLUDES = -I$(srcdir)/include $(GTK_CFLAGS)
+INCLUDES = -I$(srcdir)/include $(GTK_CFLAGS) $(MIO_CFLAGS)
 
 AM_CFLAGS = -DG_LOG_DOMAIN=\""Tagmanager"\"
 
diff --git a/tagmanager/c.c b/tagmanager/c.c
index b6714a2..5acc9fb 100644
--- a/tagmanager/c.c
+++ b/tagmanager/c.c
@@ -16,6 +16,7 @@
 
 #include <string.h>
 #include <setjmp.h>
+#include <mio/mio.h>
 
 #include "entry.h"
 #include "get.h"
@@ -180,8 +181,7 @@ typedef struct sTokenInfo
 	keywordId		keyword;
 	vString*		name;			/* the name of the token */
 	unsigned long	lineNumber;		/* line number of tag */
-	fpos_t			filePosition;	/* file position of line containing name */
-	int				bufferPosition;	/* buffer position of line containing name */
+	MIOPos			filePosition;	/* file position of line containing name */
 } tokenInfo;
 
 typedef enum eImplementation
@@ -602,10 +602,7 @@ static void initToken (tokenInfo* const token)
 	token->type			= TOKEN_NONE;
 	token->keyword		= KEYWORD_NONE;
 	token->lineNumber	= getSourceLineNumber();
-	if (useFile())
-		token->filePosition   = getInputFilePosition();
-	else
-		token->bufferPosition = getInputBufferPosition();
+	token->filePosition	= getInputFilePosition();
 	vStringClear(token->name);
 }
 
@@ -1236,16 +1233,8 @@ static void addOtherFields (tagEntryInfo* const tag, const tagType type,
             if ((TRUE == st->gotArgs) && (TRUE == Option.extensionFields.argList) &&
 				((TAG_FUNCTION == type) || (TAG_METHOD == type) || (TAG_PROTOTYPE == type)))
 			{
-				if (useFile())
-				{
-					tag->extensionFields.arglist = getArglistFromFilePos(
+				tag->extensionFields.arglist = getArglistFromFilePos(
 						tag->filePosition, tag->name);
-				}
-				else
-				{
-					tag->extensionFields.arglist = getArglistFromBufferPos(
-						tag->bufferPosition, tag->name);
-				}
 			}
 			break;
 		}
@@ -1424,10 +1413,7 @@ static void makeTag (const tokenInfo *const token,
 		initTagEntry (&e, vStringValue (token->name));
 
 		e.lineNumber	= token->lineNumber;
-		if (useFile())
-			e.filePosition	= token->filePosition;
-		else
-			e.bufferPosition = token->bufferPosition;
+		e.filePosition	= token->filePosition;
 		e.isFileScope = isFileScope;
 		e.kindName	= tagName (type);
 		e.kind		= tagLetter (type);
@@ -1894,10 +1880,7 @@ static void copyToken (tokenInfo *const dest, const tokenInfo *const src)
 {
 	dest->type         = src->type;
 	dest->keyword      = src->keyword;
-	if (useFile())
-		dest->filePosition = src->filePosition;
-	else
-		dest->bufferPosition = src->bufferPosition;
+	dest->filePosition = src->filePosition;
 	dest->lineNumber   = src->lineNumber;
 	vStringCopy (dest->name, src->name);
 }
@@ -2487,12 +2470,7 @@ static int parseParens (statementInfo *const st, parenInfo *const info)
 	}
 		if (st->argEndPosition == 0)
 		{
-			if (useFile())
-				st->argEndPosition = ftell(File.fp);
-			else
-				/* FIXME File.fpBufferPosition is wrong here, this breaks function signatures and
-				 * so Geany's calltips */
-				st->argEndPosition = File.fpBufferPosition;
+			st->argEndPosition = mio_tell(File.mio);
 		}
 
 	if (! info->isNameCandidate)
diff --git a/tagmanager/entry.c b/tagmanager/entry.c
index f09b095..8dfd312 100644
--- a/tagmanager/entry.c
+++ b/tagmanager/entry.c
@@ -127,8 +127,8 @@ static void writePseudoTag (const char *const tagName,
 			    const char *const fileName,
 			    const char *const pattern)
 {
-    const int length = fprintf (TagFile.fp, "%s%s\t%s\t/%s/\n",
-			       PSEUDO_TAG_PREFIX, tagName, fileName, pattern);
+    const int length = mio_printf (TagFile.mio, "%s%s\t%s\t/%s/\n",
+				   PSEUDO_TAG_PREFIX, tagName, fileName, pattern);
     ++TagFile.numTags.added;
     rememberMaxLengths (strlen (tagName), (size_t) length);
 }
@@ -159,7 +159,7 @@ static void addPseudoTags (void)
 }
 
 static void updateSortedFlag (const char *const line,
-			      FILE *const fp, fpos_t startOfLine)
+			      MIO *const mio, MIOPos startOfLine)
 {
     const char *const tab = strchr (line, '\t');
 
@@ -169,27 +169,27 @@ static void updateSortedFlag (const char *const line,
 
 	if (line [boolOffset] == '0'  ||  line [boolOffset] == '1')
 	{
-	    fpos_t nextLine;
+	    MIOPos nextLine;
 
-	    if (fgetpos (fp, &nextLine) == -1 || fsetpos (fp, &startOfLine) == -1)
+	    if (mio_getpos (mio, &nextLine) == -1 || mio_setpos (mio, &startOfLine) == -1)
 		error (WARNING, "Failed to update 'sorted' pseudo-tag");
 	    else
 	    {
-		fpos_t flagLocation;
+		MIOPos flagLocation;
 		int c, d;
 
 		do
-		    c = fgetc (fp);
+		    c = mio_getc (mio);
 		while (c != '\t'  &&  c != '\n');
-		fgetpos (fp, &flagLocation);
-		d = fgetc (fp);
+		mio_getpos (mio, &flagLocation);
+		d = mio_getc (mio);
 		if (c == '\t'  &&  (d == '0'  ||  d == '1')  &&
 		    d != (int) Option.sorted)
 		{
-		    fsetpos (fp, &flagLocation);
-		    fputc (Option.sorted ? '1' : '0', fp);
+		    mio_setpos (mio, &flagLocation);
+		    mio_putc (mio, Option.sorted ? '1' : '0');
 		}
-		fsetpos (fp, &nextLine);
+		mio_setpos (mio, &nextLine);
 	    }
 	}
     }
@@ -198,12 +198,12 @@ static void updateSortedFlag (const char *const line,
 /*  Look through all line beginning with "!_TAG_FILE", and update those which
  *  require it.
  */
-static long unsigned int updatePseudoTags (FILE *const fp)
+static long unsigned int updatePseudoTags (MIO *const mio)
 {
     enum { maxClassLength = 20 };
     char class [maxClassLength + 1];
     unsigned long linesRead = 0;
-    fpos_t startOfLine;
+    MIOPos startOfLine;
     size_t classLength;
     const char *line;
 
@@ -211,8 +211,8 @@ static long unsigned int updatePseudoTags (FILE *const fp)
     classLength = strlen (class);
     Assert (classLength < maxClassLength);
 
-    fgetpos (fp, &startOfLine);
-    line = readLine (TagFile.vLine, fp);
+    mio_getpos (mio, &startOfLine);
+    line = readLine (TagFile.vLine, mio);
     while (line != NULL  &&  line [0] == class [0])
     {
 	++linesRead;
@@ -224,16 +224,16 @@ static long unsigned int updatePseudoTags (FILE *const fp)
 		tab == '\t')
 	    {
 		if (strcmp (classType, "_SORTED") == 0)
-		    updateSortedFlag (line, fp, startOfLine);
+		    updateSortedFlag (line, mio, startOfLine);
 	    }
-	    fgetpos (fp, &startOfLine);
+	    mio_getpos (mio, &startOfLine);
 	}
-	line = readLine (TagFile.vLine, fp);
+	line = readLine (TagFile.vLine, mio);
     }
     while (line != NULL)			/* skip to end of file */
     {
 	++linesRead;
-	line = readLine (TagFile.vLine, fp);
+	line = readLine (TagFile.vLine, mio);
     }
     return linesRead;
 }
@@ -247,22 +247,22 @@ static long unsigned int updatePseudoTags (FILE *const fp)
 static boolean isTagFile (const char *const filename)
 {
     boolean ok = FALSE;			/* we assume not unless confirmed */
-    FILE *const fp = g_fopen (filename, "rb");
+    MIO *const mio = mio_new_file_full (filename, "rb", g_fopen, fclose);
 
-    if (fp == NULL  &&  errno == ENOENT)
+    if (mio == NULL  &&  errno == ENOENT)
 	ok = TRUE;
-    else if (fp != NULL)
+    else if (mio != NULL)
     {
-	const char *line = readLine (TagFile.vLine, fp);
+	const char *line = readLine (TagFile.vLine, mio);
 
 	if (line == NULL)
 	    ok = TRUE;
-	fclose (fp);
+	mio_free (mio);
     }
     return ok;
 }
 
-extern void copyBytes (FILE* const fromFp, FILE* const toFp, const long size)
+extern void copyBytes (MIO* const fromMio, MIO* const toMio, const long size)
 {
     enum { BufferSize = 1000 };
     long toRead, numRead;
@@ -272,8 +272,8 @@ extern void copyBytes (FILE* const fromFp, FILE* const toFp, const long size)
     {
 	toRead = (0 < remaining && remaining < BufferSize) ?
 		    remaining : BufferSize;
-	numRead = fread (buffer, (size_t) 1, (size_t) toRead, fromFp);
-	if (fwrite (buffer, (size_t)1, (size_t)numRead, toFp) < (size_t)numRead)
+	numRead = mio_read (fromMio, buffer, (size_t) 1, (size_t) toRead);
+	if (mio_write (toMio, buffer, (size_t)1, (size_t)numRead) < (size_t)numRead)
 	    error (FATAL | PERROR, "cannot complete write");
 	if (remaining > 0)
 	    remaining -= numRead;
@@ -283,20 +283,20 @@ extern void copyBytes (FILE* const fromFp, FILE* const toFp, const long size)
 
 extern void copyFile (const char *const from, const char *const to, const long size)
 {
-    FILE* const fromFp = g_fopen (from, "rb");
-    if (fromFp == NULL)
+    MIO* const fromMio = mio_new_file_full (from, "rb", g_fopen, fclose);
+    if (fromMio == NULL)
 	error (FATAL | PERROR, "cannot open file to copy");
     else
     {
-	FILE* const toFp = g_fopen (to, "wb");
-	if (toFp == NULL)
+	MIO* const toMio = mio_new_file_full (to, "wb", g_fopen, fclose);
+	if (toMio == NULL)
 	    error (FATAL | PERROR, "cannot open copy destination");
 	else
 	{
-	    copyBytes (fromFp, toFp, size);
-	    fclose (toFp);
+	    copyBytes (fromMio, toMio, size);
+	    mio_free (toMio);
 	}
-	fclose (fromFp);
+	mio_free (fromMio);
     }
 }
 
@@ -311,7 +311,12 @@ extern void openTagFile (void)
     /*  Open the tags file.
      */
     if (TagsToStdout)
-	TagFile.fp = tempFile ("w", &TagFile.name);
+    {
+	FILE *fp;
+
+	fp = tempFile ("w", &TagFile.name);
+	TagFile.mio = mio_new_fp (fp, fclose);
+    }
     else
     {
 	boolean fileExists;
@@ -324,24 +329,24 @@ extern void openTagFile (void)
 	      "\"%s\" doesn't look like a tag file; I refuse to overwrite it.",
 		  TagFile.name);
 
-    if (Option.append  &&  fileExists)
-    {
-	TagFile.fp = g_fopen (TagFile.name, "r+");
-	if (TagFile.fp != NULL)
+	if (Option.append  &&  fileExists)
 	{
-	    TagFile.numTags.prev = updatePseudoTags (TagFile.fp);
-	    fclose (TagFile.fp);
-	    TagFile.fp = g_fopen (TagFile.name, "a+");
+	    TagFile.mio = mio_new_file_full (TagFile.name, "r+", g_fopen, fclose);
+	    if (TagFile.mio != NULL)
+	    {
+		TagFile.numTags.prev = updatePseudoTags (TagFile.mio);
+		mio_free (TagFile.mio);
+		TagFile.mio = mio_new_file_full (TagFile.name, "a+", g_fopen, fclose);
+	    }
+	}
+	else
+	{
+	    TagFile.mio = mio_new_file_full (TagFile.name, "w", g_fopen, fclose);
+	    if (TagFile.mio != NULL)
+		addPseudoTags ();
 	}
-    }
-    else
-    {
-	TagFile.fp = g_fopen (TagFile.name, "w");
-	if (TagFile.fp != NULL)
-	    addPseudoTags ();
-    }
 
-	if (TagFile.fp == NULL)
+	if (TagFile.mio == NULL)
 	{
 	    error (FATAL | PERROR, "cannot open tag file");
 	    exit (1);
@@ -409,7 +414,6 @@ extern void initTagEntry (tagEntryInfo *const e, const char *const name)
     e->lineNumber	= getSourceLineNumber ();
     e->language		= getSourceLanguageName ();
     e->filePosition	= getInputFilePosition ();
-    e->bufferPosition	= getInputBufferPosition ();
     e->sourceFileName	= getSourceFileTagPath ();
     e->name		= name;
 }
diff --git a/tagmanager/entry.h b/tagmanager/entry.h
index 7a19f11..e4a2d1e 100644
--- a/tagmanager/entry.h
+++ b/tagmanager/entry.h
@@ -15,7 +15,7 @@
 */
 #include "general.h"	/* must always come first */
 
-#include <stdio.h>
+#include <mio/mio.h>
 
 #include "vstring.h"
 
@@ -33,12 +33,12 @@
 typedef struct eTagFile {
     char *name;
     char *directory;
-    FILE *fp;
+    MIO *mio;
     struct sNumTags { unsigned long added, prev; } numTags;
     struct sMax { size_t line, tag, file; } max;
     struct sEtags {
 	char *name;
-	FILE *fp;
+	MIO *mio;
 	size_t byteCount;
     } etags;
     vString *vLine;
@@ -55,7 +55,7 @@ typedef struct sTagFields {
 typedef struct sTagEntryInfo {
     boolean	lineNumberEntry;/* pattern or line number entry */
     unsigned long lineNumber;	/* line number of tag */
-    fpos_t	filePosition;	/* file position of line containing tag */
+    MIOPos	filePosition;	/* file position of line containing tag */
     int bufferPosition;		/* buffer position of line containing tag */
     const char*	language;	/* language of source file */
     boolean	isFileScope;	/* is tag visibile only within source file? */
@@ -88,7 +88,7 @@ extern tagFile TagFile;
 */
 extern void freeTagFileResources (void);
 extern const char *tagFileName (void);
-extern void copyBytes (FILE* const fromFp, FILE* const toFp, const long size);
+extern void copyBytes (MIO* const fromMio, MIO* const toMio, const long size);
 extern void copyFile (const char *const from, const char *const to, const long size);
 extern void openTagFile (void);
 extern void closeTagFile (const boolean resize);
diff --git a/tagmanager/fortran.c b/tagmanager/fortran.c
index e341a95..3dbe59b 100644
--- a/tagmanager/fortran.c
+++ b/tagmanager/fortran.c
@@ -19,6 +19,7 @@
 #include <limits.h>
 #include <ctype.h>	/* to define tolower () */
 #include <setjmp.h>
+#include <mio/mio.h>
 
 #include "entry.h"
 #include "keyword.h"
@@ -183,8 +184,7 @@ typedef struct sTokenInfo {
 	vString* string;
 	struct sTokenInfo *secondary;
 	unsigned long lineNumber;
-	fpos_t filePosition;
-	int bufferPosition;	/* buffer position of line containing name */
+	MIOPos filePosition;
 } tokenInfo;
 
 /*
@@ -423,10 +423,7 @@ static tokenInfo *newToken (void)
 	token->string       = vStringNew ();
 	token->secondary    = NULL;
 	token->lineNumber   = getSourceLineNumber ();
-	if (useFile())
-	    token->filePosition = getInputFilePosition ();
-	else
-	    token->bufferPosition = getInputBufferPosition ();
+	token->filePosition = getInputFilePosition ();
 
 	return token;
 }
@@ -480,10 +477,7 @@ static void makeFortranTag (tokenInfo *const token, tagType tag)
 			e.lineNumberEntry = (boolean) (Option.locate != EX_PATTERN);
 
 		e.lineNumber	= token->lineNumber;
-		if (useFile())
-		    e.filePosition   = token->filePosition;
-		else
-		    e.bufferPosition = token->bufferPosition;
+		e.filePosition	= token->filePosition;
 		e.isFileScope	= isFileScope (token->tag);
 		e.kindName		= FortranKinds [token->tag].name;
 		e.kind			= FortranKinds [token->tag].letter;
@@ -959,10 +953,7 @@ getNextChar:
 	c = getChar ();
 
 	token->lineNumber	= getSourceLineNumber ();
-	if (useFile())
-	    token->filePosition = getInputFilePosition ();
-	else
-	    token->bufferPosition = getInputBufferPosition ();
+	token->filePosition = getInputFilePosition ();
 
 	switch (c)
 	{
diff --git a/tagmanager/get.c b/tagmanager/get.c
index 0e924e3..5472a6b 100644
--- a/tagmanager/get.c
+++ b/tagmanager/get.c
@@ -314,14 +314,8 @@ static void makeDefineTag (const char *const name, boolean parameterized)
 		e.kind         = 'd';
 		if (parameterized)
 		{
-			if (useFile()) {
-				e.extensionFields.arglist = getArglistFromFilePos(getInputFilePosition()
-		  			, e.name);
-			}
-			else {
-				e.extensionFields.arglist = getArglistFromBufferPos(getInputBufferPosition()
-		  			, e.name);
-			}
+			e.extensionFields.arglist = getArglistFromFilePos(getInputFilePosition()
+					, e.name);
 		}
 		makeTagEntry (&e);
 		if (parameterized)
@@ -715,63 +709,30 @@ process:
 	return c;
 }
 
-extern char *getArglistFromBufferPos(int startPosition, const char *tokenName)
-{
-	int bufferOriginalPosition;
-	char *result = NULL;
-	char *arglist = NULL;
-	long pos1, pos2;
-
-	/* FIXME startPosition as well as getBufPos() are mostly wrong here */
-	pos2 = getBufPos();
-
-	if (!useFile()) {
-		bufferOriginalPosition = getBufPos ();
-		setBufPos(startPosition);
-		pos1 = File.fpBufferPosition;
-	}
-	else
-		return NULL;
-
-	if (pos2 > pos1)
-	{
-		result = (char *) g_malloc(sizeof(char ) * (pos2 - pos1 + 2));
-		if (result != NULL)
-		{
-			memcpy(result, &File.fpBuffer[getBufPos()], pos2 - pos1 + 1);
-			result[pos2-pos1+1] = '\0';
-			arglist = getArglistFromStr(result, tokenName);
-			g_free(result);
-		}
-	}
-	setBufPos (bufferOriginalPosition);
-	return arglist;
-}
-
-extern char *getArglistFromFilePos(fpos_t startPosition, const char *tokenName)
+extern char *getArglistFromFilePos(MIOPos startPosition, const char *tokenName)
 {
-	fpos_t originalPosition;
+	MIOPos originalPosition;
 	char *result = NULL;
 	char *arglist = NULL;
 	long pos1, pos2;
 
-	pos2 = ftell(File.fp);
+	pos2 = mio_tell(File.mio);
 
-	fgetpos(File.fp, &originalPosition);
-	fsetpos(File.fp, &startPosition);
-	pos1 = ftell(File.fp);
+	mio_getpos(File.mio, &originalPosition);
+	mio_setpos(File.mio, &startPosition);
+	pos1 = mio_tell(File.mio);
 
 	if (pos2 > pos1)
 	{
 		result = (char *) g_malloc(sizeof(char ) * (pos2 - pos1 + 2));
-		if (result != NULL && fread(result, sizeof(char), pos2 - pos1 + 1, File.fp) > 0)
+		if (result != NULL && mio_read(File.mio, result, sizeof(char), pos2 - pos1 + 1) > 0)
 		{
 			result[pos2-pos1+1] = '\0';
 			arglist = getArglistFromStr(result, tokenName);
 		}
 		g_free(result);
 	}
-	fsetpos(File.fp, &originalPosition);
+	mio_setpos(File.mio, &originalPosition);
 	return arglist;
 }
 
diff --git a/tagmanager/get.h b/tagmanager/get.h
index a34e33b..e284a3f 100644
--- a/tagmanager/get.h
+++ b/tagmanager/get.h
@@ -45,8 +45,7 @@ extern void cppEndStatement (void);
 extern void cppUngetc (const int c);
 extern int cppGetc (void);
 extern int skipOverCComment (void);
-extern char *getArglistFromFilePos(fpos_t startPosition, const char *tokenName);
-extern char *getArglistFromBufferPos(int startPosition, const char *tokenName);
+extern char *getArglistFromFilePos(MIOPos startPosition, const char *tokenName);
 extern char *getArglistFromStr(char *buf, const char *name);
 
 #endif  /* _GET_H */
diff --git a/tagmanager/js.c b/tagmanager/js.c
index 7c1844d..897b333 100644
--- a/tagmanager/js.c
+++ b/tagmanager/js.c
@@ -21,6 +21,7 @@
 #include "general.h"	/* must always come first */
 #include <ctype.h>	/* to define isalpha () */
 #include <setjmp.h>
+#include <mio/mio.h>
 #ifdef DEBUG
 #include <stdio.h>
 #endif
@@ -107,10 +108,9 @@ typedef struct sTokenInfo {
 	vString *		string;
 	vString *		scope;
 	unsigned long 	lineNumber;
-	fpos_t 			filePosition;
+	MIOPos			filePosition;
 	int				nestLevel;
 	boolean			ignoreTag;
-    int	bufferPosition;	/* buffer position of line containing name */
 } tokenInfo;
 
 /*
@@ -198,10 +198,7 @@ static tokenInfo *newToken (void)
 	token->nestLevel	= 0;
 	token->ignoreTag	= FALSE;
 	token->lineNumber   = getSourceLineNumber ();
-    if (useFile())
-		token->filePosition = getInputFilePosition ();
-    else
-		token->bufferPosition = getInputBufferPosition ();
+	token->filePosition = getInputFilePosition ();
 
 	return token;
 }
@@ -357,11 +354,8 @@ getNextChar:
 	{
 		c = fileGetc ();
 		token->lineNumber   = getSourceLineNumber ();
-		if (useFile())
-			token->filePosition = getInputFilePosition ();
-		else
-			token->bufferPosition = getInputBufferPosition ();
-		}
+		token->filePosition = getInputFilePosition ();
+	}
 	while (c == '\t'  ||  c == ' ' ||  c == '\n');
 
 	switch (c)
@@ -384,10 +378,7 @@ getNextChar:
 				  token->type = TOKEN_STRING;
 				  parseString (token->string, c);
 				  token->lineNumber = getSourceLineNumber ();
-				  if (useFile())
-					token->filePosition = getInputFilePosition ();
-				  else
-					token->bufferPosition = getInputBufferPosition ();
+				  token->filePosition = getInputFilePosition ();
 				  break;
 
 		case '\\':
@@ -396,10 +387,7 @@ getNextChar:
 					  fileUngetc (c);
 				  token->type = TOKEN_CHARACTER;
 				  token->lineNumber = getSourceLineNumber ();
-				  if (useFile())
-					token->filePosition = getInputFilePosition ();
-				  else
-					token->bufferPosition = getInputBufferPosition ();
+				  token->filePosition = getInputFilePosition ();
 				  break;
 
 		case '/':
@@ -442,10 +430,7 @@ getNextChar:
 				  {
 					  parseIdentifier (token->string, c);
 					  token->lineNumber = getSourceLineNumber ();
-					  if (useFile())
-						token->filePosition = getInputFilePosition ();
-					  else
-						token->bufferPosition = getInputBufferPosition ();
+					  token->filePosition = getInputFilePosition ();
 					  token->keyword = analyzeToken (token->string);
 					  if (isKeyword (token, KEYWORD_NONE))
 						  token->type = TOKEN_IDENTIFIER;
@@ -460,10 +445,7 @@ static void copyToken (tokenInfo *const dest, tokenInfo *const src)
 {
 	dest->nestLevel = src->nestLevel;
 	dest->lineNumber = src->lineNumber;
-    if (useFile())
-		dest->filePosition = src->filePosition;
-    else
-		dest->bufferPosition = src->bufferPosition;
+	dest->filePosition = src->filePosition;
 	dest->type = src->type;
 	dest->keyword = src->keyword;
 	vStringCopy(dest->string, src->string);
diff --git a/tagmanager/lregex.c b/tagmanager/lregex.c
index db97c31..bc79102 100644
--- a/tagmanager/lregex.c
+++ b/tagmanager/lregex.c
@@ -20,6 +20,7 @@
 
 #include <string.h>
 #include <glib.h>
+#include <mio/mio.h>
 
 #ifdef HAVE_REGCOMP
 # include <ctype.h>
@@ -410,15 +411,15 @@ static void processLanguageRegex (const langType language,
 	else
 	{
 		const char* regexfile = parameter + 1;
-		FILE* const fp = fopen (regexfile, "r");
-		if (fp == NULL)
+		MIO* const mio = mio_new_file (regexfile, "r");
+		if (mio == NULL)
 			printf ("regex: %s\n", regexfile);
 		else
 		{
 			vString* const regex = vStringNew ();
-			while (readLine (regex, fp))
+			while (readLine (regex, mio))
 				addLanguageRegex (language, vStringValue (regex));
-			fclose (fp);
+			mio_free (mio);
 			vStringDelete (regex);
 		}
 	}
diff --git a/tagmanager/parse.c b/tagmanager/parse.c
index a9c23ef..a6312ac 100644
--- a/tagmanager/parse.c
+++ b/tagmanager/parse.c
@@ -15,6 +15,7 @@
 #include "general.h"	/* must always come first */
 
 #include <string.h>
+#include <mio/mio.h>
 
 
 #include "entry.h"
@@ -613,16 +614,16 @@ static boolean createTagsWithFallback (const char *const fileName,
 				       const langType language)
 {
     const unsigned long numTags	= TagFile.numTags.added;
-    fpos_t tagFilePosition;
+    MIOPos tagFilePosition;
     unsigned int passCount = 0;
     boolean tagFileResized = FALSE;
 
-    fgetpos (TagFile.fp, &tagFilePosition);
+    mio_getpos (TagFile.mio, &tagFilePosition);
     while (createTagsForFile (fileName, language, ++passCount))
     {
 	/*  Restore prior state of tag file.
 	 */
-	fsetpos (TagFile.fp, &tagFilePosition);
+	mio_setpos (TagFile.mio, &tagFilePosition);
 	TagFile.numTags.added = numTags;
 	tagFileResized = TRUE;
     }
diff --git a/tagmanager/read.c b/tagmanager/read.c
index fbd0616..422e8da 100644
--- a/tagmanager/read.c
+++ b/tagmanager/read.c
@@ -28,12 +28,19 @@
 *   DATA DEFINITIONS
 */
 inputFile File;			/* globally read through macros */
-static fpos_t StartOfLine;	/* holds deferred position of start of line */
-static int bufferStartOfLine;   /* the same as StartOfLine but for buffer */
+static MIOPos StartOfLine;	/* holds deferred position of start of line */
 
 
-static int readNextChar (void);
-static int pushBackChar (int c);
+
+/* Read a character choosing automatically between file or buffer, depending
+ * on which mode we are.
+ */
+#define readNextChar() (mio_getc (File.mio))
+
+/* Replaces ungetc() for file. In case of buffer we'll perform the same action:
+ * fpBufferPosition-- and write of the param char into the buf.
+ */
+#define pushBackChar(c) (mio_ungetc (File.mio, c))
 
 /*
 *   FUNCTION DEFINITIONS
@@ -253,22 +260,22 @@ extern boolean fileOpen (const char *const fileName, const langType language)
 
     /*	If another file was already open, then close it.
      */
-    if (File.fp != NULL)
+    if (File.mio != NULL)
     {
-	fclose (File.fp);		/* close any open source file */
-	File.fp = NULL;
+	mio_free (File.mio);		/* close any open source file */
+	File.mio = NULL;
     }
 
-    File.fp = g_fopen (fileName, openMode);
-    if (File.fp == NULL)
+    File.mio = mio_new_file_full (fileName, openMode, g_fopen, fclose);
+    if (File.mio == NULL)
 	error (WARNING | PERROR, "cannot open \"%s\"", fileName);
     else
     {
 	opened = TRUE;
 
 	setInputFileName (fileName);
-	fgetpos (File.fp, &StartOfLine);
-	fgetpos (File.fp, &File.filePosition);
+	mio_getpos (File.mio, &StartOfLine);
+	mio_getpos (File.mio, &File.filePosition);
 	File.currentLine  = NULL;
 	File.language     = language;
 	File.lineNumber   = 0L;
@@ -297,19 +304,13 @@ extern boolean bufferOpen (unsigned char *buffer, int buffer_size,
 {
     boolean opened = FALSE;
 	
-    /*	Check whether a file of a buffer were already open, then close them.
+    /* Check whether a file of a buffer were already open, then close them.
      */
-    if (File.fp != NULL) {
-	fclose (File.fp);		/* close any open source file */
-	File.fp = NULL;
+    if (File.mio != NULL) {
+	mio_free (File.mio);		/* close any open source file */
+	File.mio = NULL;
     }
 
-    if (File.fpBuffer != NULL) {
-	error(PERROR, "An unallocated buffer was found. Please check you called \
-	correctly bufferClose ()\n");
-	File.fpBuffer = NULL;
-    }
-    
     /* check if we got a good buffer */
     if (buffer == NULL || buffer_size == 0) {
 	opened = FALSE;
@@ -318,11 +319,10 @@ extern boolean bufferOpen (unsigned char *buffer, int buffer_size,
 	
     opened = TRUE;
 	    
-    File.fpBuffer = buffer;		
+    File.mio = mio_new_memory (buffer, buffer_size, NULL, NULL);
     setInputFileName (fileName);
-    bufferStartOfLine = 0;
-    File.fpBufferPosition = 0;
-    File.fpBufferSize = buffer_size;
+    mio_getpos (File.mio, &StartOfLine);
+    mio_getpos (File.mio, &File.filePosition);
     File.currentLine  = NULL;
     File.language     = language;
     File.lineNumber   = 0L;
@@ -339,12 +339,12 @@ extern boolean bufferOpen (unsigned char *buffer, int buffer_size,
 	    getLanguageName (language),
 	    File.source.isHeader ? "include " : "");
 
-    return opened;	
+    return opened;
 }
 
 extern void fileClose (void)
 {
-    if (File.fp != NULL)
+    if (File.mio != NULL)
     {
 	/*  The line count of the file is 1 too big, since it is one-based
 	 *  and is incremented upon each newline.
@@ -353,16 +353,8 @@ extern void fileClose (void)
 	    addTotals (0, File.lineNumber - 1L,
 		      getFileSize (vStringValue (File.name)));
 
-	fclose (File.fp);
-	File.fp = NULL;
-    }
-}
-
-/* user should take care of freeing the buffer */
-extern void bufferClose (void)
-{
-    if (File.fpBuffer != NULL) {
-	File.fpBuffer = NULL;
+	mio_free (File.mio);
+	File.mio = NULL;
     }
 }
 
@@ -403,11 +395,7 @@ readnext:
 		goto readnext;
 	    else
 	    {
-		/* FIXME: find out a better way to do this check */
-		if (File.fp != NULL)
-		    fsetpos (File.fp, &StartOfLine);
-		else
-		    File.fpBufferPosition = bufferStartOfLine;
+		mio_setpos (File.mio, &StartOfLine);
 
 		c = readNextChar ();
 	    }
@@ -419,10 +407,7 @@ readnext:
     else if (c == NEWLINE)
     {
 	File.newLine = TRUE;
-	if (File.fp != NULL)		/* we have a file */
-	    fgetpos (File.fp, &StartOfLine);
-	else						/* it's a buffer */
-	    bufferStartOfLine = File.fpBufferPosition;
+	mio_getpos (File.mio, &StartOfLine);
     }
     else if (c == CRETURN)
     {
@@ -437,10 +422,7 @@ readnext:
 
 	c = NEWLINE;				/* convert CR into newline */
 	File.newLine = TRUE;
-	if (File.fp != NULL)
-	    fgetpos (File.fp, &StartOfLine);
-	else
-	    bufferStartOfLine = File.fpBufferPosition;
+	mio_getpos (File.mio, &StartOfLine);
     }
     DebugStatement ( debugPutc (DEBUG_RAW, c); )
     return c;
@@ -535,75 +517,17 @@ extern const unsigned char *fileReadLine (void)
     return result;
 }
 
-/* Read a character choosing automatically between file or buffer, depending
- * on which mode we are.
- */
-static int readNextChar(void) 
-{
-    if (File.fp != NULL) {
-	return getc(File.fp);
-    }
-    else {
-	int c;
-	if (File.fpBufferPosition >= File.fpBufferSize)
-	    return EOF;
-
-	c = File.fpBuffer[File.fpBufferPosition];
-	File.fpBufferPosition++;
-	
-	return c;
-    }
-}
-
-/* Replaces ungetc() for file. In case of buffer we'll perform the same action:
- * fpBufferPosition-- and write of the param char into the buf.
- */
-static int pushBackChar (int c) 
-{
-    if (File.fp != NULL) {
-	return ungetc (c, File.fp);
-    }
-    else {
-	File.fpBufferPosition--;
-	if (File.fpBufferPosition < 0)
-	    return EOF;
-	File.fpBuffer[File.fpBufferPosition] = c;
-	return File.fpBuffer[File.fpBufferPosition];
-    }
-}
-
-
-/* replacement for fsetpos, applied to a buffer */
-extern void setBufPos (int new_position) 
-{
-    File.fpBufferPosition = new_position;
-}
-
-/* replacement for fgetpos, applied to a buffer */
-extern int getBufPos (void) 
-{
-    return File.fpBufferPosition;
-}
-
-extern boolean useFile (void)
-{
-    if (File.fp != NULL)
-	return TRUE;
-    else
-	return FALSE;
-}
 
 /*
  *   Source file line reading with automatic buffer sizing
- *   Does not perform file/buffer checks. Only file is supported.
  */
-extern char *readLine (vString *const vLine, FILE *const fp)
+extern char *readLine (vString *const vLine, MIO *const mio)
 {
     char *result = NULL;
 
     vStringClear (vLine);
-    if (fp == NULL)		/* to free memory allocated to buffer */
-	error (FATAL, "NULL file pointer");
+    if (mio == NULL)		/* to free memory allocated to buffer */
+	error (FATAL, "NULL MIO pointer");
     else
     {
 	boolean reReadLine;
@@ -616,15 +540,15 @@ extern char *readLine (vString *const vLine, FILE *const fp)
 	do
 	{
 	    char *const pLastChar = vStringValue (vLine) + vStringSize (vLine) -2;
-	    fpos_t startOfLine;
+	    MIOPos startOfLine;
 
-	    fgetpos (fp, &startOfLine);
+	    mio_getpos (mio, &startOfLine);
 	    reReadLine = FALSE;
 	    *pLastChar = '\0';
-	    result = fgets (vStringValue (vLine), (int) vStringSize (vLine), fp);
+	    result = mio_gets (mio, vStringValue (vLine), (int) vStringSize (vLine));
 	    if (result == NULL)
 	    {
-		if (! feof (fp))
+		if (! mio_eof (mio))
 		    error (FATAL | PERROR, "Failure on attempt to read file");
 	    }
 	    else if (*pLastChar != '\0'  &&
@@ -633,7 +557,7 @@ extern char *readLine (vString *const vLine, FILE *const fp)
 		/*  buffer overflow */
 		reReadLine = vStringAutoResize (vLine);
 		if (reReadLine)
-		    fsetpos (fp, &startOfLine);
+		    mio_setpos (mio, &startOfLine);
 		else
 		    error (FATAL | PERROR, "input line too big; out of memory");
 	    }
@@ -660,20 +584,20 @@ extern char *readLine (vString *const vLine, FILE *const fp)
 /*  Places into the line buffer the contents of the line referenced by
  *  "location".
  */
-extern char *readSourceLine (vString *const vLine, fpos_t location,
+extern char *readSourceLine (vString *const vLine, MIOPos location,
 			     long *const pSeekValue)
 {
-    fpos_t orignalPosition;
+    MIOPos orignalPosition;
     char *result;
 
-    fgetpos (File.fp, &orignalPosition);
-    fsetpos (File.fp, &location);
+    mio_getpos (File.mio, &orignalPosition);
+    mio_setpos (File.mio, &location);
     if (pSeekValue != NULL)
-	*pSeekValue = ftell (File.fp);
-    result = readLine (vLine, File.fp);
+	*pSeekValue = mio_tell (File.mio);
+    result = readLine (vLine, File.mio);
     if (result == NULL)
 	error (FATAL, "Unexpected end of file: %s", vStringValue (File.name));
-    fsetpos (File.fp, &orignalPosition);
+    mio_setpos (File.mio, &orignalPosition);
 
     return result;
 }
diff --git a/tagmanager/read.h b/tagmanager/read.h
index 30fd424..0542712 100644
--- a/tagmanager/read.h
+++ b/tagmanager/read.h
@@ -23,6 +23,7 @@
 
 #include <stdio.h>
 #include <ctype.h>
+#include <mio/mio.h>
 
 #include "parse.h"
 #include "vstring.h"
@@ -33,7 +34,6 @@
 #define getInputLineNumber()	File.lineNumber
 #define getInputFileName()	vStringValue (File.source.name)
 #define getInputFilePosition()	File.filePosition
-#define getInputBufferPosition()	File.fpBufferPosition
 #define getSourceFileName()	vStringValue (File.source.name)
 #define getSourceFileTagPath()	File.source.tagPath
 #define getSourceLanguage()	File.source.language
@@ -73,13 +73,9 @@ typedef struct sInputFile {
     vString	*path;		/* path of input file (if any) */
     vString	*line;		/* last line read from file */
     const unsigned char* currentLine;	/* current line being worked on */
-    FILE	*fp;		/* stream used for reading the file */
-    unsigned char* fpBuffer;	/* buffer which contains the text to be parsed.
-				   This is optional to the use of a file-descriptor */
-    int fpBufferSize;		/* size of the fpBuffer */
-    int fpBufferPosition;	/* pointer to the current position in buffer */
+    MIO		*mio;		/* stream used for reading the file */
     unsigned long lineNumber;	/* line number in the input file */
-    fpos_t	filePosition;	/* file position of current line */
+    MIOPos	filePosition;	/* file position of current line */
     int		ungetch;	/* a single character that was ungotten */
     boolean	eof;		/* have we reached the end of file? */
     boolean	newLine;	/* will the next character begin a new line? */
@@ -106,11 +102,6 @@ extern CONST_FILE inputFile File;
 /*
 *   FUNCTION PROTOTYPES
 */
-#ifdef NEED_PROTO_FGETPOS
-extern int fgetpos  (FILE *stream, fpos_t *pos);
-extern int fsetpos  (FILE *stream, const fpos_t *pos);
-#endif
-
 extern void freeSourceFileResources (void);
 extern boolean fileOpen (const char *const fileName, const langType language);
 extern boolean fileEOF (void);
@@ -118,15 +109,11 @@ extern void fileClose (void);
 extern int fileGetc (void);
 extern void fileUngetc (int c);
 extern const unsigned char *fileReadLine (void);
-extern char *readLine (vString *const vLine, FILE *const fp);
-extern char *readSourceLine (vString *const vLine, fpos_t location, long *const pSeekValue);
-
+extern char *readLine (vString *const vLine, MIO *const mio);
+extern char *readSourceLine (vString *const vLine, MIOPos location, long *const pSeekValue);
 extern boolean bufferOpen (unsigned char *buffer, int buffer_size,
 			   const char *const fileName, const langType language );
-extern void bufferClose (void);
-extern void setBufPos (int new_position);
-extern int getBufPos (void);
-extern boolean useFile (void);
+#define bufferClose fileClose
 
 #endif	/* _READ_H */
 
diff --git a/tagmanager/sort.c b/tagmanager/sort.c
index 6f43577..230d6bd 100644
--- a/tagmanager/sort.c
+++ b/tagmanager/sort.c
@@ -105,11 +105,11 @@ extern void externalSortTags (const boolean toStdout)
  *  so have lots of memory if you have large tag files.
  */
 
-static void failedSort (FILE *const fp, const char* msg)
+static void failedSort (MIO *const mio, const char* msg)
 {
     const char* const cannotSort = "cannot sort tag file";
-    if (fp != NULL)
-	fclose (fp);
+    if (mio != NULL)
+	mio_free (mio);
     if (msg == NULL)
 	error (FATAL | PERROR, "%s", cannotSort);
     else
@@ -127,18 +127,18 @@ static int compareTags (const void *const one, const void *const two)
 static void writeSortedTags (char **const table, const size_t numTags,
 			     const boolean toStdout)
 {
-    FILE *fp;
+    MIO *mio;
     size_t i;
 
     /*	Write the sorted lines back into the tag file.
      */
     if (toStdout)
-	fp = stdout;
+	mio = mio_new_fp (stdout, NULL);
     else
     {
-	fp = g_fopen (tagFileName (), "w");
-	if (fp == NULL)
-	    failedSort (fp, NULL);
+	mio = mio_new_file_full (tagFileName (), "w", g_fopen, fclose);
+	if (mio == NULL)
+	    failedSort (mio, NULL);
     }
     for (i = 0 ; i < numTags ; ++i)
     {
@@ -146,19 +146,18 @@ static void writeSortedTags (char **const table, const size_t numTags,
 	 *  pattern) if this is not an xref file.
 	 */
 	if (i == 0  ||  Option.xref  ||  strcmp (table [i], table [i-1]) != 0)
-	    if (fputs (table [i], fp) == EOF)
-		failedSort (fp, NULL);
+	    if (mio_puts (mio, table [i]) == EOF)
+		failedSort (mio, NULL);
     }
     if (toStdout)
-	fflush (fp);
-    else
-	fclose (fp);
+	fflush (mio_file_get_fp (mio));
+    mio_free (mio);
 }
 
 extern void internalSortTags (const boolean toStdout)
 {
     vString *vLine = vStringNew ();
-    FILE *fp = NULL;
+    MIO *mio = NULL;
     const char *line;
     size_t i;
 
@@ -170,20 +169,20 @@ extern void internalSortTags (const boolean toStdout)
     DebugStatement ( size_t mallocSize = tableSize; )	/* cumulative total */
 
     if (table == NULL)
-	failedSort (fp, "out of memory");
+	failedSort (mio, "out of memory");
 
     /*	Open the tag file and place its lines into allocated buffers.
      */
-    fp = g_fopen (tagFileName (), "r");
-    if (fp == NULL)
-	failedSort (fp, NULL);
-    for (i = 0  ;  i < numTags  &&  ! feof (fp)  ;  )
+    mio = mio_new_file_full (tagFileName (), "r", g_fopen, fclose);
+    if (mio == NULL)
+	failedSort (mio, NULL);
+    for (i = 0  ;  i < numTags  &&  ! mio_eof (mio)  ;  )
     {
-	line = readLine (vLine, fp);
+	line = readLine (vLine, mio);
 	if (line == NULL)
 	{
-	    if (! feof (fp))
-		failedSort (fp, NULL);
+	    if (! mio_eof (mio))
+		failedSort (mio, NULL);
 	    break;
 	}
 	else if (*line == '\0'  ||  strcmp (line, "\n") == 0)
@@ -194,14 +193,14 @@ extern void internalSortTags (const boolean toStdout)
 
 	    table [i] = (char *) g_malloc (stringSize);
 	    if (table [i] == NULL)
-		failedSort (fp, "out of memory");
+		failedSort (mio, "out of memory");
 	    DebugStatement ( mallocSize += stringSize; )
 	    strcpy (table [i], line);
 	    ++i;
 	}
     }
     numTags = i;
-    fclose (fp);
+    mio_free (mio);
     vStringDelete (vLine);
 
     /*	Sort the lines.
diff --git a/tagmanager/sql.c b/tagmanager/sql.c
index 02733cc..31123aa 100644
--- a/tagmanager/sql.c
+++ b/tagmanager/sql.c
@@ -137,8 +137,7 @@ typedef struct sTokenInfo {
     vString *	string;
     vString *	scope;
     unsigned long lineNumber;
-    fpos_t filePosition;
-    int	bufferPosition;	/* buffer position of line containing name */
+    MIOPos filePosition;
 } tokenInfo;
 
 /*
@@ -392,10 +391,7 @@ static void makeConstTag (tokenInfo *const token, const sqlKind kind)
 	initTagEntry (&e, name);
 
 	e.lineNumber   = token->lineNumber;
-	if (useFile())
-	    e.filePosition	= token->filePosition;
-	else
-	    e.bufferPosition 	= token->bufferPosition;
+	e.filePosition = token->filePosition;
 	e.kindName     = SqlKinds [kind].name;
 	e.kind         = SqlKinds [kind].letter;
 
@@ -495,10 +491,7 @@ getNextChar:
 	    token->type = TOKEN_STRING;
 	    parseString (token->string, c);
             token->lineNumber = getSourceLineNumber ();
-	    if (useFile())
-		token->filePosition	= getInputFilePosition ();
-	    else
-		token->bufferPosition = getInputBufferPosition ();
+	    token->filePosition	= getInputFilePosition ();
 	    break;
 
 	case '-':
@@ -564,10 +557,7 @@ getNextChar:
 	    {
 		parseIdentifier (token->string, c);
 		token->lineNumber = getSourceLineNumber ();
-		if (useFile())
-		    token->filePosition	= getInputFilePosition ();
-		else
-		    token->bufferPosition = getInputBufferPosition ();
+		token->filePosition = getInputFilePosition ();
 		token->keyword = analyzeToken (token->string);
 		if (isKeyword (token, KEYWORD_rem))
 		{
diff --git a/tagmanager/strlist.c b/tagmanager/strlist.c
index aa42ef7..34a3338 100644
--- a/tagmanager/strlist.c
+++ b/tagmanager/strlist.c
@@ -92,20 +92,21 @@ extern stringList* stringListNewFromArgv (const char* const* const argv)
 extern stringList* stringListNewFromFile (const char* const fileName)
 {
 	stringList* result = NULL;
-	FILE* const fp = g_fopen (fileName, "r");
-	if (fp != NULL)
+	MIO* const mio = mio_new_file_full (fileName, "r", g_fopen, fclose);
+	if (mio != NULL)
 	{
 		result = stringListNew ();
-		while (! feof (fp))
+		while (! mio_eof (mio))
 		{
 			vString* const str = vStringNew ();
-			readLine (str, fp);
+			readLine (str, mio);
 			vStringStripTrailing (str);
 			if (vStringLength (str) > 0)
 				stringListAdd (result, str);
 			else
 				vStringDelete (str);
 		}
+		mio_free (mio);
 	}
 	return result;
 }
-- 
1.7.2.3

