diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2014-06-07 16:47:03 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2014-06-07 16:47:03 +0900 |
| commit | 24b02955d362fcb7962ccf874158550c1f67aaa2 (patch) | |
| tree | d0608206e9bcb74d5848ffd29c07747c26c9071c | |
| parent | d3fda42eb62b4132eb91fb75acc28d3218415c8b (diff) | |
| parent | 9709fe79a3a75eefc92329cc0b74e159ff31525f (diff) | |
| download | mruby-24b02955d362fcb7962ccf874158550c1f67aaa2.tar.gz mruby-24b02955d362fcb7962ccf874158550c1f67aaa2.zip | |
git push origin masterMerge branch 'suzukaze-add-string.clear2'
| -rw-r--r-- | bintest/mrbc.rb | 12 | ||||
| -rw-r--r-- | src/parse.y | 7 | ||||
| -rw-r--r-- | src/string.c | 33 | ||||
| -rw-r--r-- | tasks/mruby_build.rake | 1 | ||||
| -rw-r--r-- | test/t/string.rb | 21 | ||||
| -rw-r--r-- | tools/mrbc/mrbc.c | 2 |
6 files changed, 70 insertions, 6 deletions
diff --git a/bintest/mrbc.rb b/bintest/mrbc.rb new file mode 100644 index 000000000..b016378a1 --- /dev/null +++ b/bintest/mrbc.rb @@ -0,0 +1,12 @@ +require 'tempfile' + +assert('Compiling multiple files without new line in last line. #2361') do + a, b, out = Tempfile.new('a.rb'), Tempfile.new('b.rb'), Tempfile.new('out.mrb') + a.write('module A; end') + a.flush + b.write('module B; end') + b.flush + result = `bin/mrbc -c -o #{out.path} #{a.path} #{b.path} 2>&1` + assert_equal "bin/mrbc:#{a.path}:Syntax OK", result.chomp + assert_equal 0, $?.exitstatus +end diff --git a/src/parse.y b/src/parse.y index 1d4e83cde..27c2dd80d 100644 --- a/src/parse.y +++ b/src/parse.y @@ -3389,7 +3389,7 @@ nextc(parser_state *p) else { if (p->cxt->partial_hook(p) < 0) return -1; - return -2; + return '\n'; } } @@ -3777,7 +3777,6 @@ read_escape(parser_state *p) eof: case -1: - case -2: yyerror(p, "Invalid escape character syntax"); return '\0'; @@ -4093,7 +4092,6 @@ parser_yylex(parser_state *p) case '#': /* it's a comment */ skip(p, '\n'); /* fall through */ - case -2: /* end of partial script. */ case '\n': maybe_heredoc: heredoc_treat_nextline(p); @@ -4128,7 +4126,6 @@ parser_yylex(parser_state *p) goto retry; } case -1: /* EOF */ - case -2: /* end of partial script */ goto normal_newline; default: pushback(p, c); @@ -5450,7 +5447,7 @@ mrb_parser_set_filename(struct mrb_parser_state *p, const char *f) sym = mrb_intern_cstr(p->mrb, f); p->filename = mrb_sym2name_len(p->mrb, sym, NULL); - p->lineno = (p->filename_table_length > 0)? 0 : 1; + p->lineno = (p->filename_table_length > 0)? -1 : 1; for (i = 0; i < p->filename_table_length; ++i) { if (p->filename_table[i] == sym) { diff --git a/src/string.c b/src/string.c index 842e83d76..6fa9271e1 100644 --- a/src/string.c +++ b/src/string.c @@ -2523,6 +2523,38 @@ mrb_str_bytes(mrb_state *mrb, mrb_value str) return a; } +static inline void +str_discard(mrb_state *mrb, mrb_value str) { + struct RString *s = mrb_str_ptr(str); + + if (!STR_SHARED_P(s) && !STR_EMBED_P(s) && ((s->flags & MRB_STR_NOFREE) == 0)) { + mrb_free(mrb, s->as.heap.ptr); + RSTRING(str)->as.heap.ptr = 0; + RSTRING(str)->as.heap.len = 0; + } +} + +/* + * call-seq: + * string.clear -> string + * + * Makes string empty. + * + * a = "abcde" + * a.clear #=> "" + */ +static mrb_value +mrb_str_clear(mrb_state *mrb, mrb_value str) +{ + struct RString *s = mrb_str_ptr(str); + + str_discard(mrb, str); + STR_SET_EMBED_FLAG(s); + STR_SET_EMBED_LEN(s, 0); + RSTRING_PTR(str)[0] = '\0'; + return str; +} + /* ---------------------------*/ void mrb_init_string(mrb_state *mrb) @@ -2574,4 +2606,5 @@ mrb_init_string(mrb_state *mrb) mrb_define_method(mrb, s, "upcase!", mrb_str_upcase_bang, MRB_ARGS_REQ(1)); /* 15.2.10.5.43 */ mrb_define_method(mrb, s, "inspect", mrb_str_inspect, MRB_ARGS_NONE()); /* 15.2.10.5.46(x) */ mrb_define_method(mrb, s, "bytes", mrb_str_bytes, MRB_ARGS_NONE()); + mrb_define_method(mrb, s, "clear", mrb_str_clear, MRB_ARGS_NONE()); } diff --git a/tasks/mruby_build.rake b/tasks/mruby_build.rake index 966c602a4..09175d533 100644 --- a/tasks/mruby_build.rake +++ b/tasks/mruby_build.rake @@ -209,6 +209,7 @@ module MRuby def run_bintest targets = @gems.select { |v| File.directory? "#{v.dir}/bintest" }.map { |v| filename v.dir } + targets << filename(".") if File.directory? "./bintest" sh "ruby test/bintest.rb #{targets.join ' '}" end diff --git a/test/t/string.rb b/test/t/string.rb index 5ecb51530..779a74791 100644 --- a/test/t/string.rb +++ b/test/t/string.rb @@ -515,3 +515,24 @@ assert('String#each_byte') do assert_equal bytes1, bytes2 end + +assert('String#clear') do + # embed string + s = "foo" + assert_equal("", s.clear) + assert_equal("", s) + + # not embed string and not shared string + s = "foo" * 100 + a = s + assert_equal("", s.clear) + assert_equal("", s) + assert_equal("", a) + + # shared string + s = "foo" * 100 + a = s[10, 90] # create shared string + assert_equal("", s.clear) # clear + assert_equal("", s) # s is cleared + assert_not_equal("", a) # a should not be affected +end diff --git a/tools/mrbc/mrbc.c b/tools/mrbc/mrbc.c index e5858e54a..52e762a50 100644 --- a/tools/mrbc/mrbc.c +++ b/tools/mrbc/mrbc.c @@ -270,7 +270,7 @@ main(int argc, char **argv) fprintf(stderr, "%s: no program file given\n", args.prog); return EXIT_FAILURE; } - if (args.outfile == NULL) { + if (args.outfile == NULL && !args.check_syntax) { if (n + 1 == argc) { args.outfile = get_outfilename(mrb, argv[n], args.initname ? C_EXT : RITEBIN_EXT); } |
