Commits

Bart van Strien committed df4fc0c

Make most love.filesystem functions return nil, err instead of erroring (when used correctly)

Note that argument exceptions, for instance, are still thrown as errors.
Also fixes a potential uncaught exception with getSize being called for the optional
size arg in read, now it just uses the ALL constant instead.
File:read no longer opens and closes a file automagically (this was undocumented, and weird)

NOTE: the love.filesystem.lines iterator can still error, but this should only happen in
case there's something really, really wrong (otherwise love.filesystem.lines would've failed
already)
NOTE: love.filesystem.lines still errors, because otherwise you'd get weird errors from the for
loop (namely 'attempt to call nil value') instead of seeing anything useful

Comments (0)

Files changed (3)

src/modules/filesystem/physfs/File.cpp

 
 int64 File::read(void *dst, int64 size)
 {
-	bool isOpen = (file != 0);
-
-	if (!isOpen)
-		open(READ);
+	if (!file || mode != READ)
+		throw love::Exception("File is not opened for reading.");
 
 	int64 max = (int64)PHYSFS_fileLength(file);
 	size = (size == ALL) ? max : size;
 
 	int64 read = (int64)PHYSFS_read(file, dst, 1, (int) size);
 
-	if (!isOpen)
-		close();
-
 	return read;
 }
 
 bool File::write(const void *data, int64 size)
 {
-	if (file == 0)
-		throw love::Exception("Could not write to file. File not open.");
+	if (!file || (mode != WRITE && mode != APPEND))
+		throw love::Exception("File is not opened for writing.");
 
 	// Another clamp, for the time being.
 	size = (size > LOVE_UINT32_MAX) ? LOVE_UINT32_MAX : size;

src/modules/filesystem/physfs/wrap_File.cpp

 #include "common/Exception.h"
 #include "common/int.h"
 
+static int ioError(lua_State *L, const char *fmt, ...)
+{
+	va_list args;
+	va_start(args, fmt);
+
+	lua_pushnil(L);
+	lua_pushvfstring(L, fmt, args);
+
+	va_end(args);
+	return 2;
+}
+
 namespace love
 {
 namespace filesystem
 	}
 	catch (love::Exception &e)
 	{
-		return luaL_error(L, "%s", e.what());
+		return ioError(L, "%s", e.what());
 	}
 
 	return 1;
 	File *file = luax_checkfile(L, 1);
 	Data *d = 0;
 
-	int64 size = (int64)luaL_optnumber(L, 2, (lua_Number) file->getSize());
+	int64 size = (int64)luaL_optnumber(L, 2, File::ALL);
 
 	try
 	{
 	}
 	catch (love::Exception &e)
 	{
-		return luaL_error(L, "%s", e.what());
+		return ioError(L, "%s", e.what());
 	}
 
 	lua_pushlstring(L, (const char *) d->getData(), d->getSize());
 {
 	File *file = luax_checkfile(L, 1);
 	bool result;
-	if (file->getMode() == File::CLOSED)
-		return luaL_error(L, "File is not open.");
 
 	if (lua_isstring(L, 2))
 	{
 		}
 		catch (love::Exception &e)
 		{
-			return luaL_error(L, "%s", e.what());
+			return ioError(L, "%s", e.what());
 		}
 
 	}
 		}
 		catch (love::Exception &e)
 		{
-			return luaL_error(L, "%s", e.what());
+			return ioError(L, "%s", e.what());
 		}
 	}
 	else

src/modules/filesystem/physfs/wrap_Filesystem.cpp

 // LOVE
 #include "wrap_Filesystem.h"
 
+static int ioError(lua_State *L, const char *fmt, ...)
+{
+	va_list args;
+	va_start(args, fmt);
+
+	lua_pushnil(L);
+	lua_pushvfstring(L, fmt, args);
+
+	va_end(args);
+	return 2;
+}
+
 namespace love
 {
 namespace filesystem
 		catch (love::Exception &e)
 		{
 			t->release();
-			return luaL_error(L, "%s", e.what());
+			return ioError(L, "%s", e.what());
 		}
 	}
 
 			}
 			catch (love::Exception &e)
 			{
-				return luaL_error(L, "%s", e.what());
+				return ioError(L, "%s", e.what());
 			}
 			luax_newtype(L, "FileData", FILESYSTEM_FILE_DATA_T, (void *) data);
 			return 1;
 	}
 	catch (love::Exception &e)
 	{
-		return luaL_error(L, "%s", e.what());
+		return ioError(L, "%s", e.what());
 	}
 
 	if (data == 0)
-		return luaL_error(L, "File could not be read.");
+		return ioError(L, "File could not be read.");
 
 	// Push the string.
 	lua_pushlstring(L, (const char *) data->getData(), data->getSize());
 	}
 	catch (love::Exception &e)
 	{
-		return luaL_error(L, "%s", e.what());
+		return ioError(L, "%s", e.what());
 	}
 
 	luax_pushboolean(L, true);
 	}
 	catch (love::Exception &e)
 	{
-		return luaL_error(L, "%s", e.what());
+		return ioError(L, "%s", e.what());
 	}
 
 	int status = luaL_loadbuffer(L, (const char *)data->getData(), data->getSize(), ("@" + filename).c_str());
 	}
 	catch (love::Exception &e)
 	{
-		return luaL_error(L, "%s", e.what());
+		return ioError(L, "%s", e.what());
 	}
 
 	// Error on failure or if size does not fit into a double precision floating-point number.
 	if (size == -1)
-		return luaL_error(L, "Could not determine file size.");
+		return ioError(L, "Could not determine file size.");
 	else if (size >= 0x20000000000000LL)
 		return luaL_error(L, "Size too large to fit into a Lua number!");