summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/mruby/class.h1
-rw-r--r--mrbgems/mruby-bin-debugger/bintest/print.rb10
-rw-r--r--mrbgems/mruby-complex/mrbgem.rake3
-rw-r--r--mrbgems/mruby-complex/mrblib/complex.rb10
-rw-r--r--mrbgems/mruby-io/README.md1
-rw-r--r--mrbgems/mruby-io/mrbgem.rake2
-rw-r--r--mrbgems/mruby-io/src/file.c5
-rw-r--r--mrbgems/mruby-io/src/file_test.c5
-rw-r--r--mrbgems/mruby-io/src/io.c13
-rw-r--r--mrbgems/mruby-io/test/mruby_io_test.c2
-rw-r--r--mrbgems/mruby-metaprog/src/metaprog.c33
-rw-r--r--mrbgems/mruby-pack/README.md1
-rw-r--r--mrbgems/mruby-pack/mrbgem.rake2
-rw-r--r--mrbgems/mruby-sleep/mrbgem.rake2
-rw-r--r--mrbgems/mruby-sleep/src/mrb_sleep.c1
-rw-r--r--mrbgems/mruby-socket/README.md1
-rw-r--r--mrbgems/mruby-socket/mrbgem.rake2
-rw-r--r--mrbgems/mruby-test/vformat.c320
-rw-r--r--src/backtrace.c85
-rw-r--r--src/class.c2
-rw-r--r--src/error.c69
-rw-r--r--src/print.c1
-rw-r--r--src/string.c1
-rw-r--r--test/t/exception.rb4
-rw-r--r--test/t/vformat.rb130
25 files changed, 274 insertions, 432 deletions
diff --git a/include/mruby/class.h b/include/mruby/class.h
index 7c925f3b3..c15633e83 100644
--- a/include/mruby/class.h
+++ b/include/mruby/class.h
@@ -90,6 +90,7 @@ mrb_value mrb_instance_new(mrb_state *mrb, mrb_value cv);
void mrb_class_name_class(mrb_state*, struct RClass*, struct RClass*, mrb_sym);
mrb_bool mrb_const_name_p(mrb_state*, const char*, mrb_int);
mrb_value mrb_class_find_path(mrb_state*, struct RClass*);
+mrb_value mrb_mod_to_s(mrb_state*, mrb_value);
void mrb_gc_mark_mt(mrb_state*, struct RClass*);
size_t mrb_gc_mark_mt_size(mrb_state*, struct RClass*);
void mrb_gc_free_mt(mrb_state*, struct RClass*);
diff --git a/mrbgems/mruby-bin-debugger/bintest/print.rb b/mrbgems/mruby-bin-debugger/bintest/print.rb
index 6675392b8..314c7041a 100644
--- a/mrbgems/mruby-bin-debugger/bintest/print.rb
+++ b/mrbgems/mruby-bin-debugger/bintest/print.rb
@@ -90,8 +90,8 @@ assert('mruby-bin-debugger(print) error') do
# test case
tc = []
- tc << {:cmd=>"p (1+2", :exp=>'$1 = SyntaxError'}
- tc << {:cmd=>"p bar", :exp=>'$2 = (eval):2: undefined method'}
+ tc << {:cmd=>"p (1+2", :exp=>'$1 = line 1: syntax error'}
+ tc << {:cmd=>"p bar", :exp=>'$2 = undefined method'}
BinTest_MrubyBinDebugger.test(src, tc)
end
@@ -588,7 +588,7 @@ SRC
tc << {:cmd=>'p foo=[foo,bar,baz]', :exp=>'$2 = ["foo", "bar", "baz"]'}
tc << {:cmd=>'p undefined=-1', :exp=>'$3 = -1'}
- tc << {:cmd=>'p "#{undefined}"', :exp=>'$4 = (eval):2: undefined method'}
+ tc << {:cmd=>'p "#{undefined}"', :exp=>'$4 = undefined method'}
BinTest_MrubyBinDebugger.test(src, tc)
end
@@ -626,7 +626,7 @@ SRC
tc << {:cmd=>'p [a,b]', :exp=>'$13 = [20, 10]'}
tc << {:cmd=>'p undefined=-1', :exp=>'$14 = -1'}
- tc << {:cmd=>'p "#{undefined}"', :exp=>'$15 = (eval):2: undefined method'}
+ tc << {:cmd=>'p "#{undefined}"', :exp=>'$15 = undefined method'}
BinTest_MrubyBinDebugger.test(src, tc)
end
@@ -694,7 +694,7 @@ SRC
tc << {:cmd=>'p [a,b]', :exp=>'$13 = [20, 10]'}
tc << {:cmd=>'p undefined=-1', :exp=>'$14 = -1'}
- tc << {:cmd=>'p "#{undefined}"', :exp=>'$15 = (eval):2: undefined method'}
+ tc << {:cmd=>'p "#{undefined}"', :exp=>'$15 = undefined method'}
BinTest_MrubyBinDebugger.test(src, tc)
end
diff --git a/mrbgems/mruby-complex/mrbgem.rake b/mrbgems/mruby-complex/mrbgem.rake
index 19612e74d..8f782ae18 100644
--- a/mrbgems/mruby-complex/mrbgem.rake
+++ b/mrbgems/mruby-complex/mrbgem.rake
@@ -3,8 +3,5 @@ MRuby::Gem::Specification.new('mruby-complex') do |spec|
spec.author = 'mruby developers'
spec.summary = 'Complex class'
- spec.add_dependency 'mruby-metaprog', core: 'mruby-metaprog'
- spec.add_dependency 'mruby-object-ext', core: 'mruby-object-ext'
- spec.add_dependency 'mruby-numeric-ext', core: 'mruby-numeric-ext'
spec.add_dependency 'mruby-math', core: 'mruby-math'
end
diff --git a/mrbgems/mruby-complex/mrblib/complex.rb b/mrbgems/mruby-complex/mrblib/complex.rb
index f32b84c8b..ea8530919 100644
--- a/mrbgems/mruby-complex/mrblib/complex.rb
+++ b/mrbgems/mruby-complex/mrblib/complex.rb
@@ -8,7 +8,7 @@ class Complex < Numeric
end
def to_s
- "#{real}#{'+' unless imaginary.negative?}#{imaginary}i"
+ "#{real}#{'+' unless imaginary < 0}#{imaginary}i"
end
def +@
@@ -56,7 +56,7 @@ class Complex < Numeric
if rhs.is_a? Complex
real == rhs.real && imaginary == rhs.imaginary
elsif rhs.is_a? Numeric
- imaginary.zero? && real == rhs
+ imaginary == 0 && real == rhs
end
end
@@ -106,14 +106,14 @@ class Complex < Numeric
[Fixnum, Float].each do |cls|
[:+, :-, :*, :/, :==].each do |op|
- cls.instance_exec do
+ cls.instance_eval do
original_operator_name = "__original_operator_#{op}_complex"
alias_method original_operator_name, op
define_method op do |rhs|
if rhs.is_a? Complex
- Complex(self).send(op, rhs)
+ Complex(self).__send__(op, rhs)
else
- send(original_operator_name, rhs)
+ __send__(original_operator_name, rhs)
end
end
end
diff --git a/mrbgems/mruby-io/README.md b/mrbgems/mruby-io/README.md
index ccf56f970..2c5b762d8 100644
--- a/mrbgems/mruby-io/README.md
+++ b/mrbgems/mruby-io/README.md
@@ -171,6 +171,7 @@ Add the line below to your `build_config.rb`:
## License
Copyright (c) 2013 Internet Initiative Japan Inc.
+Copyright (c) 2017 mruby developers
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
diff --git a/mrbgems/mruby-io/mrbgem.rake b/mrbgems/mruby-io/mrbgem.rake
index e4f0b7bb6..bd20f6d20 100644
--- a/mrbgems/mruby-io/mrbgem.rake
+++ b/mrbgems/mruby-io/mrbgem.rake
@@ -1,6 +1,6 @@
MRuby::Gem::Specification.new('mruby-io') do |spec|
spec.license = 'MIT'
- spec.authors = 'Internet Initiative Japan Inc.'
+ spec.authors = ['Internet Initiative Japan Inc.', 'mruby developers']
spec.summary = 'IO and File class'
spec.cc.include_paths << "#{build.root}/src"
diff --git a/mrbgems/mruby-io/src/file.c b/mrbgems/mruby-io/src/file.c
index f9ccb6148..673decc20 100644
--- a/mrbgems/mruby-io/src/file.c
+++ b/mrbgems/mruby-io/src/file.c
@@ -7,12 +7,7 @@
#include "mruby/data.h"
#include "mruby/string.h"
#include "mruby/ext/io.h"
-
-#if MRUBY_RELEASE_NO < 10000
-#include "error.h"
-#else
#include "mruby/error.h"
-#endif
#include <sys/types.h>
#include <sys/stat.h>
diff --git a/mrbgems/mruby-io/src/file_test.c b/mrbgems/mruby-io/src/file_test.c
index 445bafde9..aadd1ac1c 100644
--- a/mrbgems/mruby-io/src/file_test.c
+++ b/mrbgems/mruby-io/src/file_test.c
@@ -7,12 +7,7 @@
#include "mruby/data.h"
#include "mruby/string.h"
#include "mruby/ext/io.h"
-
-#if MRUBY_RELEASE_NO < 10000
-#include "error.h"
-#else
#include "mruby/error.h"
-#endif
#include <sys/types.h>
#include <sys/stat.h>
diff --git a/mrbgems/mruby-io/src/io.c b/mrbgems/mruby-io/src/io.c
index 5bc88e047..32128fa07 100644
--- a/mrbgems/mruby-io/src/io.c
+++ b/mrbgems/mruby-io/src/io.c
@@ -10,12 +10,7 @@
#include "mruby/string.h"
#include "mruby/variable.h"
#include "mruby/ext/io.h"
-
-#if MRUBY_RELEASE_NO < 10000
-#include "error.h"
-#else
#include "mruby/error.h"
-#endif
#include <sys/types.h>
#include <sys/stat.h>
@@ -66,14 +61,6 @@ static int mrb_io_modestr_to_flags(mrb_state *mrb, const char *modestr);
static int mrb_io_flags_to_modenum(mrb_state *mrb, int flags);
static void fptr_finalize(mrb_state *mrb, struct mrb_io *fptr, int quiet);
-#if MRUBY_RELEASE_NO < 10000
-static struct RClass *
-mrb_module_get(mrb_state *mrb, const char *name)
-{
- return mrb_class_get(mrb, name);
-}
-#endif
-
static struct mrb_io *
io_get_open_fptr(mrb_state *mrb, mrb_value self)
{
diff --git a/mrbgems/mruby-io/test/mruby_io_test.c b/mrbgems/mruby-io/test/mruby_io_test.c
index f5c55499b..1c31c5fe0 100644
--- a/mrbgems/mruby-io/test/mruby_io_test.c
+++ b/mrbgems/mruby-io/test/mruby_io_test.c
@@ -18,7 +18,7 @@ typedef int mode_t;
#define open _open
#define close _close
-#ifdef _MSC_VER
+#if defined(_MSC_VER) || defined(__MINGW32__)
#include <sys/stat.h>
static int
diff --git a/mrbgems/mruby-metaprog/src/metaprog.c b/mrbgems/mruby-metaprog/src/metaprog.c
index bca8ab34c..f00c4493b 100644
--- a/mrbgems/mruby-metaprog/src/metaprog.c
+++ b/mrbgems/mruby-metaprog/src/metaprog.c
@@ -172,7 +172,7 @@ mrb_local_variables(mrb_state *mrb, mrb_value self)
KHASH_DECLARE(st, mrb_sym, char, FALSE)
static void
-method_entry_loop(mrb_state *mrb, struct RClass* klass, khash_t(st)* set)
+method_entry_loop(mrb_state *mrb, struct RClass *klass, khash_t(st) *set, khash_t(st) *undef)
{
khint_t i;
@@ -181,20 +181,28 @@ method_entry_loop(mrb_state *mrb, struct RClass* klass, khash_t(st)* set)
for (i=0;i<kh_end(h);i++) {
if (kh_exist(h, i)) {
mrb_method_t m = kh_value(h, i);
- if (MRB_METHOD_UNDEF_P(m)) continue;
- kh_put(st, mrb, set, kh_key(h, i));
+ if (MRB_METHOD_UNDEF_P(m)) {
+ if (undef) {
+ kh_put(st, mrb, undef, kh_key(h, i));
+ }
+ }
+ else if (undef == NULL ||
+ kh_get(st, mrb, undef, kh_key(h, i)) == kh_end(undef)) {
+ kh_put(st, mrb, set, kh_key(h, i));
+ }
}
}
}
static mrb_value
-mrb_class_instance_method_list(mrb_state *mrb, mrb_bool recur, struct RClass* klass, int obj)
+mrb_class_instance_method_list(mrb_state *mrb, mrb_bool recur, struct RClass *klass, int obj)
{
khint_t i;
mrb_value ary;
mrb_bool prepended = FALSE;
- struct RClass* oldklass;
- khash_t(st)* set = kh_init(st, mrb);
+ struct RClass *oldklass;
+ khash_t(st) *set = kh_init(st, mrb);
+ khash_t(st) *undef = (recur ? kh_init(st, mrb) : NULL);
if (!recur && (klass->flags & MRB_FL_CLASS_IS_PREPENDED)) {
MRB_CLASS_ORIGIN(klass);
@@ -203,7 +211,7 @@ mrb_class_instance_method_list(mrb_state *mrb, mrb_bool recur, struct RClass* kl
oldklass = 0;
while (klass && (klass != oldklass)) {
- method_entry_loop(mrb, klass, set);
+ method_entry_loop(mrb, klass, set, undef);
if ((klass->tt == MRB_TT_ICLASS && !prepended) ||
(klass->tt == MRB_TT_SCLASS)) {
}
@@ -221,6 +229,7 @@ mrb_class_instance_method_list(mrb_state *mrb, mrb_bool recur, struct RClass* kl
}
}
kh_destroy(st, mrb, set);
+ if (undef) kh_destroy(st, mrb, undef);
return ary;
}
@@ -313,18 +322,19 @@ mrb_obj_singleton_methods(mrb_state *mrb, mrb_bool recur, mrb_value obj)
{
khint_t i;
mrb_value ary;
- struct RClass* klass;
- khash_t(st)* set = kh_init(st, mrb);
+ struct RClass *klass;
+ khash_t(st) *set = kh_init(st, mrb);
+ khash_t(st) *undef = (recur ? kh_init(st, mrb) : NULL);
klass = mrb_class(mrb, obj);
if (klass && (klass->tt == MRB_TT_SCLASS)) {
- method_entry_loop(mrb, klass, set);
+ method_entry_loop(mrb, klass, set, undef);
klass = klass->super;
}
if (recur) {
while (klass && ((klass->tt == MRB_TT_SCLASS) || (klass->tt == MRB_TT_ICLASS))) {
- method_entry_loop(mrb, klass, set);
+ method_entry_loop(mrb, klass, set, undef);
klass = klass->super;
}
}
@@ -336,6 +346,7 @@ mrb_obj_singleton_methods(mrb_state *mrb, mrb_bool recur, mrb_value obj)
}
}
kh_destroy(st, mrb, set);
+ if (undef) kh_destroy(st, mrb, undef);
return ary;
}
diff --git a/mrbgems/mruby-pack/README.md b/mrbgems/mruby-pack/README.md
index 95733e2d5..c8a653fba 100644
--- a/mrbgems/mruby-pack/README.md
+++ b/mrbgems/mruby-pack/README.md
@@ -49,6 +49,7 @@ There is no dependency on other mrbgems.
## License
Copyright (c) 2012 Internet Initiative Japan Inc.
+Copyright (c) 2017 mruby developers
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
diff --git a/mrbgems/mruby-pack/mrbgem.rake b/mrbgems/mruby-pack/mrbgem.rake
index 6e8375d1e..f1c0306b1 100644
--- a/mrbgems/mruby-pack/mrbgem.rake
+++ b/mrbgems/mruby-pack/mrbgem.rake
@@ -1,6 +1,6 @@
MRuby::Gem::Specification.new('mruby-pack') do |spec|
spec.license = 'MIT'
- spec.authors = 'Internet Initiative Japan Inc.'
+ spec.authors = ['Internet Initiative Japan Inc.', 'mruby developers']
spec.summary = 'Array#pack and String#unpack method'
spec.cc.include_paths << "#{build.root}/src"
diff --git a/mrbgems/mruby-sleep/mrbgem.rake b/mrbgems/mruby-sleep/mrbgem.rake
index 8827b3580..7a303b81c 100644
--- a/mrbgems/mruby-sleep/mrbgem.rake
+++ b/mrbgems/mruby-sleep/mrbgem.rake
@@ -1,5 +1,5 @@
MRuby::Gem::Specification.new('mruby-sleep') do |spec|
spec.license = 'MIT'
- spec.authors = 'MATSUMOTO Ryosuke'
+ spec.authors = ['MATSUMOTO Ryosuke', 'mruby developers']
spec.version = '0.0.1'
end
diff --git a/mrbgems/mruby-sleep/src/mrb_sleep.c b/mrbgems/mruby-sleep/src/mrb_sleep.c
index 3f8ef90cf..ac9b07e85 100644
--- a/mrbgems/mruby-sleep/src/mrb_sleep.c
+++ b/mrbgems/mruby-sleep/src/mrb_sleep.c
@@ -2,6 +2,7 @@
** mrb_sleep - sleep methods for mruby
**
** Copyright (c) mod_mruby developers 2012-
+** Copyright (c) mruby developers 2018
**
** Permission is hereby granted, free of charge, to any person obtaining
** a copy of this software and associated documentation files (the
diff --git a/mrbgems/mruby-socket/README.md b/mrbgems/mruby-socket/README.md
index ceb50c651..947a24e9e 100644
--- a/mrbgems/mruby-socket/README.md
+++ b/mrbgems/mruby-socket/README.md
@@ -35,6 +35,7 @@ Date: Tue, 21 May 2013 04:31:30 GMT
## License
Copyright (c) 2013 Internet Initiative Japan Inc.
+Copyright (c) 2017 mruby developers
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
diff --git a/mrbgems/mruby-socket/mrbgem.rake b/mrbgems/mruby-socket/mrbgem.rake
index b0894e095..24d6f953d 100644
--- a/mrbgems/mruby-socket/mrbgem.rake
+++ b/mrbgems/mruby-socket/mrbgem.rake
@@ -1,6 +1,6 @@
MRuby::Gem::Specification.new('mruby-socket') do |spec|
spec.license = 'MIT'
- spec.authors = 'Internet Initiative Japan'
+ spec.authors = ['Internet Initiative Japan', 'mruby developers']
spec.summary = 'standard socket class'
spec.cc.include_paths << "#{build.root}/src"
diff --git a/mrbgems/mruby-test/vformat.c b/mrbgems/mruby-test/vformat.c
index 6984aaeb1..7775e1fd2 100644
--- a/mrbgems/mruby-test/vformat.c
+++ b/mrbgems/mruby-test/vformat.c
@@ -4,197 +4,177 @@
#include <mruby/data.h>
#include <mruby/string.h>
-#ifdef MRB_WITHOUT_FLOAT
-typedef mrb_int mrb_float;
-#define mrb_float(o) mrb_fixnum(o)
+/* no argument */
+static mrb_value
+vf_s_format_0(mrb_state *mrb, mrb_value klass)
+{
+ mrb_value fmt_str;
+ const char *fmt;
+
+ mrb_get_args(mrb, "S", &fmt_str);
+ fmt = RSTRING_CSTR(mrb, fmt_str);
+
+ return mrb_format(mrb, fmt);
+}
+
+/* c char */
+static mrb_value
+vf_s_format_c(mrb_state *mrb, mrb_value klass)
+{
+ mrb_value fmt_str, arg_str;
+ const char *fmt;
+ char c;
+
+ mrb_get_args(mrb, "SS", &fmt_str, &arg_str);
+ fmt = RSTRING_CSTR(mrb, fmt_str);
+ c = RSTRING_CSTR(mrb, arg_str)[0];
+
+ return mrb_format(mrb, fmt, c);
+}
+
+/* d int */
+static mrb_value
+vf_s_format_d(mrb_state *mrb, mrb_value klass)
+{
+ mrb_value fmt_str, arg_int;
+ const char *fmt;
+ int d;
+
+ mrb_get_args(mrb, "Si", &fmt_str, &arg_int);
+ fmt = RSTRING_CSTR(mrb, fmt_str);
+ d = mrb_fixnum(arg_int);
+
+ return mrb_format(mrb, fmt, d);
+}
+
+#ifndef MRB_WITHOUT_FLOAT
+/* f float */
+static mrb_value
+vf_s_format_f(mrb_state *mrb, mrb_value klass)
+{
+ mrb_value fmt_str, arg_flt;
+ const char *fmt;
+ mrb_float f;
+
+ mrb_get_args(mrb, "Sf", &fmt_str, &arg_flt);
+ fmt = RSTRING_CSTR(mrb, fmt_str);
+ f = mrb_float(arg_flt);
+
+ return mrb_format(mrb, fmt, f);
+}
#endif
-#define NATIVE_TYPES \
- char c; \
- int d; \
- mrb_float f; \
- mrb_int i; \
-/* size_t l; */\
- mrb_sym n; \
- char *s; \
- struct RClass *C
-
-#define NATIVE_DEFINE_TYPE_FUNC(t) \
- static mrb_value \
- native_s_##t(mrb_state *mrb, mrb_value klass) \
- { \
- mrb_value obj, type = mrb_fixnum_value(ARG_##t); \
- mrb_get_args(mrb, "o", &obj); \
- return mrb_funcall(mrb, klass, "new", 2, type, obj); \
- }
-
-#define NATIVE_DEFINE_TYPE_METHOD(t) \
- mrb_define_class_method(mrb, n, #t, native_s_##t, MRB_ARGS_REQ(1))
-
-typedef enum {
- ARG_c,
- ARG_d,
- ARG_f,
- ARG_i,
-/* ARG_l,*/
- ARG_n,
- ARG_s,
- ARG_C,
- ARG_v,
-} VFArgumentType;
-
-typedef struct {
- VFArgumentType type;
- union { NATIVE_TYPES; };
-} VFNative;
-
-typedef struct {
- VFArgumentType type;
- union {
- NATIVE_TYPES;
- mrb_value v;
- };
-} VFArgument;
-
-static void
-native_free(mrb_state *mrb, void *data)
+/* i fixnum */
+static mrb_value
+vf_s_format_i(mrb_state *mrb, mrb_value klass)
{
- VFNative *native = (VFNative*)data;
- if (native->type == ARG_s) mrb_free(mrb, native->s);
- mrb_free(mrb, native);
+ mrb_value fmt_str, arg_int;
+ const char *fmt;
+ mrb_int i;
+
+ mrb_get_args(mrb, "Si", &fmt_str, &arg_int);
+ fmt = RSTRING_CSTR(mrb, fmt_str);
+ i = mrb_fixnum(arg_int);
+
+ return mrb_format(mrb, fmt, i);
}
-static const struct mrb_data_type native_data_type = {
- "TestVFormat::Native", native_free
-};
+/* l char*, size_t */
+static mrb_value
+vf_s_format_l(mrb_state *mrb, mrb_value klass)
+{
+ mrb_value fmt_str, arg_str, arg_int;
+ const char *fmt;
+ const char *s;
+ size_t len;
+
+ mrb_get_args(mrb, "SSi", &fmt_str, &arg_str, &arg_int);
+ fmt = RSTRING_CSTR(mrb, fmt_str);
+ s = RSTRING_PTR(arg_str);
+ len = (size_t)mrb_fixnum(arg_int);
+ if (len > (size_t)RSTRING_LEN(arg_str)) len = (size_t)RSTRING_LEN(arg_str);
+
+ return mrb_format(mrb, fmt, s, len);
+}
+/* n symbol */
static mrb_value
-native_initialize(mrb_state *mrb, mrb_value self)
+vf_s_format_n(mrb_state *mrb, mrb_value klass)
{
- VFNative data, *datap;
- mrb_int type;
- mrb_value obj;
-
- mrb_get_args(mrb, "io", &type, &obj);
- data.type = (VFArgumentType)type;
- switch (data.type) {
- case ARG_c: data.c = RSTRING_PTR(obj)[0]; break;
- case ARG_d: data.d = (int)mrb_fixnum(obj); break;
- case ARG_f: data.f = mrb_float(obj); break;
- case ARG_i: data.i = mrb_fixnum(obj); break;
-/* case ARG_l: data.l = (size_t)mrb_fixnum(obj); break;*/
- case ARG_n: data.n = mrb_symbol(obj); break;
- case ARG_s: data.s = (char*)mrb_malloc(mrb, RSTRING_LEN(obj) + 1);
- memcpy(data.s, RSTRING_PTR(obj), RSTRING_LEN(obj));
- data.s[RSTRING_LEN(obj)] = '\0'; break;
- case ARG_C: data.C = mrb_class_ptr(obj); break;
- default: mrb_raise(mrb, E_ARGUMENT_ERROR, "unknown type");
- }
- datap = (VFNative*)mrb_malloc(mrb, sizeof(VFNative));
- *datap = data;
- mrb_data_init(self, datap, &native_data_type);
- return self;
+ mrb_value fmt_str, arg_sym;
+ const char *fmt;
+ mrb_sym n;
+
+ mrb_get_args(mrb, "Sn", &fmt_str, &arg_sym);
+ fmt = RSTRING_CSTR(mrb, fmt_str);
+ n = mrb_symbol(arg_sym);
+
+ return mrb_format(mrb, fmt, n);
}
-NATIVE_DEFINE_TYPE_FUNC(c)
-NATIVE_DEFINE_TYPE_FUNC(d)
-NATIVE_DEFINE_TYPE_FUNC(f)
-NATIVE_DEFINE_TYPE_FUNC(i)
-/*NATIVE_DEFINE_TYPE_FUNC(l)*/
-NATIVE_DEFINE_TYPE_FUNC(n)
-NATIVE_DEFINE_TYPE_FUNC(s)
-NATIVE_DEFINE_TYPE_FUNC(C)
-
-static VFArgument*
-arg_from_obj(mrb_state *mrb, mrb_value obj, struct RClass *native_class,
- VFArgument *vf_arg)
+/* s char* */
+static mrb_value
+vf_s_format_s(mrb_state *mrb, mrb_value klass)
{
- if (mrb_obj_is_instance_of(mrb, obj, native_class)) {
- const VFNative *native = (VFNative*)DATA_PTR(obj);
- *(VFNative*)vf_arg = *native;
- }
- else {
- vf_arg->v = obj;
- vf_arg->type = ARG_v;
- }
- return vf_arg;
+ mrb_value fmt_str, arg_str;
+ const char *fmt;
+ const char *s;
+
+ mrb_get_args(mrb, "SS", &fmt_str, &arg_str);
+ fmt = RSTRING_CSTR(mrb, fmt_str);
+ s = RSTRING_CSTR(mrb, arg_str);
+
+ return mrb_format(mrb, fmt, s);
}
-#define VF_FORMAT_INIT(klass) \
- struct RClass *vf_native_class = \
- mrb_class_get_under(mrb, mrb_class_ptr(klass), "Native"); \
- VFArgument vf_args[2];
-
-#define VF_ARG(args, idx) \
- arg_from_obj(mrb, args[idx], vf_native_class, &vf_args[idx])
-
-#define VF_FORMAT0(fmt) mrb_format(mrb, fmt);
-#define VF_FORMAT1(fmt, args) \
- (VF_ARG(args, 0), VF_FORMAT_TYPED(fmt, 1, vf_args, NULL))
-#define VF_FORMAT2(fmt, args) ( \
- VF_ARG(args, 0), VF_ARG(args, 1), \
- VF_FORMAT2_COND_EXPR(fmt, vf_args, vf_args+1, c) : \
- VF_FORMAT2_COND_EXPR(fmt, vf_args, vf_args+1, d) : \
- VF_FORMAT2_COND_EXPR(fmt, vf_args, vf_args+1, f) : \
- VF_FORMAT2_COND_EXPR(fmt, vf_args, vf_args+1, i) : \
-/* VF_FORMAT2_COND_EXPR(fmt, vf_args, vf_args+1, l) : */\
- VF_FORMAT2_COND_EXPR(fmt, vf_args, vf_args+1, n) : \
- VF_FORMAT2_COND_EXPR(fmt, vf_args, vf_args+1, s) : \
- VF_FORMAT2_COND_EXPR(fmt, vf_args, vf_args+1, C) : \
- VF_FORMAT2_COND_EXPR(fmt, vf_args, vf_args+1, v) : \
- mrb_nil_value() /* not reached */ \
-)
-#define VF_FORMAT2_COND_EXPR(fmt, a1, a2, t) \
- a1->type == ARG_##t ? VF_FORMAT_TYPED(fmt, 2, a2, (a1)->t)
-#define VF_FORMAT_TYPED(fmt, n_arg, type_a, v1) \
- VF_FORMAT_TYPED_COND_EXPR(fmt, n_arg, type_a, v1, c) : \
- VF_FORMAT_TYPED_COND_EXPR(fmt, n_arg, type_a, v1, d) : \
- VF_FORMAT_TYPED_COND_EXPR(fmt, n_arg, type_a, v1, f) : \
- VF_FORMAT_TYPED_COND_EXPR(fmt, n_arg, type_a, v1, i) : \
-/* VF_FORMAT_TYPED_COND_EXPR(fmt, n_arg, type_a, v1, l) : */\
- VF_FORMAT_TYPED_COND_EXPR(fmt, n_arg, type_a, v1, n) : \
- VF_FORMAT_TYPED_COND_EXPR(fmt, n_arg, type_a, v1, s) : \
- VF_FORMAT_TYPED_COND_EXPR(fmt, n_arg, type_a, v1, C) : \
- VF_FORMAT_TYPED_COND_EXPR(fmt, n_arg, type_a, v1, v) : \
- mrb_nil_value() /* not reached */
-#define VF_FORMAT_TYPED_COND_EXPR(fmt, n_arg, type_a, v1, t) \
- (type_a)->type == ARG_##t ? n_arg == 1 ? \
- mrb_format(mrb, fmt, (type_a)->t) : mrb_format(mrb, fmt, v1, (type_a)->t)
+/* C RClass */
+static mrb_value
+vf_s_format_C(mrb_state *mrb, mrb_value klass)
+{
+ mrb_value fmt_str, arg_cls;
+ const char *fmt;
+ struct RClass *c;
+
+ mrb_get_args(mrb, "SC", &fmt_str, &arg_cls);
+ fmt = RSTRING_CSTR(mrb, fmt_str);
+ c = mrb_class_ptr(arg_cls);
+ return mrb_format(mrb, fmt, c);
+}
+
+/* v value */
static mrb_value
-vf_s_format(mrb_state *mrb, mrb_value klass)
+vf_s_format_v(mrb_state *mrb, mrb_value klass)
{
- mrb_value fmt_str, args[2];
- mrb_int argc = mrb_get_args(mrb, "S|oo", &fmt_str, args, args+1);
- const char *fmt = RSTRING_CSTR(mrb, fmt_str);
-
- VF_FORMAT_INIT(klass);
-
- switch (argc) {
- case 1: return VF_FORMAT0(fmt);
- case 2: return VF_FORMAT1(fmt, args);
- case 3: return VF_FORMAT2(fmt, args);
- default: return mrb_nil_value(); /* not reached */
- }
+ mrb_value fmt_str, arg_v;
+ const char *fmt;
+
+ mrb_get_args(mrb, "So", &fmt_str, &arg_v);
+ fmt = RSTRING_CSTR(mrb, fmt_str);
+
+ return mrb_format(mrb, fmt, arg_v);
}
void
mrb_init_test_vformat(mrb_state *mrb)
{
- struct RClass *vf, *n;
+ struct RClass *vf;
vf = mrb_define_module(mrb, "TestVFormat");
- mrb_define_class_method(mrb, vf, "format", vf_s_format, MRB_ARGS_ARG(1,2));
-
- n = mrb_define_class_under(mrb, vf, "Native", mrb->object_class);
- MRB_SET_INSTANCE_TT(n, MRB_TT_DATA);
- NATIVE_DEFINE_TYPE_METHOD(c);
- NATIVE_DEFINE_TYPE_METHOD(d);
- NATIVE_DEFINE_TYPE_METHOD(f);
- NATIVE_DEFINE_TYPE_METHOD(i);
-/* NATIVE_DEFINE_TYPE_METHOD(l);*/
- NATIVE_DEFINE_TYPE_METHOD(n);
- NATIVE_DEFINE_TYPE_METHOD(s);
- NATIVE_DEFINE_TYPE_METHOD(C);
- mrb_define_method(mrb, n, "initialize", native_initialize, MRB_ARGS_REQ(2));
+ mrb_define_class_method(mrb, vf, "z", vf_s_format_0, MRB_ARGS_REQ(1));
+
+#define VF_DEFINE_FORMAT_METHOD(t) VF_DEFINE_FORMAT_METHOD_n(t,2)
+#define VF_DEFINE_FORMAT_METHOD_n(t,n) mrb_define_class_method(mrb, vf, #t, vf_s_format_##t, MRB_ARGS_REQ(n));
+
+ VF_DEFINE_FORMAT_METHOD(c);
+ VF_DEFINE_FORMAT_METHOD(d);
+#ifndef MRB_WITHOUT_FLOAT
+ VF_DEFINE_FORMAT_METHOD(f);
+#endif
+ VF_DEFINE_FORMAT_METHOD(i);
+ VF_DEFINE_FORMAT_METHOD_n(l,3);
+ VF_DEFINE_FORMAT_METHOD(n);
+ VF_DEFINE_FORMAT_METHOD(s);
+ VF_DEFINE_FORMAT_METHOD(C);
+ VF_DEFINE_FORMAT_METHOD(v);
}
diff --git a/src/backtrace.c b/src/backtrace.c
index 803c5e285..186009523 100644
--- a/src/backtrace.c
+++ b/src/backtrace.c
@@ -25,6 +25,9 @@ typedef void (*each_backtrace_func)(mrb_state*, const struct backtrace_location*
static const mrb_data_type bt_type = { "Backtrace", mrb_free };
+mrb_value mrb_exc_inspect(mrb_state *mrb, mrb_value exc);
+mrb_value mrb_unpack_backtrace(mrb_state *mrb, mrb_value backtrace);
+
static void
each_backtrace(mrb_state *mrb, ptrdiff_t ciidx, const mrb_code *pc0, each_backtrace_func func, void *data)
{
@@ -74,66 +77,27 @@ each_backtrace(mrb_state *mrb, ptrdiff_t ciidx, const mrb_code *pc0, each_backtr
#ifndef MRB_DISABLE_STDIO
static void
-print_backtrace(mrb_state *mrb, mrb_value backtrace)
+print_backtrace(mrb_state *mrb, struct RObject *exc, mrb_value backtrace)
{
int i;
- mrb_int n;
+ mrb_int n = RARRAY_LEN(backtrace);
+ mrb_value *loc, mesg;
FILE *stream = stderr;
- n = RARRAY_LEN(backtrace) - 1;
- if (n == 0) return;
-
- fprintf(stream, "trace (most recent call last):\n");
- for (i=0; i<n; i++) {
- mrb_value entry = RARRAY_PTR(backtrace)[n-i-1];
-
- if (mrb_string_p(entry)) {
- fprintf(stream, "\t[%d] %.*s\n", i, (int)RSTRING_LEN(entry), RSTRING_PTR(entry));
+ if (n != 0) {
+ fprintf(stream, "trace (most recent call last):\n");
+ for (i=n-1,loc=&RARRAY_PTR(backtrace)[i]; i>0; i--,loc--) {
+ if (mrb_string_p(*loc)) {
+ fprintf(stream, "\t[%d] %.*s\n",
+ i, (int)RSTRING_LEN(*loc), RSTRING_PTR(*loc));
+ }
}
- }
-}
-
-static int
-packed_bt_len(const struct backtrace_location *bt, int n)
-{
- int len = 0;
- int i;
-
- for (i=0; i<n; i++) {
- if (!bt[i].filename && !bt[i].lineno && !bt[i].method_id)
- continue;
- len++;
- }
- return len;
-}
-
-static void
-print_packed_backtrace(mrb_state *mrb, mrb_value packed)
-{
- FILE *stream = stderr;
- const struct backtrace_location *bt;
- int n, i;
- int ai = mrb_gc_arena_save(mrb);
-
- bt = (struct backtrace_location*)mrb_data_check_get_ptr(mrb, packed, &bt_type);
- if (bt == NULL) return;
- n = (mrb_int)RDATA(packed)->flags;
-
- if (packed_bt_len(bt, n) == 0) return;
- fprintf(stream, "trace (most recent call last):\n");
- for (i = 0; i<n; i++) {
- const struct backtrace_location *entry = &bt[n-i-1];
- if (entry->filename == NULL) continue;
- fprintf(stream, "\t[%d] %s:%d", i, entry->filename, entry->lineno);
- if (entry->method_id != 0) {
- const char *method_name;
-
- method_name = mrb_sym_name(mrb, entry->method_id);
- fprintf(stream, ":in %s", method_name);
- mrb_gc_arena_restore(mrb, ai);
+ if (mrb_string_p(*loc)) {
+ fprintf(stream, "%.*s: ", (int)RSTRING_LEN(*loc), RSTRING_PTR(*loc));
}
- fprintf(stream, "\n");
}
+ mesg = mrb_exc_inspect(mrb, mrb_obj_value(exc));
+ fprintf(stream, "%.*s\n", (int)RSTRING_LEN(mesg), RSTRING_PTR(mesg));
}
/* mrb_print_backtrace
@@ -152,12 +116,8 @@ mrb_print_backtrace(mrb_state *mrb)
backtrace = mrb_obj_iv_get(mrb, mrb->exc, mrb_intern_lit(mrb, "backtrace"));
if (mrb_nil_p(backtrace)) return;
- if (mrb_array_p(backtrace)) {
- print_backtrace(mrb, backtrace);
- }
- else {
- print_packed_backtrace(mrb, backtrace);
- }
+ if (!mrb_array_p(backtrace)) backtrace = mrb_unpack_backtrace(mrb, backtrace);
+ print_backtrace(mrb, mrb->exc, backtrace);
}
#else
@@ -175,7 +135,6 @@ count_backtrace_i(mrb_state *mrb,
{
int *lenp = (int*)data;
- if (loc->filename == NULL) return;
(*lenp)++;
}
@@ -187,7 +146,6 @@ pack_backtrace_i(mrb_state *mrb,
struct backtrace_location **pptr = (struct backtrace_location**)data;
struct backtrace_location *ptr = *pptr;
- if (loc->filename == NULL) return;
*ptr = *loc;
*pptr = ptr+1;
}
@@ -205,7 +163,7 @@ packed_backtrace(mrb_state *mrb)
size = len * sizeof(struct backtrace_location);
ptr = mrb_malloc(mrb, size);
backtrace = mrb_data_object_alloc(mrb, NULL, ptr, &bt_type);
- backtrace->flags = (unsigned int)len;
+ backtrace->flags = (uint32_t)len;
each_backtrace(mrb, ciidx, mrb->c->ci->pc, pack_backtrace_i, &ptr);
return mrb_obj_value(backtrace);
}
@@ -245,8 +203,7 @@ mrb_unpack_backtrace(mrb_state *mrb, mrb_value backtrace)
const struct backtrace_location *entry = &bt[i];
mrb_value btline;
- if (entry->filename == NULL) continue;
- btline = mrb_format(mrb, "%s:%d", entry->filename, entry->lineno);
+ btline = mrb_format(mrb, "%s:%d", entry->filename, (int)entry->lineno);
if (entry->method_id != 0) {
mrb_str_cat_lit(mrb, btline, ":in ");
mrb_str_cat_cstr(mrb, btline, mrb_sym_name(mrb, entry->method_id));
diff --git a/src/class.c b/src/class.c
index e0196fe0a..0da572b0e 100644
--- a/src/class.c
+++ b/src/class.c
@@ -2323,7 +2323,9 @@ mrb_init_class(mrb_state *mrb)
mrb_define_method(mrb, mod, "dup", mrb_mod_dup, MRB_ARGS_NONE());
mrb_undef_method(mrb, cls, "append_features");
+ mrb_undef_method(mrb, cls, "prepend_features");
mrb_undef_method(mrb, cls, "extend_object");
+ mrb_undef_method(mrb, cls, "module_function");
mrb->top_self = (struct RObject*)mrb_obj_alloc(mrb, MRB_TT_OBJECT, mrb->object_class);
mrb_define_singleton_method(mrb, mrb->top_self, "inspect", inspect_main, MRB_ARGS_NONE());
diff --git a/src/error.c b/src/error.c
index 43b09ec66..126cd23fb 100644
--- a/src/error.c
+++ b/src/error.c
@@ -13,7 +13,6 @@
#include <mruby/proc.h>
#include <mruby/string.h>
#include <mruby/variable.h>
-#include <mruby/debug.h>
#include <mruby/error.h>
#include <mruby/class.h>
#include <mruby/throw.h>
@@ -88,7 +87,7 @@ exc_exception(mrb_state *mrb, mrb_value self)
* no message is set).
*/
-static mrb_value
+mrb_value
exc_to_s(mrb_state *mrb, mrb_value exc)
{
mrb_value mesg = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "mesg"));
@@ -128,37 +127,13 @@ exc_message(mrb_state *mrb, mrb_value exc)
* returns message and class name.
*/
-static mrb_value
-exc_inspect(mrb_state *mrb, mrb_value exc)
+mrb_value
+mrb_exc_inspect(mrb_state *mrb, mrb_value exc)
{
- mrb_value str, mesg, file, line;
- mrb_bool append_mesg;
- const char *cname;
-
- mesg = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "mesg"));
- file = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "file"));
- line = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "line"));
-
- append_mesg = !mrb_nil_p(mesg);
- if (append_mesg) {
- mesg = mrb_obj_as_string(mrb, mesg);
- append_mesg = RSTRING_LEN(mesg) > 0;
- }
-
- cname = mrb_obj_classname(mrb, exc);
- str = mrb_str_new_cstr(mrb, cname);
- if (mrb_string_p(file) && mrb_fixnum_p(line)) {
- if (append_mesg) {
- str = mrb_format(mrb, "%v:%v: %v (%v)", file, line, mesg, str);
- }
- else {
- str = mrb_format(mrb, "%v:%v: %v", file, line, str);
- }
- }
- else if (append_mesg) {
- str = mrb_format(mrb, "%v: %v", str, mesg);
- }
- return str;
+ mrb_value mesg = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "mesg"));
+ mrb_value cname = mrb_mod_to_s(mrb, mrb_obj_value(mrb_obj_class(mrb, exc)));
+ mesg = mrb_obj_as_string(mrb, mesg);
+ return RSTRING_LEN(mesg) == 0 ? cname : mrb_format(mrb, "%v (%v)", mesg, cname);
}
void mrb_keep_backtrace(mrb_state *mrb, mrb_value exc);
@@ -192,33 +167,6 @@ exc_set_backtrace(mrb_state *mrb, mrb_value exc)
return backtrace;
}
-static void
-exc_debug_info(mrb_state *mrb, struct RObject *exc)
-{
- mrb_callinfo *ci = mrb->c->ci;
- const mrb_code *pc = ci->pc;
-
- if (mrb_obj_iv_defined(mrb, exc, mrb_intern_lit(mrb, "file"))) return;
- while (ci >= mrb->c->cibase) {
- const mrb_code *err = ci->err;
-
- if (!err && pc) err = pc - 1;
- if (err && ci->proc && !MRB_PROC_CFUNC_P(ci->proc)) {
- mrb_irep *irep = ci->proc->body.irep;
-
- int32_t const line = mrb_debug_get_line(mrb, irep, err - irep->iseq);
- char const* file = mrb_debug_get_filename(mrb, irep, err - irep->iseq);
- if (line != -1 && file) {
- mrb_obj_iv_set(mrb, exc, mrb_intern_lit(mrb, "file"), mrb_str_new_cstr(mrb, file));
- mrb_obj_iv_set(mrb, exc, mrb_intern_lit(mrb, "line"), mrb_fixnum_value(line));
- return;
- }
- }
- pc = ci->pc;
- ci--;
- }
-}
-
void
mrb_exc_set(mrb_state *mrb, mrb_value exc)
{
@@ -232,7 +180,6 @@ mrb_exc_set(mrb_state *mrb, mrb_value exc)
mrb->gc.arena_idx--;
}
if (!mrb->gc.out_of_memory && !mrb_frozen_p(mrb->exc)) {
- exc_debug_info(mrb, mrb->exc);
mrb_keep_backtrace(mrb, exc);
}
}
@@ -598,7 +545,7 @@ mrb_init_exception(mrb_state *mrb)
mrb_define_method(mrb, exception, "initialize", exc_initialize, MRB_ARGS_OPT(1));
mrb_define_method(mrb, exception, "to_s", exc_to_s, MRB_ARGS_NONE());
mrb_define_method(mrb, exception, "message", exc_message, MRB_ARGS_NONE());
- mrb_define_method(mrb, exception, "inspect", exc_inspect, MRB_ARGS_NONE());
+ mrb_define_method(mrb, exception, "inspect", mrb_exc_inspect, MRB_ARGS_NONE());
mrb_define_method(mrb, exception, "backtrace", mrb_exc_backtrace, MRB_ARGS_NONE());
mrb_define_method(mrb, exception, "set_backtrace", exc_set_backtrace, MRB_ARGS_REQ(1));
diff --git a/src/print.c b/src/print.c
index 03b5eadfa..7d2d16086 100644
--- a/src/print.c
+++ b/src/print.c
@@ -31,7 +31,6 @@ MRB_API void
mrb_print_error(mrb_state *mrb)
{
mrb_print_backtrace(mrb);
- printstr(mrb_funcall(mrb, mrb_obj_value(mrb->exc), "inspect", 0), stderr);
}
MRB_API void
diff --git a/src/string.c b/src/string.c
index 5a0a6a233..b3f07dfb0 100644
--- a/src/string.c
+++ b/src/string.c
@@ -1095,7 +1095,6 @@ mrb_str_equal_m(mrb_state *mrb, mrb_value str1)
return mrb_bool_value(mrb_str_equal(mrb, str1, str2));
}
/* ---------------------------------- */
-mrb_value mrb_mod_to_s(mrb_state *mrb, mrb_value klass);
MRB_API mrb_value
mrb_str_to_str(mrb_state *mrb, mrb_value str)
diff --git a/test/t/exception.rb b/test/t/exception.rb
index bdf277c1e..a6f69eef6 100644
--- a/test/t/exception.rb
+++ b/test/t/exception.rb
@@ -352,8 +352,10 @@ assert('Exception 19') do
assert_equal [true, true], Class4Exception19.new.a
end
-assert('Exception#inspect without message') do
+assert('Exception#inspect') do
assert_equal "Exception", Exception.new.inspect
+ assert_equal "Exception", Exception.new("").inspect
+ assert_equal "error! (Exception)", Exception.new("error!").inspect
end
assert('Exception#backtrace') do
diff --git a/test/t/vformat.rb b/test/t/vformat.rb
index 679f30407..df6950ee6 100644
--- a/test/t/vformat.rb
+++ b/test/t/vformat.rb
@@ -1,25 +1,4 @@
-def assert_format(exp, args)
- assert_equal(exp, TestVFormat.format(*args))
-end
-
-def assert_format_pattern(exp_pattern, args)
- assert_match(exp_pattern, TestVFormat.format(*args))
-end
-
-# Pass if ArgumentError is raised or return value is +exp+.
-def assert_implementation_dependent(exp, args)
- begin
- ret = TestVFormat.format(*args)
- rescue ArgumentError
- return pass
- end
- if ret == exp
- pass
- else
- flunk "", "Expected ArgumentError is raised or #{ret.inspect} to be #{exp}."
- end
-end
-
+# coding: utf-8-emacs
def sclass(v)
class << v
self
@@ -27,66 +6,53 @@ def sclass(v)
end
assert('mrb_vformat') do
- n = TestVFormat::Native
- assert_format '', ['']
- assert_format 'No specifier!', ['No specifier!']
- assert_format '`c`: C', ['`c`: %c', n.c(?C)]
- assert_format '`d`: 123', ['`d`: %d', n.d(123)]
- assert_format '`d`: -79', ['`d`: %d', n.d(-79)]
- assert_format '`i`: 514', ['`i`: %i', n.i(514)]
- assert_format '`i`: -83', ['`i`: %i', n.i(-83)]
- assert_format '`t`: NilClass', ['`t`: %t', nil]
- assert_format '`t`: FalseClass', ['`t`: %t', false]
- assert_format '`t`: TrueClass', ['`t`: %t', true]
- assert_format '`t`: Fixnum', ['`t`: %t', 0]
- assert_format '`t`: Hash', ['`t`: %t', k: "value"]
- assert_format_pattern '#<Class:#<Class:#<Hash:0x*>>>', ['%t', sclass({})]
-# assert_format 'string and length', ['string %l length', n.s('andante'), n.l(3)]
- assert_format '`n`: sym', ['`n`: %n', n.n(:sym)]
- assert_format '%C文字列%', ['%s', n.s('%C文字列%')]
- assert_format '`C`: Kernel module', ['`C`: %C module', n.C(Kernel)]
- assert_format '`C`: NilClass', ['`C`: %C', n.C(nil.class)]
- assert_format_pattern '#<Class:#<String:0x*>>', ['%C', n.C(sclass(""))]
- assert_format '`T`: NilClass', ['`T`: %T', nil]
- assert_format '`T`: FalseClass', ['`T`: %T', false]
- assert_format '`T`: TrueClass', ['`T`: %T', true]
- assert_format '`T`: Fixnum', ['`T`: %T', 0]
- assert_format '`T`: Hash', ['`T`: %T', k: "value"]
- assert_format_pattern 'Class', ['%T', sclass({})]
- assert_format '`Y`: nil', ['`Y`: %Y', nil]
- assert_format '`Y`: false', ['`Y`: %Y', false]
- assert_format '`Y`: true', ['`Y`: %Y', true]
- assert_format '`Y`: Fixnum', ['`Y`: %Y', 0]
- assert_format '`Y`: Hash', ['`Y`: %Y', k: "value"]
- assert_format 'Class', ['%Y', sclass({})]
- assert_format_pattern '#<Class:#<String:0x*>>', ['%v', sclass("")]
- assert_format '`v`: 1...3', ['`v`: %v', 1...3]
- assert_format '`S`: {:a=>1, "b"=>"c"}', ['`S`: %S', a: 1, "b" => ?c]
- assert_format 'percent: %', ['percent: %%']
- assert_format '"I": inspect char', ['%!c: inspect char', n.c(?I)]
- assert_format '709: inspect mrb_int', ['%!d: inspect mrb_int', n.i(709)]
-# assert_format '"a\x00b\xff"', ['%!l', n.s("a\000b\xFFc\000d"), n.l(4)]
- assert_format ':"&.": inspect symbol', ['%!n: inspect symbol', n.n(:'&.')]
- assert_format 'inspect "String"', ['inspect %!v', 'String']
- assert_format 'inspect Array: [1, :x, {}]', ['inspect Array: %!v', [1,:x,{}]]
- assert_format_pattern '`!C`: #<Class:0x*>', ['`!C`: %!C', n.C(Class.new)]
- assert_format 'to_s -> to_s: ab,cd', ['to_s -> to_s: %n,%v', n.n(:ab), 'cd']
- assert_format 'to_s -> inspect: x:y', ['to_s -> inspect: %v%!v', 'x', :y]
- assert_format 'inspect -> to_s: "a"b', ['inspect -> to_s: %!v%n', 'a', n.n(:b)]
- assert_format 'Y -> to_s: nile', ['Y -> to_s: %Y%v', nil, "e"]
- assert_format '"abc":Z', ['%!s%!n', n.s('abc'), n.n('Z'.to_sym)]
- assert_format 'escape: \\%a,b,c,d', ['escape: \\\\\%a,b,\c%v', ',d']
-
- assert_implementation_dependent 'unknown specifier: %^',
- ['unknown specifier: %^']
- assert_implementation_dependent 'unknown specifier with modifier: %!^',
- ['unknown specifier with modifier: %!^']
- assert_implementation_dependent 'termination is \\', ['termination is \\']
- assert_implementation_dependent 'termination is %', ['termination is %']
- assert_implementation_dependent 'termination is %!', ['termination is %!']
+ vf = TestVFormat
+ assert_equal '', vf.z('')
+ assert_equal 'No specifier!', vf.z('No specifier!')
+ assert_equal '`c`: C', vf.c('`c`: %c', ?C)
+ assert_equal '`d`: 123', vf.d('`d`: %d', 123)
+ assert_equal '`d`: -79', vf.d('`d`: %d', -79)
+ assert_equal '`i`: 514', vf.i('`i`: %i', 514)
+ assert_equal '`i`: -83', vf.i('`i`: %i', -83)
+ assert_equal '`t`: NilClass', vf.v('`t`: %t', nil)
+ assert_equal '`t`: FalseClass', vf.v('`t`: %t', false)
+ assert_equal '`t`: TrueClass', vf.v('`t`: %t', true)
+ assert_equal '`t`: Fixnum', vf.v('`t`: %t', 0)
+ assert_equal '`t`: Hash', vf.v('`t`: %t', {k: "value"})
+ assert_match '#<Class:#<Class:#<Hash:0x*>>>', vf.v('%t', sclass({}))
+ assert_equal 'string and length', vf.l('string %l length', 'andante', 3)
+ assert_equal '`n`: sym', vf.n('`n`: %n', :sym)
+ assert_equal '%C文字列����%', vf.s('%s', '%C文字列����%')
+ assert_equal '`C`: Kernel module', vf.C('`C`: %C module', Kernel)
+ assert_equal '`C`: NilClass', vf.C('`C`: %C', nil.class)
+ assert_match '#<Class:#<String:0x*>>', vf.C('%C', sclass(""))
+ assert_equal '`T`: NilClass', vf.v('`T`: %T', nil)
+ assert_equal '`T`: FalseClass', vf.v('`T`: %T', false)
+ assert_equal '`T`: TrueClass', vf.v('`T`: %T', true)
+ assert_equal '`T`: Fixnum', vf.v('`T`: %T', 0)
+ assert_equal '`T`: Hash', vf.v('`T`: %T', {k: "value"})
+ assert_match 'Class', vf.v('%T', sclass({}))
+ assert_equal '`Y`: nil', vf.v('`Y`: %Y', nil)
+ assert_equal '`Y`: false', vf.v('`Y`: %Y', false)
+ assert_equal '`Y`: true', vf.v('`Y`: %Y', true)
+ assert_equal '`Y`: Fixnum', vf.v('`Y`: %Y', 0)
+ assert_equal '`Y`: Hash', vf.v('`Y`: %Y', {k: "value"})
+ assert_equal 'Class', vf.v('%Y', sclass({}))
+ assert_match '#<Class:#<String:0x*>>', vf.v('%v', sclass(""))
+ assert_equal '`v`: 1...3', vf.v('`v`: %v', 1...3)
+ assert_equal '`S`: {:a=>1, "b"=>"c"}', vf.v('`S`: %S', {a: 1, "b" => ?c})
+ assert_equal 'percent: %', vf.z('percent: %%')
+ assert_equal '"I": inspect char', vf.c('%!c: inspect char', ?I)
+ assert_equal '709: inspect mrb_int', vf.i('%!d: inspect mrb_int', 709)
+ assert_equal '"a\x00b\xff"', vf.l('%!l', "a\000b\xFFc\000d", 4)
+ assert_equal ':"&.": inspect symbol', vf.n('%!n: inspect symbol', :'&.')
+ assert_equal 'inspect "String"', vf.v('inspect %!v', 'String')
+ assert_equal 'inspect Array: [1, :x, {}]', vf.v('inspect Array: %!v', [1,:x,{}])
+ assert_match '`!C`: #<Class:0x*>', vf.C('`!C`: %!C', Class.new)
+ assert_equal 'escape: \\%a,b,c,d', vf.v('escape: \\\\\%a,b,\c%v', ',d')
skip unless Object.const_defined?(:Float)
- assert_format '`f`: 0.0125', ['`f`: %f', n.f(0.0125)]
- assert_format '-Infinity', ['%f', n.f(-Float::INFINITY)]
- assert_format 'NaN: Not a Number', ['%f: Not a Number', n.f(Float::NAN)]
+ assert_equal '`f`: 0.0125', vf.f('`f`: %f', 0.0125)
+ assert_equal '-Infinity', vf.f('%f', -Float::INFINITY)
+ assert_equal 'NaN: Not a Number', vf.f('%f: Not a Number', Float::NAN)
end