From b344b2934532500d29fff93fd0dd2b1f3c89f6c7 Mon Sep 17 00:00:00 2001 From: take_cheeze Date: Wed, 9 Jul 2014 22:02:33 +0900 Subject: Use `mrb_parse_nstring` instead in eval. --- mrbgems/mruby-eval/src/eval.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/mrbgems/mruby-eval/src/eval.c b/mrbgems/mruby-eval/src/eval.c index b5cb833c2..3036837d5 100644 --- a/mrbgems/mruby-eval/src/eval.c +++ b/mrbgems/mruby-eval/src/eval.c @@ -113,10 +113,12 @@ create_proc_from_string(mrb_state *mrb, char *s, int len, mrb_value binding, cha mrbc_filename(mrb, cxt, file); } - p = mrb_parser_new(mrb); - p->s = s; - p->send = s + len; - mrb_parser_parse(p, cxt); + p = mrb_parse_nstring(mrb, s, len, cxt); + + /* only occur when memory ran out */ + if (!p) { + mrb_raise(mrb, E_RUNTIME_ERROR, "Failed to create parser state."); + } if (0 < p->nerr) { /* parse error */ -- cgit v1.2.3 From dfe65423da9ed952c1f77121adddc9b4f1137d88 Mon Sep 17 00:00:00 2001 From: take_cheeze Date: Wed, 9 Jul 2014 22:03:21 +0900 Subject: Add `SyntaxError` test and don't print compilation error to stderr in eval. --- mrbgems/mruby-eval/src/eval.c | 1 + mrbgems/mruby-eval/test/eval.rb | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/mrbgems/mruby-eval/src/eval.c b/mrbgems/mruby-eval/src/eval.c index 3036837d5..6ca7d4fc2 100644 --- a/mrbgems/mruby-eval/src/eval.c +++ b/mrbgems/mruby-eval/src/eval.c @@ -112,6 +112,7 @@ create_proc_from_string(mrb_state *mrb, char *s, int len, mrb_value binding, cha if (file) { mrbc_filename(mrb, cxt, file); } + cxt->capture_errors = TRUE; p = mrb_parse_nstring(mrb, s, len, cxt); diff --git a/mrbgems/mruby-eval/test/eval.rb b/mrbgems/mruby-eval/test/eval.rb index c0338d644..eb51f396a 100644 --- a/mrbgems/mruby-eval/test/eval.rb +++ b/mrbgems/mruby-eval/test/eval.rb @@ -44,3 +44,9 @@ assert('rest arguments of eval') do Kernel.eval('[\'test\', __FILE__, __LINE__]', nil, 'test.rb', 10) end end + +assert 'eval syntax error' do + assert_raise(SyntaxError) do + eval 'p "test' + end +end -- cgit v1.2.3 From 8df63b4d1f51814b86fa0db39d664d8fa37f148d Mon Sep 17 00:00:00 2001 From: cremno Date: Wed, 9 Jul 2014 14:18:37 +0200 Subject: check `mrb_open` return value --- mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c b/mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c index f209fa060..b89b3d32d 100644 --- a/mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c +++ b/mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c @@ -96,6 +96,10 @@ main(int argc, char **argv) } mrb = mrb_open(); + if (mrb == NULL) { + fputs("Invalid mrb_state, exiting mruby-strip\n", stderr); + return EXIT_FAILURE; + } ireps = (mrb_irep**)malloc(sizeof(mrb_irep*) * argc); for (i = args_result; i < argc; ++i) { -- cgit v1.2.3 From 41961ae6d0bfabdd00d47c75ae0c6339272e8592 Mon Sep 17 00:00:00 2001 From: cremno Date: Wed, 9 Jul 2014 15:32:13 +0200 Subject: rewrite stripping Previous version ignored some errors, and didn't free memory and close files. Now no memory will be dynamically allocated to simplify error handling. This commit also fixes a wrong check: files[i] = fopen(argv[i], "wb"); if (!ireps[i]) { Improve error messages a bit and add missing newline to one. --- .../tools/mruby-strip/mruby-strip.c | 103 +++++++++++++-------- 1 file changed, 62 insertions(+), 41 deletions(-) diff --git a/mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c b/mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c index b89b3d32d..f4b821d4b 100644 --- a/mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c +++ b/mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c @@ -6,6 +6,9 @@ #include "mruby/dump.h" struct strip_args { + int argc_start; + int argc; + char **argv; mrb_bool lvar; }; @@ -64,14 +67,65 @@ parse_args(int argc, char **argv, struct strip_args *args) return i; } +static int +strip(mrb_state *mrb, struct strip_args *args) +{ + int i; + + for (i = args->argc_start; i < args->argc; ++i) { + char *filename; + FILE *rfile; + mrb_irep *irep; + FILE *wfile; + int dump_result; + + filename = args->argv[i]; + rfile = fopen(filename, "rb"); + if (rfile == NULL) { + fprintf(stderr, "can't open file for reading %s\n", filename); + return EXIT_FAILURE; + } + + irep = mrb_read_irep_file(mrb, rfile); + fclose(rfile); + if (irep == NULL) { + fprintf(stderr, "can't read irep file %s\n", filename); + return EXIT_FAILURE; + } + + /* clear lv if --lvar is enabled */ + if (args->lvar) { + irep_remove_lv(mrb, irep); + } + + wfile = fopen(filename, "wb"); + if (wfile == NULL) { + fprintf(stderr, "can't open file for writing %s\n", filename); + mrb_irep_decref(mrb, irep); + return EXIT_FAILURE; + } + + /* debug flag must always be false */ + dump_result = mrb_dump_irep_binary(mrb, irep, FALSE, wfile); + + fclose(wfile); + mrb_irep_decref(mrb, irep); + + if (dump_result != MRB_DUMP_OK) { + fprintf(stderr, "error occurred during dumping %s\n", filename); + return EXIT_FAILURE; + } + } + return EXIT_SUCCESS; +} + int main(int argc, char **argv) { struct strip_args args; - int args_result, i, dump_result; - FILE **files; - mrb_irep **ireps; + int args_result; mrb_state *mrb; + int ret; if (argc <= 1) { printf("no files to strip\n"); @@ -85,15 +139,9 @@ main(int argc, char **argv) return EXIT_FAILURE; } - files = (FILE**)malloc(sizeof(FILE*) * argc); - for (i = args_result; i < argc; ++i) { - files[i] = fopen(argv[i], "rb"); - - if (!files[i]) { - fprintf(stderr, "can't open file %s\n", argv[i]); - return EXIT_FAILURE; - } - } + args.argc_start = args_result; + args.argc = argc; + args.argv = argv; mrb = mrb_open(); if (mrb == NULL) { @@ -101,35 +149,8 @@ main(int argc, char **argv) return EXIT_FAILURE; } - ireps = (mrb_irep**)malloc(sizeof(mrb_irep*) * argc); - for (i = args_result; i < argc; ++i) { - ireps[i] = mrb_read_irep_file(mrb, files[i]); - if (!ireps[i]) { - fprintf(stderr, "can't read irep file %s\n", argv[i]); - return EXIT_FAILURE; - } - fclose(files[i]); - files[i] = fopen(argv[i], "wb"); - if (!ireps[i]) { - fprintf(stderr, "can't reopen irep file %s\n", argv[i]); - return EXIT_FAILURE; - } - } - - for (i = args_result; i < argc; ++i) { - /* clear lv if --lvar is enabled */ - if (args.lvar) { - irep_remove_lv(mrb, ireps[i]); - } - - /* debug flag must be alway false */ - dump_result = mrb_dump_irep_binary(mrb, ireps[i], FALSE, files[i]); - if (dump_result != MRB_DUMP_OK) { - fprintf(stderr, "error occur when dumping %s", argv[i]); - return EXIT_FAILURE; - } - } + ret = strip(mrb, &args); mrb_close(mrb); - return EXIT_SUCCESS; + return ret; } -- cgit v1.2.3 From b4c1a943d17930bc24b076a952e36b3448c6aeb6 Mon Sep 17 00:00:00 2001 From: cremno Date: Wed, 9 Jul 2014 16:42:11 +0200 Subject: update expected error message in bintest --- mrbgems/mruby-bin-strip/bintest/mruby-strip.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mrbgems/mruby-bin-strip/bintest/mruby-strip.rb b/mrbgems/mruby-bin-strip/bintest/mruby-strip.rb index 770ea0638..e74a74f10 100644 --- a/mrbgems/mruby-bin-strip/bintest/mruby-strip.rb +++ b/mrbgems/mruby-bin-strip/bintest/mruby-strip.rb @@ -9,7 +9,7 @@ end assert('file not found') do o = `bin/mruby-strip not_found.mrb 2>&1` assert_equal 1, $?.exitstatus - assert_equal "can't open file not_found.mrb\n", o + assert_equal "can't open file for reading not_found.mrb\n", o end assert('not irep file') do -- cgit v1.2.3 From c90d923273cf49ea6d20351c3035e13ebedfb795 Mon Sep 17 00:00:00 2001 From: cremno Date: Wed, 9 Jul 2014 15:39:54 +0200 Subject: coding style adjustments --- mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c b/mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c index f4b821d4b..28bb2ca76 100644 --- a/mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c +++ b/mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c @@ -45,9 +45,9 @@ parse_args(int argc, char **argv, struct strip_args *args) *args = initial_args; for (i = 1; i < argc; ++i) { - size_t const len = strlen(argv[i]); + const size_t len = strlen(argv[i]); if (len >= 2 && argv[i][0] == '-') { - switch(argv[i][1]) { + switch (argv[i][1]) { case 'l': args->lvar = TRUE; break; @@ -59,7 +59,8 @@ parse_args(int argc, char **argv, struct strip_args *args) default: return -1; } - } else { + } + else { break; } } -- cgit v1.2.3 From 10bd78e85ddf3ba6238e7a37cef4ccad08dee51f Mon Sep 17 00:00:00 2001 From: cremno Date: Wed, 9 Jul 2014 16:36:07 +0200 Subject: initialize `args` in `parse_args` --- mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c b/mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c index 28bb2ca76..75d6d49fd 100644 --- a/mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c +++ b/mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c @@ -39,10 +39,12 @@ print_usage(const char *f) static int parse_args(int argc, char **argv, struct strip_args *args) { - static const struct strip_args initial_args = {0}; int i; - *args = initial_args; + args->argc_start = 0; + args->argc = argc; + args->argv = argv; + args->lvar = FALSE; for (i = 1; i < argc; ++i) { const size_t len = strlen(argv[i]); @@ -65,6 +67,7 @@ parse_args(int argc, char **argv, struct strip_args *args) } } + args->argc_start = i; return i; } @@ -139,11 +142,6 @@ main(int argc, char **argv) print_usage(argv[0]); return EXIT_FAILURE; } - - args.argc_start = args_result; - args.argc = argc; - args.argv = argv; - mrb = mrb_open(); if (mrb == NULL) { fputs("Invalid mrb_state, exiting mruby-strip\n", stderr); -- cgit v1.2.3 From ec45dbe16a418f58414f039f1a3b734cd14f63b8 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Fri, 11 Jul 2014 09:11:49 +0900 Subject: remove spaces after open parens --- mrbgems/mruby-random/src/random.c | 2 +- mrbgems/mruby-sprintf/src/sprintf.c | 2 +- src/numeric.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mrbgems/mruby-random/src/random.c b/mrbgems/mruby-random/src/random.c index 391336493..c3f030c74 100644 --- a/mrbgems/mruby-random/src/random.c +++ b/mrbgems/mruby-random/src/random.c @@ -46,7 +46,7 @@ mrb_random_mt_srand(mrb_state *mrb, mt_state *t, mrb_value seed) if (mrb_nil_p(seed)) { seed = mrb_fixnum_value((mrb_int)(time(NULL) + mt_rand(t))); if (mrb_fixnum(seed) < 0) { - seed = mrb_fixnum_value( 0 - mrb_fixnum(seed)); + seed = mrb_fixnum_value(0 - mrb_fixnum(seed)); } } diff --git a/mrbgems/mruby-sprintf/src/sprintf.c b/mrbgems/mruby-sprintf/src/sprintf.c index 31f22975d..3fce60237 100644 --- a/mrbgems/mruby-sprintf/src/sprintf.c +++ b/mrbgems/mruby-sprintf/src/sprintf.c @@ -836,7 +836,7 @@ retry: if (base == 2) { org_v = v; - if ( v < 0 && !sign ) { + if (v < 0 && !sign) { val = mrb_fix2binstr(mrb, mrb_fixnum_value(v), base); dots = 1; } diff --git a/src/numeric.c b/src/numeric.c index 3f7600151..51ce0399f 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -474,7 +474,7 @@ flo_infinite_p(mrb_state *mrb, mrb_value num) mrb_float value = mrb_float(num); if (isinf(value)) { - return mrb_fixnum_value( value < 0 ? -1 : 1 ); + return mrb_fixnum_value(value < 0 ? -1 : 1); } return mrb_nil_value(); } -- cgit v1.2.3 From 55a31f3f239e9ee1c09f1094b1bd6bbed07bf58b Mon Sep 17 00:00:00 2001 From: cremno Date: Fri, 11 Jul 2014 08:40:40 +0200 Subject: check the return value of `fwrite` --- src/dump.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/dump.c b/src/dump.c index b820f1a68..e019baa99 100644 --- a/src/dump.c +++ b/src/dump.c @@ -952,7 +952,9 @@ mrb_dump_irep_binary(mrb_state *mrb, mrb_irep *irep, int debug_info, FILE* fp) result = mrb_dump_irep(mrb, irep, debug_info, &bin, &bin_size); if (result == MRB_DUMP_OK) { - fwrite(bin, bin_size, 1, fp); + if (fwrite(bin, sizeof(bin[0]), bin_size, fp) != bin_size) { + result = MRB_DUMP_WRITE_FAULT; + } } mrb_free(mrb, bin); -- cgit v1.2.3 From 03866f25f86a4f0d0f924b664414fedaac31319d Mon Sep 17 00:00:00 2001 From: take_cheeze Date: Thu, 10 Jul 2014 21:43:07 +0900 Subject: Run mrbgem and core tests on minimum dependencies. Solves #2355. In test drivers: * Uses `mrb_t_pass_result` to check and pass test result to main `mrb_state`. * Adds `mrb_init_test_driver` to init test `mrb_state`. --- mrbgems/mruby-enumerator/mrbgem.rake | 1 + mrbgems/mruby-hash-ext/mrbgem.rake | 2 + mrbgems/mruby-numeric-ext/test/numeric.rb | 9 +-- tasks/mrbgem_spec.rake | 44 ++++++++++---- tasks/mrbgems_test.rake | 95 +++++++------------------------ test/driver.c | 65 +++++++++++++++++---- test/init_mrbtest.c | 13 ++++- test/mrbtest.rake | 11 ++-- test/no_mrb_open_test_dummy.rb | 2 - 9 files changed, 130 insertions(+), 112 deletions(-) delete mode 100644 test/no_mrb_open_test_dummy.rb diff --git a/mrbgems/mruby-enumerator/mrbgem.rake b/mrbgems/mruby-enumerator/mrbgem.rake index abcc54e7a..8757a15ea 100644 --- a/mrbgems/mruby-enumerator/mrbgem.rake +++ b/mrbgems/mruby-enumerator/mrbgem.rake @@ -2,5 +2,6 @@ MRuby::Gem::Specification.new('mruby-enumerator') do |spec| spec.license = 'MIT' spec.author = 'mruby developers' spec.add_dependency('mruby-fiber', :core => 'mruby-fiber') + spec.add_dependency 'mruby-enum-ext', :core => 'mruby-enum-ext' spec.summary = 'Enumerator class' end diff --git a/mrbgems/mruby-hash-ext/mrbgem.rake b/mrbgems/mruby-hash-ext/mrbgem.rake index e1ce8e767..663de2166 100644 --- a/mrbgems/mruby-hash-ext/mrbgem.rake +++ b/mrbgems/mruby-hash-ext/mrbgem.rake @@ -2,4 +2,6 @@ MRuby::Gem::Specification.new('mruby-hash-ext') do |spec| spec.license = 'MIT' spec.author = 'mruby developers' spec.summary = 'extensional Hash class' + spec.add_dependency 'mruby-enum-ext', :core => 'mruby-enum-ext' + spec.add_dependency 'mruby-array-ext', :core => 'mruby-array-ext' end diff --git a/mrbgems/mruby-numeric-ext/test/numeric.rb b/mrbgems/mruby-numeric-ext/test/numeric.rb index 4d9e83113..96644da69 100644 --- a/mrbgems/mruby-numeric-ext/test/numeric.rb +++ b/mrbgems/mruby-numeric-ext/test/numeric.rb @@ -5,13 +5,8 @@ assert('Integer#chr') do assert_equal("A", 65.chr) assert_equal("B", 0x42.chr) - if "こんにちわ世界".size == 7 then - # UTF-8 gem is configured - assert_raise(RangeError) { 0x110000.chr } - else - # multibyte encoding (not support yet) - assert_raise(RangeError) { 256.chr } - end + # multibyte encoding (not support yet) + assert_raise(RangeError) { 256.chr } end assert('Integer#div') do diff --git a/tasks/mrbgem_spec.rake b/tasks/mrbgem_spec.rake index 2a15a1f46..9e461d42b 100644 --- a/tasks/mrbgem_spec.rake +++ b/tasks/mrbgem_spec.rake @@ -45,10 +45,6 @@ module MRuby MRuby::Gem.current = self end - def run_test_in_other_mrb_state? - not test_preload.nil? or not test_objs.empty? or not test_args.empty? - end - def setup MRuby::Gem.current = self MRuby::Build::COMMANDS.each do |command| @@ -184,13 +180,15 @@ module MRuby print_gem_comment(f) f.puts %Q[#include ] f.puts %Q[#include "mruby.h"] - f.puts %Q[#include "mruby/array.h"] f.puts %Q[#include "mruby/irep.h"] - f.puts %Q[#include "mruby/string.h"] f.puts %Q[#include "mruby/variable.h"] f.puts %Q[#include "mruby/hash.h"] unless test_args.empty? end + def test_dependencies + [@name] + end + def version_ok?(req_versions) req_versions.map do |req| cmp, ver = req.split @@ -290,7 +288,7 @@ module MRuby @ary.empty? end - def check(build) + def generate_gem_table gem_table = @ary.reduce({}) { |res,v| res[v.name] = v; res } default_gems = [] @@ -335,9 +333,29 @@ module MRuby fail "Conflicts of gem `#{g.name}` found: #{cfls.join ', '}" unless cfls.empty? end - class << gem_table + gem_table + end + + def tsort_dependencies ary, table, all_dependency_listed = false + unless all_dependency_listed + left = ary.dup + until left.empty? + v = left.pop + table[v].dependencies.each do |dep| + left.push dep[:gem] + ary.push dep[:gem] + end + end + end + + ary.uniq! + table.instance_variable_set :@root_gems, ary + class << table include TSort - alias tsort_each_node each_key + def tsort_each_node &b + @root_gems.each &b + end + def tsort_each_child(n, &b) fetch(n).dependencies.each do |v| b.call v[:gem] @@ -346,10 +364,16 @@ module MRuby end begin - @ary = gem_table.tsort.map { |v| gem_table[v] } + table.tsort.map { |v| table[v] } rescue TSort::Cyclic => e fail "Circular mrbgem dependency found: #{e.message}" end + end + + def check(build) + gem_table = generate_gem_table + + @ary = tsort_dependencies gem_table.keys, gem_table, true each do |g| import_include_paths(g) diff --git a/tasks/mrbgems_test.rake b/tasks/mrbgems_test.rake index 2fdf5f171..9fc9a9d2a 100644 --- a/tasks/mrbgems_test.rake +++ b/tasks/mrbgems_test.rake @@ -1,16 +1,12 @@ MRuby.each_target do - no_mrb_open_test_gem = [] + gem_table = gems.generate_gem_table gems.each do |g| - unless g.run_test_in_other_mrb_state? - no_mrb_open_test_gem << g - next - end - test_rbobj = g.test_rbireps.ext(exts.object) + dep_list = gems.tsort_dependencies g.test_dependencies, gem_table file test_rbobj => g.test_rbireps - file g.test_rbireps => [g.test_rbfiles].flatten + [g.build.mrbcfile, __FILE__] do |t| + file g.test_rbireps => [g.test_rbfiles].flatten + [File.join(g.dir, 'mrbgem.rake'), g.build.mrbcfile, __FILE__, "#{MRUBY_ROOT}/tasks/mrbgem_spec.rake"] do |t| open(t.name, 'w') do |f| g.print_gem_test_header(f) test_preload = g.test_preload and [g.dir, MRUBY_ROOT].map {|dir| @@ -33,21 +29,32 @@ MRuby.each_target do g.build.mrbc.run f, rbfile, "gem_test_irep_#{g.funcname}_#{i}" end f.puts %Q[void mrb_#{g.funcname}_gem_test(mrb_state *mrb);] unless g.test_objs.empty? + dep_list.each do |d| + f.puts %Q[void GENERATED_TMP_mrb_#{d.funcname}_gem_init(mrb_state *mrb);] + f.puts %Q[void GENERATED_TMP_mrb_#{d.funcname}_gem_final(mrb_state *mrb);] + end + f.puts %Q[void mrb_init_test_driver(mrb_state *mrb);] + f.puts %Q[void mrb_t_pass_result(mrb_state *dst, mrb_state *src);] f.puts %Q[void GENERATED_TMP_mrb_#{g.funcname}_gem_test(mrb_state *mrb) {] unless g.test_rbfiles.empty? f.puts %Q[ mrb_state *mrb2;] if g.test_args.empty? - f.puts %Q[ mrb_value val1, val2, val3, ary1, ary2;] + f.puts %Q[ mrb_value verbose;] else - f.puts %Q[ mrb_value val1, val2, val3, ary1, ary2, test_args_hash;] + f.puts %Q[ mrb_value verbose, test_args_hash;] end f.puts %Q[ int ai;] g.test_rbfiles.count.times do |i| f.puts %Q[ ai = mrb_gc_arena_save(mrb);] - f.puts %Q[ mrb2 = mrb_open();] - f.puts %Q[ val3 = mrb_gv_get(mrb, mrb_intern_lit(mrb, "$mrbtest_verbose"));] - f.puts %Q[ if (mrb_test(val3)) {] - f.puts %Q[ mrb_gv_set(mrb2, mrb_intern_lit(mrb2, "$mrbtest_verbose"), val3);] + f.puts %Q[ mrb2 = mrb_open_core(mrb_default_allocf, NULL);] + dep_list.each do |d| + f.puts %Q[ GENERATED_TMP_mrb_#{d.funcname}_gem_init(mrb2);] + f.puts %Q[ mrb_state_atexit(mrb2, GENERATED_TMP_mrb_#{d.funcname}_gem_final);] + end + f.puts %Q[ mrb_init_test_driver(mrb2);] + f.puts %Q[ verbose = mrb_gv_get(mrb, mrb_intern_lit(mrb, "$mrbtest_verbose"));] + f.puts %Q[ if (mrb_test(verbose)) {] + f.puts %Q[ mrb_gv_set(mrb2, mrb_intern_lit(mrb2, "$mrbtest_verbose"), verbose);] f.puts %Q[ }] if test_preload.nil? f.puts %Q[ mrb_load_irep(mrb2, mrbtest_assert_irep);] @@ -73,30 +80,9 @@ MRuby.each_target do f.puts %Q[ mrb_#{g.funcname}_gem_test(mrb2);] unless g.test_objs.empty? f.puts %Q[ mrb_load_irep(mrb2, gem_test_irep_#{g.funcname}_#{i});] - f.puts %Q[ if (mrb2->exc) {] - f.puts %Q[ mrb_print_error(mrb2);] - f.puts %Q[ exit(EXIT_FAILURE);] - f.puts %Q[ }] f.puts %Q[ ] - %w(ok_test ko_test kill_test).each do |vname| - f.puts %Q[ val2 = mrb_gv_get(mrb2, mrb_intern_lit(mrb2, "$#{vname}"));] - f.puts %Q[ if (mrb_fixnum_p(val2)) {] - f.puts %Q[ val1 = mrb_gv_get(mrb, mrb_intern_lit(mrb, "$#{vname}"));] - f.puts %Q[ mrb_gv_set(mrb, mrb_intern_lit(mrb, "$#{vname}"), mrb_fixnum_value(mrb_fixnum(val1) + mrb_fixnum(val2)));] - f.puts %Q[ }\n] - end - - f.puts %Q[ ary2 = mrb_gv_get(mrb2, mrb_intern_lit(mrb2, "$asserts"));] - f.puts %Q[ if (mrb_test(ary2)) {] - f.puts %Q[ ary1 = mrb_gv_get(mrb, mrb_intern_lit(mrb, "$asserts"));] - f.puts %Q[ val2 = mrb_ary_shift(mrb2, ary2);] - f.puts %Q[ ] - f.puts %Q[ while (mrb_test(val2)) {] - f.puts %Q[ mrb_ary_push(mrb, ary1, mrb_str_new(mrb, RSTRING_PTR(val2), RSTRING_LEN(val2)));] - f.puts %Q[ val2 = mrb_ary_shift(mrb2, ary2);] - f.puts %Q[ }] - f.puts %Q[ }] + f.puts %Q[ mrb_t_pass_result(mrb, mrb2);] f.puts %Q[ mrb_close(mrb2);] f.puts %Q[ mrb_gc_arena_restore(mrb, ai);] end @@ -104,44 +90,5 @@ MRuby.each_target do f.puts %Q[}] end end - - end - - no_mrb_open_test = "#{build_dir}/test/no_mrb_open_test" - no_mrb_open_test_rbfiles = no_mrb_open_test_gem.reduce([]) { |res, v| - res += v.test_rbfiles - } - if no_mrb_open_test_rbfiles.empty? - no_mrb_open_test_rbfiles << "#{MRUBY_ROOT}/test/no_mrb_open_test_dummy.rb" - end - - no_mrb_open_test_lib = no_mrb_open_test.ext(exts.object) - file no_mrb_open_test_lib => "#{no_mrb_open_test}.c" - file "#{no_mrb_open_test}.c" => no_mrb_open_test_rbfiles + [MRUBY_CONFIG, __FILE__] do |t| - open(t.name, 'w') do |f| - f.puts %Q[/*] - f.puts %Q[ * This file contains a test code for following gems:] - no_mrb_open_test_gem.each { |g| f.puts %Q[ * #{g.name}] } - f.puts %Q[ *] - f.puts %Q[ * IMPORTANT:] - f.puts %Q[ * This file was generated!] - f.puts %Q[ * All manual changes will get lost.] - f.puts %Q[ */] - - f.puts %Q[] - - f.puts %Q[\#include "mruby.h"] - f.puts %Q[\#include "mruby/irep.h"] - - f.puts %Q[] - - mrbc.run f, no_mrb_open_test_rbfiles, "no_mrb_open_gem_test_irep" - - f.puts %Q[] - - f.puts %Q[void no_mrb_open_mrbgem_test(mrb_state *mrb) {] - f.puts %Q[ mrb_load_irep(mrb, no_mrb_open_gem_test_irep);] - f.puts %Q[}] - end end end diff --git a/test/driver.c b/test/driver.c index 7fd8ef720..c696262bf 100644 --- a/test/driver.c +++ b/test/driver.c @@ -16,6 +16,7 @@ #include "mruby/compile.h" #include "mruby/string.h" #include "mruby/variable.h" +#include "mruby/array.h" void mrb_init_mrbtest(mrb_state *); @@ -81,12 +82,62 @@ mrb_t_printstr(mrb_state *mrb, mrb_value self) return argv; } +void +mrb_init_test_driver(mrb_state *mrb) +{ + struct RClass *krn, *mrbtest; + + krn = mrb->kernel_module; + mrb_define_method(mrb, krn, "__t_printstr__", mrb_t_printstr, MRB_ARGS_REQ(1)); + + mrbtest = mrb_define_module(mrb, "Mrbtest"); + + mrb_define_const(mrb, mrbtest, "FIXNUM_MAX", mrb_fixnum_value(MRB_INT_MAX)); + mrb_define_const(mrb, mrbtest, "FIXNUM_MIN", mrb_fixnum_value(MRB_INT_MIN)); + mrb_define_const(mrb, mrbtest, "FIXNUM_BIT", mrb_fixnum_value(MRB_INT_BIT)); +} + +void +mrb_t_pass_result(mrb_state *mrb_dst, mrb_state *mrb_src) +{ + mrb_value res_src; + + if (mrb_src->exc) { + mrb_print_error(mrb_src); + exit(EXIT_FAILURE); + } + +#define TEST_COUNT_PASS(name) \ + do { \ + res_src = mrb_gv_get(mrb_src, mrb_intern_lit(mrb_src, "$" #name)); \ + if (mrb_fixnum_p(res_src)) { \ + mrb_value res_dst = mrb_gv_get(mrb_dst, mrb_intern_lit(mrb_dst, "$" #name)); \ + mrb_gv_set(mrb_dst, mrb_intern_lit(mrb_dst, "$" #name), mrb_fixnum_value(mrb_fixnum(res_dst) + mrb_fixnum(res_src))); \ + } \ + } while (FALSE) \ + + TEST_COUNT_PASS(ok_test); + TEST_COUNT_PASS(ko_test); + TEST_COUNT_PASS(kill_test); + +#undef TEST_COUNT_PASS + + res_src = mrb_gv_get(mrb_src, mrb_intern_lit(mrb_src, "$asserts")); + + if (mrb_array_p(res_src)) { + mrb_int i; + mrb_value res_dst = mrb_gv_get(mrb_dst, mrb_intern_lit(mrb_dst, "$asserts")); + for (i = 0; i < RARRAY_LEN(res_src); ++i) { + mrb_value val_src = RARRAY_PTR(res_src)[i]; + mrb_ary_push(mrb_dst, res_dst, mrb_str_new(mrb_dst, RSTRING_PTR(val_src), RSTRING_LEN(val_src))); + } + } +} + int main(int argc, char **argv) { mrb_state *mrb; - struct RClass *krn; - struct RClass *mrbtest; int ret; print_hint(); @@ -103,15 +154,7 @@ main(int argc, char **argv) mrb_gv_set(mrb, mrb_intern_lit(mrb, "$mrbtest_verbose"), mrb_true_value()); } - krn = mrb->kernel_module; - mrb_define_method(mrb, krn, "__t_printstr__", mrb_t_printstr, MRB_ARGS_REQ(1)); - - mrbtest = mrb_define_module(mrb, "Mrbtest"); - - mrb_define_const(mrb, mrbtest, "FIXNUM_MAX", mrb_fixnum_value(MRB_INT_MAX)); - mrb_define_const(mrb, mrbtest, "FIXNUM_MIN", mrb_fixnum_value(MRB_INT_MIN)); - mrb_define_const(mrb, mrbtest, "FIXNUM_BIT", mrb_fixnum_value(MRB_INT_BIT)); - + mrb_init_test_driver(mrb); mrb_init_mrbtest(mrb); ret = eval_test(mrb); mrb_close(mrb); diff --git a/test/init_mrbtest.c b/test/init_mrbtest.c index 3ce42f661..3a61a6f39 100644 --- a/test/init_mrbtest.c +++ b/test/init_mrbtest.c @@ -6,15 +6,26 @@ extern const uint8_t mrbtest_assert_irep[]; extern const uint8_t mrbtest_irep[]; void mrbgemtest_init(mrb_state* mrb); +void mrb_init_test_driver(mrb_state* mrb); +void mrb_t_pass_result(mrb_state *mrb_dst, mrb_state *mrb_src); void mrb_init_mrbtest(mrb_state *mrb) { + mrb_state *core_test; + mrb_load_irep(mrb, mrbtest_assert_irep); - mrb_load_irep(mrb, mrbtest_irep); + + core_test = mrb_open_core(mrb_default_allocf, NULL); + mrb_init_test_driver(core_test); + mrb_load_irep(core_test, mrbtest_assert_irep); + mrb_load_irep(core_test, mrbtest_irep); + mrb_t_pass_result(mrb, core_test); + #ifndef DISABLE_GEMS mrbgemtest_init(mrb); #endif + if (mrb->exc) { mrb_print_error(mrb); exit(EXIT_FAILURE); diff --git a/test/mrbtest.rake b/test/mrbtest.rake index c28cf3577..21afad946 100644 --- a/test/mrbtest.rake +++ b/test/mrbtest.rake @@ -12,11 +12,12 @@ MRuby.each_target do ass_lib = ass_c.ext(exts.object) mrbtest_lib = libfile("#{current_build_dir}/mrbtest") - gem_test_files = gems.select { |g| g.run_test_in_other_mrb_state? }.map { |g| g.test_rbireps.ext(exts.object) } - file mrbtest_lib => [mlib, ass_lib, gems.map(&:test_objs), gem_test_files].flatten do |t| + mrbtest_objs = gems.map do |v| + v.test_objs + [v.test_rbireps.ext(exts.object)] + end + file mrbtest_lib => [mlib, ass_lib] + mrbtest_objs do |t| archiver.run t.name, t.prerequisites end - file mrbtest_lib => "#{build_dir}/test/no_mrb_open_test.c".ext(exts.object) unless build_mrbtest_lib_only? driver_obj = objfile("#{current_build_dir}/driver") @@ -55,16 +56,12 @@ MRuby.each_target do f.puts IO.read(init) mrbc.run f, mrbs, 'mrbtest_irep' gems.each do |g| - next unless g.run_test_in_other_mrb_state? f.puts %Q[void GENERATED_TMP_mrb_#{g.funcname}_gem_test(mrb_state *mrb);] end - f.puts %Q[void no_mrb_open_mrbgem_test(mrb_state *mrb);] f.puts %Q[void mrbgemtest_init(mrb_state* mrb) {] gems.each do |g| - next unless g.run_test_in_other_mrb_state? f.puts %Q[ GENERATED_TMP_mrb_#{g.funcname}_gem_test(mrb);] end - f.puts %Q[ no_mrb_open_mrbgem_test(mrb);] f.puts %Q[}] end end diff --git a/test/no_mrb_open_test_dummy.rb b/test/no_mrb_open_test_dummy.rb deleted file mode 100644 index 5181c0a45..000000000 --- a/test/no_mrb_open_test_dummy.rb +++ /dev/null @@ -1,2 +0,0 @@ -#dummy - -- cgit v1.2.3