[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