2003-08-15 18:00:22 +00:00
|
|
|
/*
|
|
|
|
** $Id$
|
|
|
|
** Standard I/O (and system) library
|
|
|
|
** See Copyright Notice in lua.h
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
2008-08-02 21:20:13 +00:00
|
|
|
#include "common/savefile.h"
|
2008-08-03 19:39:29 +00:00
|
|
|
#include "common/fs.h"
|
2009-05-07 19:06:31 +00:00
|
|
|
#include "common/system.h"
|
2008-08-02 21:20:13 +00:00
|
|
|
|
2008-07-29 08:05:28 +00:00
|
|
|
#include "engine/lua/lauxlib.h"
|
|
|
|
#include "engine/lua/lua.h"
|
|
|
|
#include "engine/lua/luadebug.h"
|
|
|
|
#include "engine/lua/lualib.h"
|
2003-08-15 18:00:22 +00:00
|
|
|
|
2008-07-26 18:05:08 +00:00
|
|
|
#include "engine/resource.h"
|
2008-08-02 21:20:13 +00:00
|
|
|
#include "engine/cmd_line.h"
|
2009-04-05 14:48:54 +00:00
|
|
|
#include "engine/engine.h"
|
2008-08-02 21:20:13 +00:00
|
|
|
#include "engine/savegame.h"
|
2008-07-26 20:27:15 +00:00
|
|
|
|
2008-08-03 19:48:17 +00:00
|
|
|
#if defined(UNIX) || defined(__SYMBIAN32__)
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#endif
|
|
|
|
|
2008-08-03 19:39:29 +00:00
|
|
|
#ifdef _WIN32
|
|
|
|
#include <direct.h>
|
|
|
|
#endif
|
|
|
|
|
2003-08-15 18:00:22 +00:00
|
|
|
#define CLOSEDTAG 2
|
|
|
|
#define IOTAG 1
|
|
|
|
|
2008-07-29 08:05:28 +00:00
|
|
|
#define FIRSTARG 3 // 1st and 2nd are upvalues
|
2003-08-15 18:00:22 +00:00
|
|
|
|
|
|
|
#define FINPUT "_INPUT"
|
|
|
|
#define FOUTPUT "_OUTPUT"
|
|
|
|
|
2009-04-05 14:48:54 +00:00
|
|
|
LuaFile *g_fin;
|
|
|
|
LuaFile *g_fout;
|
|
|
|
LuaFile *g_stdin;
|
|
|
|
LuaFile *g_stdout;
|
|
|
|
LuaFile *g_stderr;
|
2008-08-02 21:20:13 +00:00
|
|
|
|
2009-04-05 14:48:54 +00:00
|
|
|
LuaFile::LuaFile() : _in(NULL), _out(NULL), _file(NULL), _stdin(false), _stdout(false), _stderr(false) {
|
2008-08-03 19:39:29 +00:00
|
|
|
}
|
|
|
|
|
2009-04-05 14:48:54 +00:00
|
|
|
LuaFile::~LuaFile() {
|
|
|
|
close();
|
|
|
|
}
|
2008-08-02 21:20:13 +00:00
|
|
|
|
2009-04-05 14:48:54 +00:00
|
|
|
void LuaFile::close() {
|
|
|
|
delete _in;
|
|
|
|
delete _out;
|
|
|
|
_in = NULL;
|
|
|
|
_out = NULL;
|
|
|
|
_stdin = _stdout = _stderr = false;
|
|
|
|
}
|
2008-08-02 21:20:13 +00:00
|
|
|
|
2009-04-05 14:48:54 +00:00
|
|
|
bool LuaFile::isOpen() const {
|
|
|
|
return _in || _out || _stdin || stdout || stderr;
|
|
|
|
}
|
2008-08-02 21:20:13 +00:00
|
|
|
|
2009-04-05 14:48:54 +00:00
|
|
|
uint32 LuaFile::read(void *buf, uint32 len) {
|
|
|
|
if (_stdin) {
|
|
|
|
return fread(buf, len, 1, stdin);
|
|
|
|
} else if (_in) {
|
|
|
|
return _in->read(buf, len);
|
|
|
|
} else
|
|
|
|
assert(0);
|
|
|
|
return 0;
|
|
|
|
}
|
2008-08-02 21:20:13 +00:00
|
|
|
|
2009-04-05 14:48:54 +00:00
|
|
|
uint32 LuaFile::write(const char *buf, uint32 len) {
|
2009-05-04 17:45:42 +00:00
|
|
|
if (_stdin)
|
|
|
|
error("LuaFile::write() not allowed on stdin");
|
|
|
|
if (_in)
|
|
|
|
error("LuaFile::write() not allowed on in");
|
2009-04-05 14:48:54 +00:00
|
|
|
if (_stdout) {
|
|
|
|
return fwrite(buf, len, 1, stdout);
|
|
|
|
} else if (_stderr) {
|
|
|
|
return fwrite(buf, len, 1, stderr);
|
|
|
|
} else if (_out) {
|
|
|
|
return _out->write(buf, len);
|
|
|
|
} else
|
|
|
|
assert(0);
|
|
|
|
return 0;
|
2008-08-02 21:20:13 +00:00
|
|
|
}
|
|
|
|
|
2009-04-05 14:48:54 +00:00
|
|
|
void LuaFile::seek(int32 pos, int whence) {
|
|
|
|
if (_stdin) {
|
|
|
|
fseek(stdin, pos, whence);
|
|
|
|
} else if (_in) {
|
|
|
|
_in->seek(pos, whence);
|
|
|
|
} else
|
|
|
|
assert(0);
|
|
|
|
}
|
2008-08-02 21:20:13 +00:00
|
|
|
|
2008-07-29 08:05:28 +00:00
|
|
|
static int32 gettag(int32 i) {
|
|
|
|
return (int32)lua_getnumber(lua_getparam(i));
|
2003-08-15 18:00:22 +00:00
|
|
|
}
|
|
|
|
|
2008-07-29 08:05:28 +00:00
|
|
|
static void pushresult(int32 i) {
|
|
|
|
if (i)
|
|
|
|
lua_pushuserdata(NULL);
|
|
|
|
else {
|
|
|
|
lua_pushnil();
|
2008-08-02 21:20:13 +00:00
|
|
|
lua_pushstring("File I/O error.");
|
2008-07-29 08:05:28 +00:00
|
|
|
}
|
2003-08-15 18:00:22 +00:00
|
|
|
}
|
|
|
|
|
2008-07-29 08:05:28 +00:00
|
|
|
static int32 ishandler(lua_Object f) {
|
|
|
|
if (lua_isuserdata(f)) {
|
|
|
|
if (lua_tag(f) == gettag(CLOSEDTAG))
|
|
|
|
lua_error("cannot access a closed file");
|
|
|
|
return lua_tag(f) == gettag(IOTAG);
|
|
|
|
}
|
|
|
|
else return 0;
|
2003-08-15 18:00:22 +00:00
|
|
|
}
|
|
|
|
|
2009-04-05 14:48:54 +00:00
|
|
|
static LuaFile *getfile(const char *name) {
|
2008-07-29 08:05:28 +00:00
|
|
|
lua_Object f = lua_getglobal(name);
|
|
|
|
if (!ishandler(f))
|
|
|
|
luaL_verror("global variable `%.50s' is not a file handle", name);
|
2009-04-05 14:48:54 +00:00
|
|
|
return (LuaFile *)lua_getuserdata(f);
|
2003-08-15 18:00:22 +00:00
|
|
|
}
|
|
|
|
|
2009-04-05 14:48:54 +00:00
|
|
|
static LuaFile *getfileparam(const char *name, int32 *arg) {
|
2008-07-29 08:05:28 +00:00
|
|
|
lua_Object f = lua_getparam(*arg);
|
|
|
|
if (ishandler(f)) {
|
|
|
|
(*arg)++;
|
2009-04-05 14:48:54 +00:00
|
|
|
return (LuaFile *)lua_getuserdata(f);
|
2008-07-29 08:05:28 +00:00
|
|
|
} else
|
|
|
|
return getfile(name);
|
2003-08-15 18:00:22 +00:00
|
|
|
}
|
|
|
|
|
2008-08-02 21:20:13 +00:00
|
|
|
static void closefile(const char *name) {
|
2009-04-05 14:48:54 +00:00
|
|
|
LuaFile *f = getfile(name);
|
2008-08-02 21:20:13 +00:00
|
|
|
f->close();
|
2008-07-29 08:05:28 +00:00
|
|
|
lua_pushobject(lua_getglobal(name));
|
|
|
|
lua_settag(gettag(CLOSEDTAG));
|
2003-08-15 18:00:22 +00:00
|
|
|
}
|
|
|
|
|
2009-04-05 14:48:54 +00:00
|
|
|
static void setfile(LuaFile *f, const char *name, int32 tag) {
|
2008-07-29 08:05:28 +00:00
|
|
|
lua_pushusertag(f, tag);
|
|
|
|
lua_setglobal(name);
|
2003-08-15 18:00:22 +00:00
|
|
|
}
|
|
|
|
|
2009-04-05 14:48:54 +00:00
|
|
|
static void setreturn(LuaFile *f, const char *name) {
|
2008-07-29 08:05:28 +00:00
|
|
|
int32 tag = gettag(IOTAG);
|
|
|
|
setfile(f, name, tag);
|
|
|
|
lua_pushusertag(f, tag);
|
2003-08-15 18:00:22 +00:00
|
|
|
}
|
|
|
|
|
2008-07-29 08:05:28 +00:00
|
|
|
static void io_readfrom() {
|
|
|
|
lua_Object f = lua_getparam(FIRSTARG);
|
|
|
|
if (f == LUA_NOOBJECT) {
|
|
|
|
closefile(FINPUT);
|
2008-08-02 21:20:13 +00:00
|
|
|
setreturn(g_fin, FINPUT);
|
2008-07-29 08:05:28 +00:00
|
|
|
} else if (lua_tag(f) == gettag(IOTAG)) {
|
2009-04-05 14:48:54 +00:00
|
|
|
LuaFile *current = (LuaFile *)lua_getuserdata(f);
|
2008-08-02 21:20:13 +00:00
|
|
|
if (!current) {
|
|
|
|
pushresult(0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
setreturn(current, FINPUT);
|
2008-07-29 08:05:28 +00:00
|
|
|
} else {
|
|
|
|
const char *s = luaL_check_string(FIRSTARG);
|
2009-04-05 14:48:54 +00:00
|
|
|
LuaFile *current;
|
|
|
|
Common::SeekableReadStream *inFile = NULL;
|
2009-05-07 19:06:31 +00:00
|
|
|
Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
|
2009-04-05 14:48:54 +00:00
|
|
|
inFile = saveFileMan->openForLoading(s);
|
|
|
|
if (!inFile)
|
|
|
|
current = g_resourceloader->openNewStreamLua(s);
|
|
|
|
else {
|
|
|
|
current = new LuaFile();
|
|
|
|
current->_in = inFile;
|
2008-08-02 21:20:13 +00:00
|
|
|
}
|
|
|
|
if (!current) {
|
2009-04-05 14:48:54 +00:00
|
|
|
delete current;
|
2008-08-02 21:20:13 +00:00
|
|
|
pushresult(0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
setreturn(current, FINPUT);
|
2005-08-20 22:05:55 +00:00
|
|
|
}
|
2003-08-15 18:00:22 +00:00
|
|
|
}
|
|
|
|
|
2008-07-29 08:05:28 +00:00
|
|
|
static void io_writeto() {
|
|
|
|
lua_Object f = lua_getparam(FIRSTARG);
|
|
|
|
if (f == LUA_NOOBJECT) {
|
|
|
|
closefile(FOUTPUT);
|
2008-08-02 21:20:13 +00:00
|
|
|
setreturn(g_fout, FOUTPUT);
|
|
|
|
} else if (lua_tag(f) == gettag(IOTAG)) {
|
2009-04-05 14:48:54 +00:00
|
|
|
LuaFile *current = (LuaFile *)lua_getuserdata(f);
|
2008-08-02 21:20:13 +00:00
|
|
|
if (!current->isOpen()) {
|
|
|
|
pushresult(0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
setreturn(current, FOUTPUT);
|
|
|
|
} else {
|
2008-07-29 08:05:28 +00:00
|
|
|
const char *s = luaL_check_string(FIRSTARG);
|
2009-05-03 19:45:43 +00:00
|
|
|
if (Common::String(s).hasSuffix("\\bino.txt")) {
|
|
|
|
pushresult(0);
|
|
|
|
return;
|
|
|
|
}
|
2009-04-05 14:48:54 +00:00
|
|
|
LuaFile *current;
|
|
|
|
Common::WriteStream *outFile = NULL;
|
2009-05-07 19:06:31 +00:00
|
|
|
Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
|
2009-04-05 14:48:54 +00:00
|
|
|
outFile = saveFileMan->openForSaving(s);
|
|
|
|
if (!outFile) {
|
2008-07-29 08:05:28 +00:00
|
|
|
pushresult(0);
|
|
|
|
return;
|
|
|
|
}
|
2009-04-05 14:48:54 +00:00
|
|
|
current = new LuaFile();
|
|
|
|
current->_out = outFile;
|
2008-08-02 21:20:13 +00:00
|
|
|
setreturn(current, FOUTPUT);
|
2008-07-29 08:05:28 +00:00
|
|
|
}
|
2003-08-15 18:00:22 +00:00
|
|
|
}
|
|
|
|
|
2008-07-29 08:05:28 +00:00
|
|
|
static void io_appendto() {
|
|
|
|
const char *s = luaL_check_string(FIRSTARG);
|
2009-04-05 14:48:54 +00:00
|
|
|
Common::SeekableReadStream *inFile = NULL;
|
2009-05-07 19:06:31 +00:00
|
|
|
Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
|
2009-04-05 14:48:54 +00:00
|
|
|
inFile = saveFileMan->openForLoading(s);
|
|
|
|
if (!inFile) {
|
2008-08-02 21:20:13 +00:00
|
|
|
pushresult(0);
|
|
|
|
return;
|
|
|
|
}
|
2009-04-05 14:48:54 +00:00
|
|
|
int size = inFile->size();
|
2008-08-02 21:20:13 +00:00
|
|
|
byte *buf = new byte[size];
|
2009-04-05 14:48:54 +00:00
|
|
|
inFile->read(buf, size);
|
|
|
|
delete inFile;
|
|
|
|
|
|
|
|
Common::WriteStream *outFile = NULL;
|
|
|
|
outFile = saveFileMan->openForSaving(s);
|
|
|
|
if (!outFile)
|
2008-07-29 08:05:28 +00:00
|
|
|
pushresult(0);
|
2009-04-05 14:48:54 +00:00
|
|
|
else {
|
|
|
|
outFile->write(buf, size);
|
|
|
|
LuaFile *current = new LuaFile();
|
|
|
|
current->_out = outFile;
|
|
|
|
setreturn(current, FOUTPUT);
|
2008-08-02 21:20:13 +00:00
|
|
|
}
|
2008-08-11 19:14:03 +00:00
|
|
|
delete[] buf;
|
2003-08-15 18:00:22 +00:00
|
|
|
}
|
|
|
|
|
2008-07-29 08:05:28 +00:00
|
|
|
#define NEED_OTHER (EOF - 1) // just some flag different from EOF
|
2003-08-15 18:00:22 +00:00
|
|
|
|
2009-04-05 14:48:54 +00:00
|
|
|
static void read_until(LuaFile *f, int32 lim) {
|
2008-07-29 08:05:28 +00:00
|
|
|
int32 l = 0;
|
2008-08-02 21:20:13 +00:00
|
|
|
int8 c;
|
|
|
|
|
|
|
|
if (f->read(&c, 1) == 0)
|
|
|
|
c = EOF;
|
2009-04-05 14:48:54 +00:00
|
|
|
|
2008-08-02 21:20:13 +00:00
|
|
|
for (; c != EOF && c != lim; ) {
|
2008-07-29 08:05:28 +00:00
|
|
|
luaL_addchar(c);
|
|
|
|
l++;
|
2008-08-02 21:20:13 +00:00
|
|
|
if (f->read(&c, 1) == 0)
|
|
|
|
c = EOF;
|
2008-07-29 08:05:28 +00:00
|
|
|
}
|
|
|
|
if (l > 0 || c == lim) // read anything?
|
|
|
|
lua_pushlstring(luaL_buffer(), l);
|
2003-08-15 18:00:22 +00:00
|
|
|
}
|
|
|
|
|
2008-07-30 07:37:00 +00:00
|
|
|
static void io_read() {
|
2008-07-29 08:05:28 +00:00
|
|
|
int32 arg = FIRSTARG;
|
2009-04-05 14:48:54 +00:00
|
|
|
LuaFile *f = (LuaFile *)getfileparam(FINPUT, &arg);
|
2008-07-29 08:05:28 +00:00
|
|
|
const char *p = luaL_opt_string(arg, NULL);
|
|
|
|
luaL_resetbuffer();
|
2008-08-02 21:20:13 +00:00
|
|
|
if (!p) // default: read a line
|
2008-07-29 08:05:28 +00:00
|
|
|
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}
|
2008-08-02 21:20:13 +00:00
|
|
|
int8 c = NEED_OTHER;
|
2008-07-29 08:05:28 +00:00
|
|
|
while (*p) {
|
|
|
|
switch (*p) {
|
|
|
|
case '{':
|
|
|
|
inskip++;
|
|
|
|
p++;
|
|
|
|
continue;
|
|
|
|
case '}':
|
|
|
|
if (inskip == 0)
|
|
|
|
lua_error("unbalanced braces in read pattern");
|
|
|
|
inskip--;
|
|
|
|
p++;
|
|
|
|
continue;
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
const char *ep; // get what is next
|
|
|
|
int32 m; // match result
|
2008-08-02 21:20:13 +00:00
|
|
|
if (c == NEED_OTHER) {
|
|
|
|
if (f->read(&c, 1) == 0)
|
|
|
|
c = EOF;
|
|
|
|
}
|
2008-07-29 08:05:28 +00:00
|
|
|
if (c == EOF) {
|
|
|
|
luaI_singlematch(0, p, &ep); // to set "ep"
|
|
|
|
m = 0;
|
|
|
|
} else {
|
|
|
|
m = luaI_singlematch(c, p, &ep);
|
|
|
|
if (m) {
|
|
|
|
if (inskip == 0) {
|
|
|
|
luaL_addchar(c);
|
|
|
|
l++;
|
|
|
|
}
|
|
|
|
c = NEED_OTHER;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
switch (*ep) {
|
|
|
|
case '*': // repetition
|
|
|
|
if (!m)
|
2008-08-02 21:20:13 +00:00
|
|
|
p = ep + 1; // else stay in (repeat) the same item
|
2008-07-29 08:05:28 +00:00
|
|
|
continue;
|
|
|
|
case '?': // optional
|
|
|
|
p = ep + 1; // continues reading the pattern
|
|
|
|
continue;
|
|
|
|
default:
|
|
|
|
if (m)
|
|
|
|
p = ep; // continues reading the pattern
|
|
|
|
else
|
|
|
|
goto break_while; // pattern fails
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break_while:
|
2009-04-05 14:48:54 +00:00
|
|
|
if (c >= 0) // not EOF nor NEED_OTHER?
|
2008-08-02 21:20:13 +00:00
|
|
|
f->seek(-1, SEEK_CUR);
|
2008-07-29 08:05:28 +00:00
|
|
|
if (l > 0 || *p == 0) // read something or did not fail?
|
|
|
|
lua_pushlstring(luaL_buffer(), l);
|
|
|
|
}
|
2003-08-15 18:00:22 +00:00
|
|
|
}
|
|
|
|
|
2008-07-29 08:05:28 +00:00
|
|
|
static void io_write() {
|
|
|
|
int32 arg = FIRSTARG;
|
2009-04-05 14:48:54 +00:00
|
|
|
LuaFile *f = (LuaFile *)getfileparam(FOUTPUT, &arg);
|
2008-07-29 08:05:28 +00:00
|
|
|
int32 status = 1;
|
|
|
|
const char *s;
|
|
|
|
int32 l;
|
|
|
|
while ((s = luaL_opt_lstr(arg++, NULL, &l)))
|
2008-08-02 21:20:13 +00:00
|
|
|
status = status && (f->write(s, l) == (size_t)l);
|
2008-07-29 08:05:28 +00:00
|
|
|
pushresult(status);
|
2003-08-15 18:00:22 +00:00
|
|
|
}
|
|
|
|
|
2008-07-29 08:05:28 +00:00
|
|
|
static void io_date() {
|
|
|
|
tm t;
|
|
|
|
char b[BUFSIZ];
|
2003-08-15 18:00:22 +00:00
|
|
|
|
2009-05-07 19:06:31 +00:00
|
|
|
g_system->getTimeAndDate(t);
|
2008-07-29 08:05:28 +00:00
|
|
|
sprintf(b, "%02d.%02d.%d %02d:%02d.%02d", t.tm_mday, t.tm_mon + 1, 1900 + t.tm_year, t.tm_hour, t.tm_min, t.tm_sec);
|
|
|
|
lua_pushstring(b);
|
2003-08-15 18:00:22 +00:00
|
|
|
}
|
|
|
|
|
2008-07-29 08:05:28 +00:00
|
|
|
static void io_exit() {
|
|
|
|
lua_Object o = lua_getparam(1);
|
|
|
|
exit((int)lua_isnumber(o) ? (int)lua_getnumber(o) : 1);
|
2003-08-15 18:00:22 +00:00
|
|
|
}
|
|
|
|
|
2008-08-02 21:20:13 +00:00
|
|
|
static void lua_printstack() {
|
2008-07-29 08:05:28 +00:00
|
|
|
int32 level = 1; // skip level 0 (it's this function)
|
|
|
|
lua_Object func;
|
2008-08-02 21:20:13 +00:00
|
|
|
char buf[256];
|
2008-07-29 08:05:28 +00:00
|
|
|
while ((func = lua_stackedfunction(level++)) != LUA_NOOBJECT) {
|
|
|
|
const char *name;
|
|
|
|
int32 currentline;
|
|
|
|
const char *filename;
|
|
|
|
int32 linedefined;
|
|
|
|
lua_funcinfo(func, &filename, &linedefined);
|
2008-08-03 07:55:16 +00:00
|
|
|
sprintf(buf, (level == 2) ? "Active Stack:\n\t" : "\t");
|
2008-08-02 21:20:13 +00:00
|
|
|
g_stderr->write(buf, strlen(buf));
|
2008-07-29 08:05:28 +00:00
|
|
|
switch (*lua_getobjname(func, &name)) {
|
|
|
|
case 'g':
|
2008-08-03 07:55:16 +00:00
|
|
|
sprintf(buf, "function %s", name);
|
2008-07-29 08:05:28 +00:00
|
|
|
break;
|
|
|
|
case 't':
|
2008-08-03 07:55:16 +00:00
|
|
|
sprintf(buf, "`%s' tag method", name);
|
2008-07-29 08:05:28 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
if (linedefined == 0)
|
2008-08-03 07:55:16 +00:00
|
|
|
sprintf(buf, "main of %s", filename);
|
2008-07-29 08:05:28 +00:00
|
|
|
else if (linedefined < 0)
|
2008-08-03 07:55:16 +00:00
|
|
|
sprintf(buf, "%s", filename);
|
2008-07-29 08:05:28 +00:00
|
|
|
else
|
2008-08-03 07:55:16 +00:00
|
|
|
sprintf(buf, "function (%s:%d)", filename, (int)linedefined);
|
2008-07-29 08:05:28 +00:00
|
|
|
filename = NULL;
|
|
|
|
}
|
|
|
|
}
|
2008-08-02 21:20:13 +00:00
|
|
|
g_stderr->write(buf, strlen(buf));
|
2008-07-29 08:05:28 +00:00
|
|
|
|
2008-08-02 21:20:13 +00:00
|
|
|
if ((currentline = lua_currentline(func)) > 0) {
|
2008-08-03 07:55:16 +00:00
|
|
|
sprintf(buf, " at line %d", (int)currentline);
|
2008-08-02 21:20:13 +00:00
|
|
|
g_stderr->write(buf, strlen(buf));
|
|
|
|
}
|
|
|
|
if (filename) {
|
2008-08-03 07:55:16 +00:00
|
|
|
sprintf(buf, " [in file %s]", filename);
|
2008-08-02 21:20:13 +00:00
|
|
|
g_stderr->write(buf, strlen(buf));
|
|
|
|
}
|
2008-08-03 07:55:16 +00:00
|
|
|
sprintf(buf, "\n");
|
2008-08-02 21:20:13 +00:00
|
|
|
g_stderr->write(buf, strlen(buf));
|
2008-07-29 08:05:28 +00:00
|
|
|
}
|
2003-08-15 18:00:22 +00:00
|
|
|
}
|
|
|
|
|
2008-07-29 08:05:28 +00:00
|
|
|
static void errorfb() {
|
2008-08-03 07:55:16 +00:00
|
|
|
char buf[256];
|
|
|
|
sprintf(buf, "lua: %s\n", lua_getstring(lua_getparam(1)));
|
|
|
|
g_stderr->write(buf, strlen(buf));
|
2008-08-02 21:20:13 +00:00
|
|
|
lua_printstack();
|
2003-08-15 18:00:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static struct luaL_reg iolib[] = {
|
2008-07-29 08:05:28 +00:00
|
|
|
{ "date", io_date },
|
|
|
|
{ "exit", io_exit },
|
|
|
|
{ "print_stack", errorfb }
|
2003-08-15 18:00:22 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static struct luaL_reg iolibtag[] = {
|
2008-07-29 08:05:28 +00:00
|
|
|
{ "readfrom", io_readfrom },
|
|
|
|
{ "writeto", io_writeto },
|
|
|
|
{ "appendto", io_appendto },
|
|
|
|
{ "read", io_read },
|
|
|
|
{ "write", io_write }
|
2003-08-15 18:00:22 +00:00
|
|
|
};
|
|
|
|
|
2008-07-29 08:05:28 +00:00
|
|
|
static void openwithtags() {
|
|
|
|
int32 iotag = lua_newtag();
|
|
|
|
int32 closedtag = lua_newtag();
|
|
|
|
uint32 i;
|
|
|
|
for (i = 0; i < sizeof(iolibtag) / sizeof(iolibtag[0]); i++) {
|
|
|
|
// put both tags as upvalues for these functions
|
|
|
|
lua_pushnumber(iotag);
|
|
|
|
lua_pushnumber(closedtag);
|
|
|
|
lua_pushcclosure(iolibtag[i].func, 2);
|
|
|
|
lua_setglobal(iolibtag[i].name);
|
|
|
|
}
|
2008-08-02 21:20:13 +00:00
|
|
|
|
2009-04-05 14:48:54 +00:00
|
|
|
g_fin = new LuaFile();
|
|
|
|
g_fin->_stdin = true;
|
|
|
|
setfile(g_fin, FINPUT, iotag);
|
|
|
|
|
|
|
|
g_fout = new LuaFile();
|
|
|
|
g_fout->_stdout = true;
|
|
|
|
setfile(g_fout, FOUTPUT, iotag);
|
|
|
|
|
|
|
|
g_stdin = new LuaFile();
|
|
|
|
g_stdin->_stdin = true;
|
|
|
|
setfile(g_stdin, "_STDIN", iotag);
|
|
|
|
|
|
|
|
g_stdout = new LuaFile();
|
|
|
|
g_stdout->_stdout = true;
|
|
|
|
setfile(g_stdout, "_STDOUT", iotag);
|
|
|
|
|
|
|
|
g_stderr = new LuaFile();
|
|
|
|
g_stderr->_stderr = true;
|
|
|
|
setfile(g_stderr, "_STDERR", iotag);
|
2003-08-15 18:00:22 +00:00
|
|
|
}
|
|
|
|
|
2008-07-29 08:05:28 +00:00
|
|
|
void lua_iolibopen() {
|
|
|
|
luaL_openlib(iolib, (sizeof(iolib) / sizeof(iolib[0])));
|
2008-08-02 21:20:13 +00:00
|
|
|
luaL_addlibtolist(iolibtag, (sizeof(iolibtag) / sizeof(iolibtag[0])));
|
2008-07-29 08:05:28 +00:00
|
|
|
openwithtags();
|
|
|
|
lua_pushcfunction(errorfb);
|
|
|
|
lua_seterrormethod();
|
2003-08-15 18:00:22 +00:00
|
|
|
}
|
2008-08-02 21:20:13 +00:00
|
|
|
|
|
|
|
void lua_iolibclose() {
|
|
|
|
delete g_fin;
|
|
|
|
delete g_fout;
|
|
|
|
delete g_stdin;
|
|
|
|
delete g_stdout;
|
|
|
|
delete g_stderr;
|
|
|
|
}
|