summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2014-06-07 16:47:03 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2014-06-07 16:47:03 +0900
commit24b02955d362fcb7962ccf874158550c1f67aaa2 (patch)
treed0608206e9bcb74d5848ffd29c07747c26c9071c
parentd3fda42eb62b4132eb91fb75acc28d3218415c8b (diff)
parent9709fe79a3a75eefc92329cc0b74e159ff31525f (diff)
downloadmruby-24b02955d362fcb7962ccf874158550c1f67aaa2.tar.gz
mruby-24b02955d362fcb7962ccf874158550c1f67aaa2.zip
git push origin masterMerge branch 'suzukaze-add-string.clear2'
-rw-r--r--bintest/mrbc.rb12
-rw-r--r--src/parse.y7
-rw-r--r--src/string.c33
-rw-r--r--tasks/mruby_build.rake1
-rw-r--r--test/t/string.rb21
-rw-r--r--tools/mrbc/mrbc.c2
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);
}