summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog16
-rw-r--r--NEWS5
-rw-r--r--error.c25
-rw-r--r--include/ruby/intern.h1
-rw-r--r--load.c9
-rw-r--r--ruby.c2
-rw-r--r--test/ruby/test_require.rb8
7 files changed, 59 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index 742a5c4c62..b7c8a2c70a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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!
diff --git a/NEWS b/NEWS
index 8698195afc..be17902b0d 100644
--- a/NEWS
+++ b/NEWS
@@ -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
diff --git a/error.c b/error.c
index bea4d50909..e0c6a44b2f 100644
--- a/error.c
+++ b/error.c
@@ -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*));
diff --git a/load.c b/load.c
index cddd7255ac..67020a1ecd 100644
--- a/load.c
+++ b/load.c
@@ -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
diff --git a/ruby.c b/ruby.c
index 1ad68caeb1..16e66c8f9c 100644
--- a/ruby.c
+++ b/ruby.c
@@ -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"