diff options
-rw-r--r-- | ChangeLog | 16 | ||||
-rw-r--r-- | NEWS | 5 | ||||
-rw-r--r-- | error.c | 25 | ||||
-rw-r--r-- | include/ruby/intern.h | 1 | ||||
-rw-r--r-- | load.c | 9 | ||||
-rw-r--r-- | ruby.c | 2 | ||||
-rw-r--r-- | test/ruby/test_require.rb | 8 |
7 files changed, 59 insertions, 7 deletions
@@ -1,3 +1,19 @@ +Wed Mar 7 08:32:43 2012 Aaron Patterson <aaron@tenderlovemaking.com> + + * error.c (rb_loaderror_with_path): Adding the missing file as an + instance variable to the LoadError exception. + + * load.c: call rb_loaderror_with_path so that the missing path is + added to the exception. + + * ruby.c: call rb_loaderror rather than raising our own LoadError + exception. + + * include/ruby/intern.h: add declaration for rb_loaderror_with_path. + + * test/ruby/test_require.rb: add supporting test for LoadError#path + method. + Wed Mar 7 08:28:00 2012 Aaron Patterson <aaron@tenderlovemaking.com> * lib/xmlrpc/parser.rb: support i8 types. Thanks Stas Kelvich! @@ -28,6 +28,11 @@ with all sufficient information, see the ChangeLog file. * respond_to? against a protected method now returns false unless the second argument is true. + * LoadError + * added method: + * added LoadError#path method to return the file name that could not be + loaded. + * Signal * incompatible changes: * Signal.trap raises ArgumentError when :SEGV, :BUS, :ILL, :FPE, :VTALRM @@ -1691,7 +1691,10 @@ Init_Exception(void) rb_eScriptError = rb_define_class("ScriptError", rb_eException); rb_eSyntaxError = rb_define_class("SyntaxError", rb_eScriptError); + rb_eLoadError = rb_define_class("LoadError", rb_eScriptError); + rb_attr(rb_eLoadError, rb_intern("path"), 1, 0, Qfalse); + rb_eNotImpError = rb_define_class("NotImplementedError", rb_eScriptError); rb_eNameError = rb_define_class("NameError", rb_eStandardError); @@ -1742,11 +1745,29 @@ rb_loaderror(const char *fmt, ...) { va_list args; VALUE mesg; + VALUE err; + + va_start(args, fmt); + mesg = rb_enc_vsprintf(rb_locale_encoding(), fmt, args); + va_end(args); + err = rb_exc_new3(rb_eLoadError, mesg); + rb_ivar_set(err, rb_intern("@path"), Qnil); + rb_exc_raise(err); +} + +void +rb_loaderror_with_path(VALUE path, const char *fmt, ...) +{ + va_list args; + VALUE mesg; + VALUE err; va_start(args, fmt); mesg = rb_enc_vsprintf(rb_locale_encoding(), fmt, args); va_end(args); - rb_exc_raise(rb_exc_new3(rb_eLoadError, mesg)); + err = rb_exc_new3(rb_eLoadError, mesg); + rb_ivar_set(err, rb_intern("@path"), path); + rb_exc_raise(err); } void @@ -1889,7 +1910,7 @@ rb_sys_warning(const char *fmt, ...) void rb_load_fail(const char *path) { - rb_loaderror("%s -- %s", strerror(errno), path); + rb_loaderror_with_path(rb_str_new2(path), "%s -- %s", strerror(errno), path); } void diff --git a/include/ruby/intern.h b/include/ruby/intern.h index 6f632973f2..42f9e48c55 100644 --- a/include/ruby/intern.h +++ b/include/ruby/intern.h @@ -209,6 +209,7 @@ VALUE rb_exc_new(VALUE, const char*, long); VALUE rb_exc_new2(VALUE, const char*); VALUE rb_exc_new3(VALUE, VALUE); PRINTF_ARGS(NORETURN(void rb_loaderror(const char*, ...)), 1, 2); +PRINTF_ARGS(NORETURN(void rb_loaderror_with_path(VALUE path, const char*, ...)), 2, 3); PRINTF_ARGS(NORETURN(void rb_name_error(ID, const char*, ...)), 2, 3); PRINTF_ARGS(NORETURN(void rb_name_error_str(VALUE, const char*, ...)), 2, 3); NORETURN(void rb_invalid_str(const char*, const char*)); @@ -495,7 +495,7 @@ rb_f_require_relative(VALUE obj, VALUE fname) { VALUE base = rb_current_realfilepath(); if (NIL_P(base)) { - rb_raise(rb_eLoadError, "cannot infer basepath"); + rb_loaderror("cannot infer basepath"); } base = rb_file_dirname(base); return rb_require_safe(rb_file_absolute_path(fname, base), rb_safe_level()); @@ -588,12 +588,13 @@ search_required(VALUE fname, volatile VALUE *path, int safe_level) return type ? 's' : 'r'; } +void rb_loaderror_with_path(VALUE path, const char *fmt, ...); + static void load_failed(VALUE fname) { - VALUE mesg = rb_str_buf_new_cstr("cannot load such file -- "); - rb_str_append(mesg, fname); /* should be ASCII compatible */ - rb_exc_raise(rb_exc_new3(rb_eLoadError, mesg)); + rb_loaderror_with_path(fname, "cannot load such file -- %s", RSTRING_PTR(fname)); + RB_GC_GUARD(fname); } static VALUE @@ -1560,7 +1560,7 @@ load_file_internal(VALUE arg) } } } - rb_raise(rb_eLoadError, "no Ruby script found in input"); + rb_loaderror("no Ruby script found in input"); } c = rb_io_getbyte(f); diff --git a/test/ruby/test_require.rb b/test/ruby/test_require.rb index 379efec58a..e0e885dce6 100644 --- a/test/ruby/test_require.rb +++ b/test/ruby/test_require.rb @@ -5,6 +5,14 @@ require_relative 'envutil' require 'tmpdir' class TestRequire < Test::Unit::TestCase + def test_load_error_path + filename = "should_not_exist" + error = assert_raises(LoadError) do + require filename + end + assert_equal filename, error.path + end + def test_require_invalid_shared_object t = Tempfile.new(["test_ruby_test_require", ".so"]) t.puts "dummy" |