From b8fc8cf9b66455ae5b1e22db9de59ea3791c890a Mon Sep 17 00:00:00 2001 From: cremno Date: Sun, 31 Aug 2014 09:31:18 +0200 Subject: [PATCH 1/4] fix Bitmap's object to string conversion Calling #to_s might not return a string (it should though). --- binding-mri/bitmap-binding.cpp | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/binding-mri/bitmap-binding.cpp b/binding-mri/bitmap-binding.cpp index 1461e74..a49d3e5 100644 --- a/binding-mri/bitmap-binding.cpp +++ b/binding-mri/bitmap-binding.cpp @@ -29,6 +29,12 @@ DEF_TYPE(Bitmap); +static const char *objAsStringPtr(VALUE obj) +{ + VALUE str = rb_obj_as_string(obj); + return RSTRING_PTR(str); +} + void bitmapInitProps(Bitmap *b, VALUE self) { /* Wrap properties */ @@ -258,10 +264,7 @@ RB_METHOD(bitmapDrawText) VALUE strObj; rb_get_args(argc, argv, "oo|i", &rectObj, &strObj, &align RB_ARG_END); - if (!RB_TYPE_P(strObj, RUBY_T_STRING)) - strObj = rb_funcallv(strObj, rb_intern("to_s"), 0, 0); - - str = RSTRING_PTR(strObj); + str = objAsStringPtr(strObj); } else { @@ -281,10 +284,7 @@ RB_METHOD(bitmapDrawText) VALUE strObj; rb_get_args(argc, argv, "iiiio|i", &x, &y, &width, &height, &strObj, &align RB_ARG_END); - if (!RB_TYPE_P(strObj, RUBY_T_STRING)) - strObj = rb_funcallv(strObj, rb_intern("to_s"), 0, 0); - - str = RSTRING_PTR(strObj); + str = objAsStringPtr(strObj); } else { @@ -308,10 +308,7 @@ RB_METHOD(bitmapTextSize) VALUE strObj; rb_get_args(argc, argv, "o", &strObj RB_ARG_END); - if (!RB_TYPE_P(strObj, RUBY_T_STRING)) - strObj = rb_funcallv(strObj, rb_intern("to_s"), 0, 0); - - str = RSTRING_PTR(strObj); + str = objAsStringPtr(strObj); } else { -- 2.43.0 From 3b7b8657eaad33374ed78177a9bea714df4ee7d1 Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Tue, 2 Sep 2014 16:35:19 +0200 Subject: [PATCH 2/4] MRI: Fix exception message box script name and display script index Previously, when the script names in the backtrace were in the form 'SectionXXX'/'{XXXX}' (default RMXP behavior), this same name would be shown in the error message box, whereas RMXP always displays the actual script name (eg. 'Scene_Map') instead; only with useScriptNames=true was mkxp's behavior mostly correct. Fix this by keeping a backtrace format -> actual script name mapping and always using the script name in the message box. The script name and line would also be parsed wrongly if the name contained any colons, fix this by walking the exception string back to front instead. Also prepend the script index to the name when useScriptNames=true; this is invaluable when debugging projects where multiple scripts carry the same name. The format is 'XXX:Script_Name'. --- binding-mri/binding-mri.cpp | 93 ++++++++++++++++++++++++++----------- 1 file changed, 67 insertions(+), 26 deletions(-) diff --git a/binding-mri/binding-mri.cpp b/binding-mri/binding-mri.cpp index 12c9e86..d22b90e 100644 --- a/binding-mri/binding-mri.cpp +++ b/binding-mri/binding-mri.cpp @@ -27,6 +27,7 @@ #include "util.h" #include "debugwriter.h" #include "graphics.h" +#include "boost-hash.h" #include #include @@ -303,7 +304,15 @@ static void runCustomScript(const std::string &filename) VALUE kernelLoadDataInt(const char *filename); -static void runRMXPScripts() +struct BacktraceData +{ + /* Maps: Ruby visible filename, To: Actual script name */ + BoostHash scriptNames; +}; + +#define SCRIPT_SECTION_FMT (rgssVer >= 3 ? "{%04ld}" : "Section%03ld") + +static void runRMXPScripts(BacktraceData &btData) { const Config &conf = shState->rtData().config; const std::string &scriptPack = conf.game.scripts; @@ -394,17 +403,17 @@ static void runRMXPScripts() RSTRING_LEN(scriptDecoded)); VALUE fname; + const char *scriptName = RSTRING_PTR(rb_ary_entry(script, 1)); + char buf[512]; + int len; + if (conf.useScriptNames) - { - fname = rb_ary_entry(script, 1); - } + len = snprintf(buf, sizeof(buf), "%03ld:%s", i, scriptName); else - { - char buf[32]; - const char *format = rgssVer >= 3 ? "{%04ld}" : "Section%03ld"; - int len = snprintf(buf, sizeof(buf), format, i); - fname = newStringUTF8(buf, len); - } + len = snprintf(buf, sizeof(buf), SCRIPT_SECTION_FMT, i); + + fname = newStringUTF8(buf, len); + btData.scriptNames.insert(buf, scriptName); int state; evalString(string, fname, &state); @@ -413,9 +422,10 @@ static void runRMXPScripts() } } -static void showExc(VALUE exc) +static void showExc(VALUE exc, const BacktraceData &btData) { VALUE bt = rb_funcall2(exc, rb_intern("backtrace"), 0, NULL); + VALUE msg = rb_funcall2(exc, rb_intern("message"), 0, NULL); VALUE bt0 = rb_ary_entry(bt, 0); VALUE name = rb_class_path(rb_obj_class(exc)); @@ -426,19 +436,49 @@ static void showExc(VALUE exc) rb_str_catf(ds, "\n\tfrom %" PRIsVALUE, rb_ary_entry(bt, i)); Debug() << StringValueCStr(ds); - ID id_index = rb_intern("index"); - /* an "offset" argument is not needed for the first time */ - VALUE argv[2] = { rb_str_new_cstr(":") }; - long filelen = NUM2LONG(rb_funcall2(bt0, id_index, 1, argv)); - argv[1] = LONG2NUM(filelen + 1); - VALUE tmp = rb_funcall2(bt0, id_index, ARRAY_SIZE(argv), argv); - long linelen = NUM2LONG(tmp) - filelen - 1; - VALUE file = rb_str_subseq(bt0, 0, filelen); - VALUE line = rb_str_subseq(bt0, filelen + 1, linelen); - VALUE ms = rb_sprintf("Script '%" PRIsVALUE "' line %" PRIsVALUE - ": %" PRIsVALUE " occured.\n\n%" PRIsVALUE, - file, line, name, exc); - showMsg(StringValueCStr(ms)); + char *s = RSTRING_PTR(bt0); + + char line[16]; + std::string file(512, '\0'); + + char *p = s + strlen(s); + char *e; + + while (p != s) + if (*--p == ':') + break; + + e = p; + + while (p != s) + if (*--p == ':') + break; + + /* s p e + * SectionXXX:YY: in 'blabla' */ + + *e = '\0'; + strncpy(line, *p ? p+1 : p, sizeof(line)); + line[sizeof(line)-1] = '\0'; + *e = ':'; + e = p; + + /* s e + * SectionXXX:YY: in 'blabla' */ + + *e = '\0'; + strncpy(&file[0], s, file.size()); + *e = ':'; + + /* Shrink to fit */ + file.resize(strlen(file.c_str())); + file = btData.scriptNames.value(file, file); + + std::string ms(640, '\0'); + snprintf(&ms[0], ms.size(), "Script '%s' line %s: %s occured.\n\n%s", + file.c_str(), line, RSTRING_PTR(name), RSTRING_PTR(msg)); + + showMsg(ms); } static void mriBindingExecute() @@ -464,6 +504,7 @@ static void mriBindingExecute() RbData rbData; shState->setBindingData(&rbData); + BacktraceData btData; mriBindingInit(); @@ -471,11 +512,11 @@ static void mriBindingExecute() if (!customScript.empty()) runCustomScript(customScript); else - runRMXPScripts(); + runRMXPScripts(btData); VALUE exc = rb_errinfo(); if (!NIL_P(exc) && !rb_obj_is_kind_of(exc, rb_eSystemExit)) - showExc(exc); + showExc(exc, btData); ruby_cleanup(0); -- 2.43.0 From 7acbb06fbd720a7d8cba9f5102a0d2e04b4bbda8 Mon Sep 17 00:00:00 2001 From: cremno Date: Tue, 2 Sep 2014 19:45:50 +0200 Subject: [PATCH 3/4] add RGSS 3.0.1 etc classes equality comparison RGSS 3.0.1 finally fixed #==, #===, #eql? for Color, Tone, and Rect. Now instances of them can be compared to other kinds of objects. --- binding-mri/etc-binding.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/binding-mri/etc-binding.cpp b/binding-mri/etc-binding.cpp index 32ad494..731ccca 100644 --- a/binding-mri/etc-binding.cpp +++ b/binding-mri/etc-binding.cpp @@ -22,6 +22,7 @@ #include "etc.h" #include "binding-util.h" #include "serializable-binding.h" +#include "sharedstate.h" DEF_TYPE(Color); DEF_TYPE(Tone); @@ -68,6 +69,9 @@ ATTR_INT_RW(Rect, Height) VALUE otherObj; \ Klass *other; \ rb_get_args(argc, argv, "o", &otherObj RB_ARG_END); \ + if (rgssVer >= 3) \ + if (!rb_typeddata_is_kind_of(otherObj, &Klass##Type)) \ + return Qfalse; \ other = getPrivateDataCheck(otherObj, Klass##Type); \ return rb_bool_new(*p == *other); \ } -- 2.43.0 From fd4f7c66d1af89a6518676c90c824a4ef0e19608 Mon Sep 17 00:00:00 2001 From: cremno Date: Tue, 2 Sep 2014 19:48:47 +0200 Subject: [PATCH 4/4] bump RGSS_VERSION to 3.0.1 --- binding-mri/binding-mri.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/binding-mri/binding-mri.cpp b/binding-mri/binding-mri.cpp index 12c9e86..962b51e 100644 --- a/binding-mri/binding-mri.cpp +++ b/binding-mri/binding-mri.cpp @@ -114,7 +114,7 @@ static void mriBindingInit() _rb_define_module_function(rb_mKernel, "msgbox", mriPrint); _rb_define_module_function(rb_mKernel, "msgbox_p", mriP); - rb_define_global_const("RGSS_VERSION", rb_str_new_cstr("3.0.0")); + rb_define_global_const("RGSS_VERSION", rb_str_new_cstr("3.0.1")); } else { -- 2.43.0