diff --git a/configure.ac b/configure.ac index 30386655..215ca73b 100644 --- a/configure.ac +++ b/configure.ac @@ -88,7 +88,7 @@ AC_CHECK_HEADERS(cxxabi.h) AC_LANG_POP(C++) dnl Common C functions -AC_CHECK_FUNCS(getenv getcwd _getcwd backtrace_symbols) +AC_CHECK_FUNCS(getenv system tmpfile tmpnam getcwd _getcwd backtrace_symbols) if test "${enable_debug}" = "yes"; then diff --git a/src/image/codec/ps3-image.cpp b/src/image/codec/ps3-image.cpp index f129fe84..0950e5bf 100644 --- a/src/image/codec/ps3-image.cpp +++ b/src/image/codec/ps3-image.cpp @@ -14,6 +14,7 @@ #if defined __CELLOS_LV2__ +#include #include #include @@ -98,7 +99,7 @@ bool Ps3ImageData::Open(char const *path) Array pathlist = System::GetPathList(path); for (int i = 0; i < pathlist.Count(); ++i) { - String name = String("/app_home/") + pathlist[i]; + String name = String(SYS_APP_HOME) + '/' + pathlist[i]; dec_src.fileName = name.C(); err = cellPngDecOpen(hmain, &hsub, &dec_src, &open_info); if (err == CELL_OK) diff --git a/src/lol/base/assert.h b/src/lol/base/assert.h index 2b898825..42fd85b4 100644 --- a/src/lol/base/assert.h +++ b/src/lol/base/assert.h @@ -25,17 +25,19 @@ static inline void Abort() #endif } +extern void DumpStack(); + /* FIXME: see http://stackoverflow.com/q/3596781/111461 for discussions * on implementing __debugbreak() on POSIX systems. */ -static inline void DebugBreak() +static inline void DebugAbort() { + DumpStack(); #if defined _WIN32 __debugbreak(); #endif + Abort(); } -extern void DumpStack(); - #define LOL_CALL(macro, args) macro args #define LOL_EVAL(a) a #define LOL_1ST(a, ...) a @@ -117,9 +119,7 @@ extern void DumpStack(); LOL_CALL(LOL_CAT(LOL_ERROR_, LOL_CALL(LOL_COUNT_TO_3, \ (__VA_ARGS__))), \ (__VA_ARGS__)); \ - DumpStack(); \ - DebugBreak(); \ - Abort(); \ + DebugAbort(); \ } #endif diff --git a/src/lol/sys/file.h b/src/lol/sys/file.h index 4f7363c1..173f4ebf 100644 --- a/src/lol/sys/file.h +++ b/src/lol/sys/file.h @@ -43,9 +43,12 @@ public: ~File(); void Open(String const &file, FileAccess mode); - String ReadString(); + bool IsValid() const; void Close(); + int Read(uint8_t *buf, int count); + String ReadString(); + private: class FileData *m_data; }; diff --git a/src/lua/linit.c b/src/lua/linit.c index a62aeeca..10417a1c 100644 --- a/src/lua/linit.c +++ b/src/lua/linit.c @@ -34,8 +34,10 @@ static const luaL_Reg loadedlibs[] = { {LUA_LOADLIBNAME, luaopen_package}, {LUA_COLIBNAME, luaopen_coroutine}, {LUA_TABLIBNAME, luaopen_table}, +#if 0 // LOL BEGIN {LUA_IOLIBNAME, luaopen_io}, {LUA_OSLIBNAME, luaopen_os}, +#endif // LOL END {LUA_STRLIBNAME, luaopen_string}, {LUA_BITLIBNAME, luaopen_bit32}, {LUA_MATHLIBNAME, luaopen_math}, diff --git a/src/sys/file.cpp b/src/sys/file.cpp index 9f639ab7..95aadbf7 100644 --- a/src/sys/file.cpp +++ b/src/sys/file.cpp @@ -12,8 +12,24 @@ # include "config.h" #endif +#if __CELLOS_LV2__ +# include +# include +#endif + #include "core.h" +/* HACK: use fopen() for now so that we get FIOS. */ +#if 0//__CELLOS_LV2__ +extern "C" { +# include +} +# undef __CELLOS_LV2__ +# define HAVE_STDIO_H 1 +# undef BUFSIZ +# define BUFSIZ 1024 +#endif + namespace lol { @@ -24,35 +40,69 @@ class FileData void Open(String const &file, FileAccess mode) { #if __CELLOS_LV2__ + String realfile = String(SYS_APP_HOME) + '/' + file; + CellFsErrno err = cellFsOpen(realfile.C(), CELL_FS_O_RDONLY, + &m_fd, NULL, 0); + if (err != CELL_FS_SUCCEEDED) + m_fd = -1; #elif HAVE_STDIO_H /* FIXME: no modes, no error checking, no nothing */ m_fd = fopen(file.C(), "r"); #endif } - String ReadString() + inline bool IsValid() const { - String ret; #if __CELLOS_LV2__ + return m_fd > -1; +#elif HAVE_STDIO_H + return !!m_fd; +#endif + } + + int Read(uint8_t *buf, int count) + { +#if __CELLOS_LV2__ + uint64_t done; + CellFsErrno err = cellFsRead(m_fd, buf, count, &done); + + if (err != CELL_FS_SUCCEEDED) + return -1; + + return (int)done; #elif HAVE_STDIO_H - while (m_fd && !feof(m_fd)) + size_t done = fread(buf, 1, count, m_fd); + if (done <= 0) + return -1; + + return (int)done; +#endif + } + + String ReadString() + { + String ret; + while (IsValid()) { - char buf[BUFSIZ]; - size_t count = fread(buf, 1, BUFSIZ, m_fd); - if (count <= 0) + /* XXX: BUFSIZ would overflow the stack here */ + uint8_t buf[1024]; + int done = Read(buf, 1024); + + if (done <= 0) break; int oldsize = ret.Count(); - ret.Resize(oldsize + count); - memcpy(&ret[oldsize], buf, count); + ret.Resize(oldsize + done); + memcpy(&ret[oldsize], buf, done); } -#endif return ret; } void Close() { #if __CELLOS_LV2__ + if (m_fd >= 0) + cellFsClose(m_fd); #elif HAVE_STDIO_H if (m_fd) fclose(m_fd); @@ -61,6 +111,7 @@ class FileData } #if __CELLOS_LV2__ + int m_fd; #elif HAVE_STDIO_H FILE *m_fd; #endif @@ -84,6 +135,7 @@ File &File::operator =(File const &that) if (this == &that) return *this; + /* FIXME: this needs auditing */ int refcount = --m_data->m_refcount; if (refcount == 0) { @@ -112,6 +164,16 @@ void File::Open(String const &file, FileAccess mode) return m_data->Open(file, mode); } +bool File::IsValid() const +{ + return m_data->IsValid(); +} + +int File::Read(uint8_t *buf, int count) +{ + return m_data->Read(buf, count); +} + String File::ReadString() { return m_data->ReadString(); diff --git a/src/world.cpp b/src/world.cpp index c4592976..6364c43b 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -31,6 +31,12 @@ class WorldData { friend class World; + static int LuaPanic(lua_State* L) + { + DebugAbort(); + return 0; + } + lua_State *m_lua_state; }; @@ -44,6 +50,7 @@ World g_world; World::World() { g_world_data.m_lua_state = luaL_newstate(); + lua_atpanic(g_world_data.m_lua_state, WorldData::LuaPanic); luaL_openlibs(g_world_data.m_lua_state); } @@ -55,18 +62,32 @@ World::~World() bool World::ExecLua(String const &lua) { Array pathlist = System::GetPathList(lua); + File f; for (int i = 0; i < pathlist.Count(); ++i) { - luaL_dofile(g_world_data.m_lua_state, pathlist[i].C()); + f.Open(pathlist[i], FileAccess::Read); + if (f.IsValid()) + { + String s = f.ReadString(); + f.Close(); + + luaL_dostring(g_world_data.m_lua_state, s.C()); + Log::Debug("loaded Lua file %s\n", pathlist[i].C()); + return true; + } } - return true; + Log::Error("could not find Lua file %s\n", lua.C()); + return false; } double World::GetLuaNumber(String const &var) { + double ret; lua_getglobal(g_world_data.m_lua_state, var.C()); - return lua_tonumber(g_world_data.m_lua_state, -1); + ret = lua_tonumber(g_world_data.m_lua_state, -1); + lua_pop(g_world_data.m_lua_state, 1); + return ret; } } /* namespace lol */