[Scummvm-cvs-logs] SF.net SVN: scummvm:[33540] residual/trunk

aquadran at users.sourceforge.net aquadran at users.sourceforge.net
Sat Aug 2 23:20:16 CEST 2008


Revision: 33540
          http://scummvm.svn.sourceforge.net/scummvm/?rev=33540&view=rev
Author:   aquadran
Date:     2008-08-02 21:20:13 +0000 (Sat, 02 Aug 2008)

Log Message:
-----------
make lua io more portable

Modified Paths:
--------------
    residual/trunk/common/file.cpp
    residual/trunk/engine/lua/liolib.cpp
    residual/trunk/engine/lua/lstate.cpp
    residual/trunk/engine/lua/lualib.h

Modified: residual/trunk/common/file.cpp
===================================================================
--- residual/trunk/common/file.cpp	2008-08-02 21:14:54 UTC (rev 33539)
+++ residual/trunk/common/file.cpp	2008-08-02 21:20:13 UTC (rev 33540)
@@ -146,10 +146,21 @@
 static StringMap *_filesMap;
 
 static FILE *fopenNoCase(const String &filename, const String &directory, const char *mode) {
-	FILE *file;
+	FILE *file = NULL;
 	String dirBuf(directory);
 	String fileBuf(filename);
 
+	if (fileBuf == "(stdin)") {
+		return stdin;
+	} else if (fileBuf == "(stdout)") {
+		return stdout;
+	} else if (fileBuf == "(stderr)") {
+		return stderr;
+	}
+	if (file)
+		return file;
+
+
 #if !defined(__GP32__) && !defined(PALMOS_MODE)
 	// Add a trailing slash, if necessary.
 	if (!dirBuf.empty()) {
@@ -443,7 +454,7 @@
 }
 
 void File::close() {
-	if (_handle)
+	if (_handle && !(_handle == stdin || _handle == stdout || _handle == stderr))
 		fclose((FILE *)_handle);
 	_handle = NULL;
 }

Modified: residual/trunk/engine/lua/liolib.cpp
===================================================================
--- residual/trunk/engine/lua/liolib.cpp	2008-08-02 21:14:54 UTC (rev 33539)
+++ residual/trunk/engine/lua/liolib.cpp	2008-08-02 21:20:13 UTC (rev 33540)
@@ -5,16 +5,18 @@
 */
 
 
+#include "common/savefile.h"
+
 #include "engine/lua/lauxlib.h"
 #include "engine/lua/lua.h"
 #include "engine/lua/luadebug.h"
 #include "engine/lua/lualib.h"
 
 #include "engine/resource.h"
+#include "engine/cmd_line.h"
+#include "engine/savegame.h"
 #include "engine/backend/platform/driver.h"
 
-#include <errno.h>
-
 #define CLOSEDTAG	2
 #define IOTAG		1
 
@@ -23,6 +25,42 @@
 #define FINPUT		"_INPUT"
 #define FOUTPUT		"_OUTPUT"
 
+Common::File *g_fin;
+Common::File *g_fout;
+Common::File *g_stdin;
+Common::File *g_stdout;
+Common::File *g_stderr;
+
+
+extern Common::SaveFileManager *g_saveFileMan;
+
+static void join_paths(const char *filename, const char *directory,
+								 char *buf, int bufsize) {
+	buf[bufsize - 1] = '\0';
+	strncpy(buf, directory, bufsize - 1);
+
+#ifdef WIN32
+	// Fix for Win98 issue related with game directory pointing to root drive ex. "c:\"
+	if ((buf[0] != 0) && (buf[1] == ':') && (buf[2] == '\\') && (buf[3] == 0)) {
+		buf[2] = 0;
+	}
+#endif
+
+	const int dirLen = strlen(buf);
+
+	if (dirLen > 0) {
+#if defined(__MORPHOS__) || defined(__amigaos4__)
+		if (buf[dirLen - 1] != ':' && buf[dirLen - 1] != '/')
+#endif
+
+#if !defined(__GP32__)
+		strncat(buf, "/", bufsize - 1);	// prevent double /
+#endif
+	}
+	strncat(buf, filename, bufsize - 1);
+}
+
+
 static int32 gettag(int32 i) {
 	return (int32)lua_getnumber(lua_getparam(i));
 }
@@ -32,11 +70,10 @@
 		lua_pushuserdata(NULL);
 	else {
 		lua_pushnil();
-		lua_pushstring(strerror(errno));
+		lua_pushstring("File I/O error.");
 	}
 }
 
-
 static int32 ishandler(lua_Object f) {
 	if (lua_isuserdata(f)) {
 		if (lua_tag(f) == gettag(CLOSEDTAG))
@@ -46,100 +83,154 @@
 	else return 0;
 }
 
-static FILE *getfile(const char *name) {
+static Common::File *getfile(const char *name) {
 	lua_Object f = lua_getglobal(name);
 	if (!ishandler(f))
 		luaL_verror("global variable `%.50s' is not a file handle", name);
-	return (FILE *)lua_getuserdata(f);
+	return (Common::File *)lua_getuserdata(f);
 }
 
-static FILE *getfileparam(const char *name, int32 *arg) {
+static Common::File *getfileparam(const char *name, int32 *arg) {
 	lua_Object f = lua_getparam(*arg);
 	if (ishandler(f)) {
 		(*arg)++;
-		return (FILE *)lua_getuserdata(f);
+		return (Common::File *)lua_getuserdata(f);
 	} else
 		return getfile(name);
 }
 
-static void closefile (const char *name) {
-	FILE *f = getfile(name);
-	if (f == stdin || f == stdout)
-		return;
-	fclose(f);
+static void closefile(const char *name) {
+	Common::File *f = getfile(name);
+	f->close();
 	lua_pushobject(lua_getglobal(name));
 	lua_settag(gettag(CLOSEDTAG));
 }
 
-
-static void setfile(FILE *f, const char *name, int32 tag) {
+static void setfile(Common::File *f, const char *name, int32 tag) {
 	lua_pushusertag(f, tag);
 	lua_setglobal(name);
 }
 
-static void setreturn(FILE *f, const char *name) {
+static void setreturn(Common::File *f, const char *name) {
 	int32 tag = gettag(IOTAG);
 	setfile(f, name, tag);
 	lua_pushusertag(f, tag);
 }
 
 static void io_readfrom() {
-	FILE *current;
 	lua_Object f = lua_getparam(FIRSTARG);
 	if (f == LUA_NOOBJECT) {
 		closefile(FINPUT);
-		current = stdin;
+		setreturn(g_fin, FINPUT);
 	} else if (lua_tag(f) == gettag(IOTAG)) {
-		current = (FILE *)lua_getuserdata(f);
+		Common::File *current = (Common::File *)lua_getuserdata(f);
+		if (!current) {
+			pushresult(0);
+			return;
+		}
+		setreturn(current, FINPUT);
 	} else {
 		const char *s = luaL_check_string(FIRSTARG);
-		current = fopen(s, "r");
-		//      if (current == NULL)
-		//	    current = g_resourceloader->openNewStream(s);
+		Common::File *current = new Common::File();
+		Common::String dir = ConfMan.get("savepath");
+#ifdef _WIN32_WCE
+		if (dir.empty())
+			dir = ConfMan.get("path");
+#endif
+		char buf[256];
+		join_paths(s, dir.c_str(), buf, sizeof(buf));
+		if (current->exists(buf))
+			current->open(buf);
+		if (!current->isOpen()) {
+			delete current;
+			current = g_resourceloader->openNewStream(s);
+		}
+		if (!current) {
+			pushresult(0);
+			return;
+		}
+		setreturn(current, FINPUT);
 	}
-	if (!current) {
-		pushresult(0);
-		return;
-	}
-	setreturn(current, FINPUT);
 }
 
 static void io_writeto() {
-	FILE *current;
 	lua_Object f = lua_getparam(FIRSTARG);
 	if (f == LUA_NOOBJECT) {
 		closefile(FOUTPUT);
-		current = stdout;
-	} else if (lua_tag(f) == gettag(IOTAG))
-		current = (FILE *)lua_getuserdata(f);
-	else {
+		setreturn(g_fout, FOUTPUT);
+	} else if (lua_tag(f) == gettag(IOTAG)) {
+		Common::File *current = (Common::File *)lua_getuserdata(f);
+		if (!current->isOpen()) {
+			pushresult(0);
+			return;
+		}
+		setreturn(current, FOUTPUT);
+	} else {
 		const char *s = luaL_check_string(FIRSTARG);
-		current = fopen(s, "w");
-		if (!current) {
+		Common::File *current = new Common::File();
+		Common::String dir = ConfMan.get("savepath");
+#ifdef _WIN32_WCE
+		if (dir.empty())
+			dir = ConfMan.get("path");
+#endif
+		char buf[256];
+		join_paths(s, dir.c_str(), buf, sizeof(buf));
+		current->open(buf, Common::File::kFileWriteMode);
+		if (!current->isOpen()) {
+			delete current;
 			pushresult(0);
 			return;
 		}
+		setreturn(current, FOUTPUT);
 	}
-	setreturn(current, FOUTPUT);
 }
 
 static void io_appendto() {
 	const char *s = luaL_check_string(FIRSTARG);
-	FILE *fp = fopen (s, "a");
-	if (fp)
+	Common::File file;
+	Common::File *current = new Common::File();
+	Common::String dir = ConfMan.get("savepath");
+#ifdef _WIN32_WCE
+	if (dir.empty())
+		dir = ConfMan.get("path");
+#endif
+	char path[256];
+	join_paths(s, dir.c_str(), path, sizeof(path));
+	file.open(path);
+	if (!file.isOpen()) {
+		pushresult(0);
+		return;
+	}
+	int size = file.size();
+	byte *buf = new byte[size];
+	file.read(buf, size);
+	file.close();
+
+	Common::File *fp = new Common::File();
+	fp->open(path, Common::File::kFileWriteMode);
+	if (fp->isOpen()) {
+		fp->write(buf, size);
 		setreturn(fp, FOUTPUT);
-	else
+	} else {
+		delete fp;
 		pushresult(0);
+	}
+	delete buf;
 }
 
 #define NEED_OTHER (EOF - 1)  // just some flag different from EOF
 
-static void read_until(FILE *f, int32 lim) {
+static void read_until(Common::File *f, int32 lim) {
 	int32 l = 0;
-	int32 c;
-	for (c = getc(f); c != EOF && c != lim; c = getc(f)) {
+	int8 c;
+
+	if (f->read(&c, 1) == 0)
+		c = EOF;
+	for (; c != EOF && c != lim; ) {
 		luaL_addchar(c);
 		l++;
+		if (f->read(&c, 1) == 0)
+			c = EOF;
 	}
 	if (l > 0 || c == lim)  // read anything?
 		lua_pushlstring(luaL_buffer(), l);
@@ -147,17 +238,17 @@
 
 static void io_read() {
 	int32 arg = FIRSTARG;
-	FILE *f = getfileparam(FINPUT, &arg);
+	Common::File *f = (Common::File *)getfileparam(FINPUT, &arg);
 	const char *p = luaL_opt_string(arg, NULL);
 	luaL_resetbuffer();
-	if (p == NULL)  // default: read a line
+	if (!p)  // default: read a line
 		read_until(f, '\n');
 	else if (p[0] == '.' && p[1] == '*' && p[2] == 0)  // p = ".*"
 		read_until(f, EOF);
 	else {
 		int32 l = 0;  // number of chars read in buffer
 		int32 inskip = 0;  // to control {skips}
-		int32 c = NEED_OTHER;
+		int8 c = NEED_OTHER;
 		while (*p) {
 			switch (*p) {
 			case '{':
@@ -174,8 +265,10 @@
 				{
 					const char *ep;  // get what is next
 					int32 m;  // match result
-					if (c == NEED_OTHER)
-						c = getc(f);
+					if (c == NEED_OTHER) {
+						if (f->read(&c, 1) == 0)
+							c = EOF;
+					}
 					if (c == EOF) {
 						luaI_singlematch(0, p, &ep);  // to set "ep"
 						m = 0;
@@ -192,7 +285,7 @@
 					switch (*ep) {
 					case '*':  // repetition
 						if (!m)
-						p = ep + 1;  // else stay in (repeat) the same item
+							p = ep + 1;  // else stay in (repeat) the same item
 						continue;
 					case '?':  // optional
 						p = ep + 1;  // continues reading the pattern
@@ -208,7 +301,7 @@
 		}
 break_while:
 		if (c >= 0)  // not EOF nor NEED_OTHER?
-			ungetc(c, f);
+			f->seek(-1, SEEK_CUR);
 		if (l > 0 || *p == 0)  // read something or did not fail?
 			lua_pushlstring(luaL_buffer(), l);
 	}
@@ -216,12 +309,12 @@
 
 static void io_write() {
 	int32 arg = FIRSTARG;
-	FILE *f = getfileparam(FOUTPUT, &arg);
+	Common::File *f = (Common::File *)getfileparam(FOUTPUT, &arg);
 	int32 status = 1;
 	const char *s;
 	int32 l;
 	while ((s = luaL_opt_lstr(arg++, NULL, &l)))
-		status = status && (fwrite(s, 1, l, f) == (size_t)l);
+		status = status && (f->write(s, l) == (size_t)l);
 	pushresult(status);
 }
 
@@ -239,46 +332,54 @@
 	exit((int)lua_isnumber(o) ? (int)lua_getnumber(o) : 1);
 }
 
-static void lua_printstack(FILE *f) {
+static void lua_printstack() {
 	int32 level = 1;  // skip level 0 (it's this function)
 	lua_Object func;
+	char buf[256];
 	while ((func = lua_stackedfunction(level++)) != LUA_NOOBJECT) {
 		const char *name;
 		int32 currentline;
 		const char *filename;
 		int32 linedefined;
 		lua_funcinfo(func, &filename, &linedefined);
-		fprintf(f, (level == 2) ? "Active Stack:\n\t" : "\t");
+		printf(buf, (level == 2) ? "Active Stack:\n\t" : "\t");
+		g_stderr->write(buf, strlen(buf));
 		switch (*lua_getobjname(func, &name)) {
 		case 'g':
-			fprintf(f, "function %s", name);
+			printf(buf, "function %s", name);
 			break;
 		case 't':
-			fprintf(f, "`%s' tag method", name);
+			printf(buf, "`%s' tag method", name);
 			break;
 		default: 
 			{
 				if (linedefined == 0)
-					fprintf(f, "main of %s", filename);
+					printf(buf, "main of %s", filename);
 				else if (linedefined < 0)
-					fprintf(f, "%s", filename);
+					printf(buf, "%s", filename);
 				else
-					fprintf(f, "function (%s:%d)", filename, (int)linedefined);
+					printf(buf, "function (%s:%d)", filename, (int)linedefined);
 				filename = NULL;
 			}
 		}
+		g_stderr->write(buf, strlen(buf));
 
-		if ((currentline = lua_currentline(func)) > 0)
-			fprintf(f, " at line %d", (int)currentline);
-		if (filename)
-			fprintf(f, " [in file %s]", filename);
-		fprintf(f, "\n");
+		if ((currentline = lua_currentline(func)) > 0) {
+			printf(buf, " at line %d", (int)currentline);
+			g_stderr->write(buf, strlen(buf));
+		}
+		if (filename) {
+			printf(buf, " [in file %s]", filename);
+			g_stderr->write(buf, strlen(buf));
+		}
+		printf(buf, "\n");
+		g_stderr->write(buf, strlen(buf));
 	}
 }
 
 static void errorfb() {
 	fprintf(stderr, "lua: %s\n", lua_getstring(lua_getparam(1)));
-	lua_printstack(stderr);
+	lua_printstack();
 }
 
 static struct luaL_reg iolib[] = {
@@ -306,17 +407,51 @@
 		lua_pushcclosure(iolibtag[i].func, 2);
 		lua_setglobal(iolibtag[i].name);
 	}
-	setfile(stdin, FINPUT, iotag);
-	setfile(stdout, FOUTPUT, iotag);
-	setfile(stdin, "_STDIN", iotag);
-	setfile(stdout, "_STDOUT", iotag);
-	setfile(stderr, "_STDERR", iotag);
+
+	g_fin = new Common::File();
+	g_fin->open("(stdin)");
+	if (!g_fin->isOpen())
+		delete g_fin;
+	else
+		setfile(g_fin, FINPUT, iotag);
+	g_fout = new Common::File();
+	g_fout->open("(stdout)", Common::File::kFileWriteMode);
+	if (!g_fout->isOpen())
+		delete g_fout;
+	else
+		setfile(g_fout, FOUTPUT, iotag);
+	g_stdin = new Common::File();
+	g_stdin->open("(stdin)");
+	if (!g_stdin->isOpen())
+		delete g_stdin;
+	else
+		setfile(g_stdin, "_STDIN", iotag);
+	g_stdout = new Common::File();
+	g_stdout->open("(stdout)", Common::File::kFileWriteMode);
+	if (!g_stdout->isOpen())
+		delete g_stdout;
+	else
+		setfile(g_stdout, "_STDOUT", iotag);
+	g_stderr = new Common::File();
+	g_stderr->open("(stderr)", Common::File::kFileWriteMode);
+	if (!g_stderr->isOpen())
+		delete g_stderr;
+	else
+		setfile(g_stderr, "_STDERR", iotag);
 }
 
 void lua_iolibopen() {
 	luaL_openlib(iolib, (sizeof(iolib) / sizeof(iolib[0])));
-	luaL_addlibtolist(iolibtag, (sizeof(iolib) / sizeof(iolib[0])));
+	luaL_addlibtolist(iolibtag, (sizeof(iolibtag) / sizeof(iolibtag[0])));
 	openwithtags();
 	lua_pushcfunction(errorfb);
 	lua_seterrormethod();
 }
+
+void lua_iolibclose() {
+	delete g_fin;
+	delete g_fout;
+	delete g_stdin;
+	delete g_stdout;
+	delete g_stderr;
+}

Modified: residual/trunk/engine/lua/lstate.cpp
===================================================================
--- residual/trunk/engine/lua/lstate.cpp	2008-08-02 21:14:54 UTC (rev 33539)
+++ residual/trunk/engine/lua/lstate.cpp	2008-08-02 21:20:13 UTC (rev 33540)
@@ -17,6 +17,7 @@
 #include "engine/lua/ltable.h"
 #include "engine/lua/ltask.h"
 #include "engine/lua/ltm.h"
+#include "engine/lua/lualib.h"
 
 lua_State *lua_state = NULL;
 
@@ -93,6 +94,7 @@
 	luaM_free(L->Mbuffer);
 	luaM_free(L);
 	L = NULL;
+	lua_iolibclose();
 #ifdef LUA_DEBUG
 	printf("total de blocos: %ld\n", numblocks);
 	printf("total de memoria: %ld\n", totalmem);

Modified: residual/trunk/engine/lua/lualib.h
===================================================================
--- residual/trunk/engine/lua/lualib.h	2008-08-02 21:14:54 UTC (rev 33539)
+++ residual/trunk/engine/lua/lualib.h	2008-08-02 21:20:13 UTC (rev 33540)
@@ -13,6 +13,7 @@
 void lua_iolibopen();
 void lua_strlibopen();
 void lua_mathlibopen();
+void lua_iolibclose();
 
 // To keep compatibility with old versions
 


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list