Просмотр исходного кода

Use setjmp based scheme to handle errors when compiling data

Daniele Bartolini 10 лет назад
Родитель
Сommit
fd642f41a9
3 измененных файлов с 58 добавлено и 24 удалено
  1. 21 10
      src/compilers/bundle_compiler.cpp
  2. 22 1
      src/compilers/compile_options.h
  3. 15 13
      src/resource/lua_resource.cpp

+ 21 - 10
src/compilers/bundle_compiler.cpp

@@ -27,6 +27,7 @@
 #include "font_resource.h"
 #include "level_resource.h"
 #include "shader.h"
+#include <setjmp.h>
 
 namespace crown
 {
@@ -93,13 +94,23 @@ bool BundleCompiler::compile(const char* type, const char* name, const char* pla
 
 	CE_LOGI("%s <= %s.%s", res_name, name, type);
 
+	bool success = true;
+	jmp_buf buf;
+
 	File* outf = _bundle_fs.open(path.c_str(), FOM_WRITE);
+	CompileOptions opts(_source_fs, outf, platform, &buf);
 
-	CompileOptions opts(_source_fs, outf, platform);
-	compile(_type, src_path.c_str(), opts);
+	if (!setjmp(buf))
+	{
+		compile(_type, src_path.c_str(), opts);
+	}
+	else
+	{
+		success = false;
+	}
 
 	_bundle_fs.close(outf);
-	return true;
+	return success;
 }
 
 bool BundleCompiler::compile_all(const char* platform)
@@ -143,7 +154,8 @@ bool BundleCompiler::compile_all(const char* platform)
 		strncpy(name, filename, size);
 		name[size] = '\0';
 
-		compile(type, name, platform);
+		if (!compile(type, name, platform))
+			return false;
 	}
 
 	return true;
@@ -194,16 +206,15 @@ namespace bundle_compiler
 {
 	bool main(bool do_compile, bool do_continue, const char* platform)
 	{
+		bool can_proceed = true;
+
 		if (do_compile)
 		{
-			bool ok = bundle_compiler_globals::compiler()->compile_all(platform);
-			if (!ok || !do_continue)
-			{
-				return false;
-			}
+			bool success = bundle_compiler_globals::compiler()->compile_all(platform);
+			can_proceed = !(!success || !do_continue);
 		}
 
-		return true;
+		return can_proceed;
 	}
 } // namespace bundle_compiler
 

+ 22 - 1
src/compilers/compile_options.h

@@ -7,17 +7,37 @@
 
 #include "filesystem.h"
 #include "reader_writer.h"
+#include "log.h"
+#include <setjmp.h>
+
+#define RESOURCE_COMPILER_ASSERT(condition, opts, msg, ...) do { if (!(condition))\
+	{ opts.error(msg, ##__VA_ARGS__); } } while(0)
 
 namespace crown
 {
 
 struct CompileOptions
 {
-	CompileOptions(Filesystem& fs, File* out, const char* platform)
+	CompileOptions(Filesystem& fs, File* out, const char* platform, jmp_buf* buf)
 		: _fs(fs)
 		, _bw(*out)
 		, _platform(platform)
+		, _jmpbuf(buf)
+	{
+	}
+
+	void error(const char* msg, va_list args)
+	{
+		CE_LOGEV(msg, args);
+		longjmp(*_jmpbuf, 1);
+	}
+
+	void error(const char* msg, ...)
 	{
+		va_list args;
+		va_start(args, msg);
+		error(msg, args);
+		va_end(args);
 	}
 
 	Buffer read(const char* path)
@@ -70,6 +90,7 @@ struct CompileOptions
 	Filesystem& _fs;
 	BinaryWriter _bw;
 	const char* _platform;
+	jmp_buf* _jmpbuf;
 };
 
 } // namespace crown

+ 15 - 13
src/resource/lua_resource.cpp

@@ -36,25 +36,27 @@ namespace lua_resource
 	{
 		using namespace string_stream;
 
-		TempAllocator1024 alloc;
-		DynamicString res_abs_path(alloc);
-		TempAllocator1024 alloc2;
-		DynamicString bc_abs_path(alloc2);
-		opts.get_absolute_path(path, res_abs_path);
-		opts.get_absolute_path("bc.tmp", bc_abs_path);
-
 		TempAllocator1024 ta;
+		DynamicString luasrc(ta);
+		DynamicString luabin(ta);
+		opts.get_absolute_path(path, luasrc);
+		opts.get_absolute_path("luabin.tmp", luabin);
+
 		StringStream args(ta);
 		args << " " << LUAJIT_FLAGS;
-		args << " " << res_abs_path.c_str();
-		args << " " << bc_abs_path.c_str();
+		args << " " << luasrc.c_str();
+		args << " " << luabin.c_str();
 
 		StringStream output(ta);
 		int exitcode = os::execute_process(LUAJIT_EXE, c_str(args), output);
-		CE_ASSERT(exitcode == 0, "Failed to compile lua:\n%s", c_str(output));
-
-		Buffer blob = opts.read(bc_abs_path.c_str());
-		opts.delete_file(bc_abs_path.c_str());
+		RESOURCE_COMPILER_ASSERT(exitcode == 0
+			, opts
+			, "Failed to compile lua:\n%s"
+			, c_str(output)
+			);
+
+		Buffer blob = opts.read(luabin.c_str());
+		opts.delete_file(luabin.c_str());
 
 		LuaResource lr;
 		lr.version = SCRIPT_VERSION;