From e3beef065c2de80a843f329599b424676d83086c Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Tue, 9 Apr 2019 18:23:11 +0900 Subject: Extract frozen checking to function --- src/string.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'src/string.c') diff --git a/src/string.c b/src/string.c index 63c592d59..f7a805a94 100644 --- a/src/string.c +++ b/src/string.c @@ -493,20 +493,12 @@ str_index_str(mrb_state *mrb, mrb_value str, mrb_value str2, mrb_int offset) return mrb_str_index(mrb, str, ptr, len, offset); } -static void -check_frozen(mrb_state *mrb, struct RString *s) -{ - if (MRB_FROZEN_P(s)) { - mrb_raise(mrb, E_FROZEN_ERROR, "can't modify frozen string"); - } -} - static mrb_value str_replace(mrb_state *mrb, struct RString *s1, struct RString *s2) { mrb_int len; - check_frozen(mrb, s1); + mrb_check_frozen(mrb, s1); if (s1 == s2) return mrb_obj_value(s1); s1->flags &= ~MRB_STR_NO_UTF; s1->flags |= s2->flags&MRB_STR_NO_UTF; @@ -646,7 +638,7 @@ mrb_locale_from_utf8(const char *utf8, int len) MRB_API void mrb_str_modify(mrb_state *mrb, struct RString *s) { - check_frozen(mrb, s); + mrb_check_frozen(mrb, s); s->flags &= ~MRB_STR_NO_UTF; if (RSTR_SHARED_P(s)) { mrb_shared_string *shared = s->as.heap.aux.shared; -- cgit v1.2.3 From 0c5f26e0ffc30bdc88b857daed1c9fe18c4b8f0c Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 24 Apr 2019 09:43:12 +0900 Subject: Remove unnecessary `mrb_regexp_check()` and related functions. --- include/mruby.h | 4 ---- include/mruby/string.h | 3 --- include/mruby/value.h | 1 - src/etc.c | 16 ---------------- src/string.c | 39 ++++++--------------------------------- 5 files changed, 6 insertions(+), 57 deletions(-) (limited to 'src/string.c') diff --git a/include/mruby.h b/include/mruby.h index de6a803ef..dcd64b2d8 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -196,13 +196,9 @@ struct mrb_jmpbuf; typedef void (*mrb_atexit_func)(struct mrb_state*); -#define MRB_STATE_NO_REGEXP 1 -#define MRB_STATE_REGEXP 2 - typedef struct mrb_state { struct mrb_jmpbuf *jmp; - uint32_t flags; mrb_allocf allocf; /* memory allocation function */ void *allocf_ud; /* auxiliary data of allocf */ diff --git a/include/mruby/string.h b/include/mruby/string.h index 0b90debec..22445f654 100644 --- a/include/mruby/string.h +++ b/include/mruby/string.h @@ -433,9 +433,6 @@ mrb_value mrb_str_dump(mrb_state *mrb, mrb_value str); */ mrb_value mrb_str_inspect(mrb_state *mrb, mrb_value str); -void mrb_noregexp(mrb_state *mrb, mrb_value self); -void mrb_regexp_check(mrb_state *mrb, mrb_value obj); - /* For backward compatibility */ #define mrb_str_cat2(mrb, str, ptr) mrb_str_cat_cstr(mrb, str, ptr) #define mrb_str_buf_cat(mrb, str, ptr, len) mrb_str_cat(mrb, str, ptr, len) diff --git a/include/mruby/value.h b/include/mruby/value.h index 0446e772c..4d47d30ff 100644 --- a/include/mruby/value.h +++ b/include/mruby/value.h @@ -180,7 +180,6 @@ typedef void mrb_value; #define mrb_cptr_p(o) (mrb_type(o) == MRB_TT_CPTR) #define mrb_exception_p(o) (mrb_type(o) == MRB_TT_EXCEPTION) #define mrb_test(o) mrb_bool(o) -MRB_API mrb_bool mrb_regexp_p(struct mrb_state*, mrb_value); /* * Returns a float in Ruby. diff --git a/src/etc.c b/src/etc.c index d15b398dd..ac1540f92 100644 --- a/src/etc.c +++ b/src/etc.c @@ -194,22 +194,6 @@ mrb_word_boxing_cptr_value(mrb_state *mrb, void *p) } #endif /* MRB_WORD_BOXING */ -MRB_API mrb_bool -mrb_regexp_p(mrb_state *mrb, mrb_value v) -{ - if (mrb->flags & MRB_STATE_NO_REGEXP) { - return FALSE; - } - if ((mrb->flags & MRB_STATE_REGEXP) || mrb_class_defined(mrb, REGEXP_CLASS)) { - mrb->flags |= MRB_STATE_REGEXP; - return mrb_obj_is_kind_of(mrb, v, mrb_class_get(mrb, REGEXP_CLASS)); - } - else { - mrb->flags |= MRB_STATE_NO_REGEXP; - } - return FALSE; -} - #if defined _MSC_VER && _MSC_VER < 1900 #ifndef va_copy diff --git a/src/string.c b/src/string.c index f7a805a94..89ab59d4b 100644 --- a/src/string.c +++ b/src/string.c @@ -997,20 +997,6 @@ mrb_string_value_len(mrb_state *mrb, mrb_value ptr) return RSTRING_LEN(ptr); } -void -mrb_noregexp(mrb_state *mrb, mrb_value self) -{ - mrb_raise(mrb, E_NOTIMP_ERROR, "Regexp class not implemented"); -} - -void -mrb_regexp_check(mrb_state *mrb, mrb_value obj) -{ - if (mrb_regexp_p(mrb, obj)) { - mrb_noregexp(mrb, obj); - } -} - MRB_API mrb_value mrb_str_dup(mrb_state *mrb, mrb_value str) { @@ -1026,7 +1012,6 @@ mrb_str_aref(mrb_state *mrb, mrb_value str, mrb_value indx) { mrb_int idx; - mrb_regexp_check(mrb, indx); switch (mrb_type(indx)) { case MRB_TT_FIXNUM: idx = mrb_fixnum(indx); @@ -1119,7 +1104,6 @@ mrb_str_aref_m(mrb_state *mrb, mrb_value str) if (argc == 2) { mrb_int n1, n2; - mrb_regexp_check(mrb, a1); mrb_get_args(mrb, "ii", &n1, &n2); return str_substr(mrb, str, n1, n2); } @@ -1549,7 +1533,6 @@ mrb_str_index_m(mrb_state *mrb, mrb_value str) else sub = mrb_nil_value(); } - mrb_regexp_check(mrb, sub); clen = RSTRING_CHAR_LEN(str); if (pos < 0) { pos += clen; @@ -1801,7 +1784,6 @@ mrb_str_rindex(mrb_state *mrb, mrb_value str) if (pos < 0) { pos += len; if (pos < 0) { - mrb_regexp_check(mrb, sub); return mrb_nil_value(); } } @@ -1815,7 +1797,6 @@ mrb_str_rindex(mrb_state *mrb, mrb_value str) sub = mrb_nil_value(); } pos = chars2bytes(str, 0, pos); - mrb_regexp_check(mrb, sub); switch (mrb_type(sub)) { default: { @@ -1909,16 +1890,11 @@ mrb_str_split_m(mrb_state *mrb, mrb_value str) if (argc == 0 || mrb_nil_p(spat)) { split_type = awk; } - else { - if (mrb_string_p(spat)) { - split_type = string; - if (RSTRING_LEN(spat) == 1 && RSTRING_PTR(spat)[0] == ' ') { - split_type = awk; - } - } - else { - mrb_noregexp(mrb, str); - } + else if (!mrb_string_p(spat)) { + mrb_raise(mrb, E_TYPE_ERROR, "expected String"); + } + else if (RSTRING_LEN(spat) == 1 && RSTRING_PTR(spat)[0] == ' ') { + split_type = awk; } result = mrb_ary_new(mrb); @@ -1955,7 +1931,7 @@ mrb_str_split_m(mrb_state *mrb, mrb_value str) } } } - else if (split_type == string) { + else { /* split_type == string */ mrb_int str_len = RSTRING_LEN(str); mrb_int pat_len = RSTRING_LEN(spat); mrb_int idx = 0; @@ -1976,9 +1952,6 @@ mrb_str_split_m(mrb_state *mrb, mrb_value str) } beg = idx; } - else { - mrb_noregexp(mrb, str); - } if (RSTRING_LEN(str) > 0 && (lim_p || RSTRING_LEN(str) > beg || lim < 0)) { if (RSTRING_LEN(str) == beg) { tmp = mrb_str_new_empty(mrb, str); -- cgit v1.2.3 From 1a8f6e70b5e91dcbdf92a3b671e00cd7410c3cc1 Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Wed, 1 May 2019 15:04:08 +0900 Subject: Remove unneeded `argc` check in `mrb_str_aref_m()` --- src/string.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/string.c') diff --git a/src/string.c b/src/string.c index 89ab59d4b..90e609992 100644 --- a/src/string.c +++ b/src/string.c @@ -1107,9 +1107,6 @@ mrb_str_aref_m(mrb_state *mrb, mrb_value str) mrb_get_args(mrb, "ii", &n1, &n2); return str_substr(mrb, str, n1, n2); } - if (argc != 1) { - mrb_raisef(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (%S for 1)", mrb_fixnum_value(argc)); - } return mrb_str_aref(mrb, str, a1); } -- cgit v1.2.3 From 95a92d35c89ec9c39c97c5f948255389a129029e Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Thu, 2 May 2019 20:45:31 +0900 Subject: Unify overflow error class for conversion to integer to `RangeError` --- src/numeric.c | 2 +- src/string.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/string.c') diff --git a/src/numeric.c b/src/numeric.c index 8205e41f6..101b338de 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -1230,7 +1230,7 @@ mrb_flo_to_fixnum(mrb_state *mrb, mrb_value x) z = (mrb_int)d; } else { - mrb_raisef(mrb, E_ARGUMENT_ERROR, "number (%S) too big for integer", x); + mrb_raisef(mrb, E_RANGE_ERROR, "number (%S) too big for integer", x); } } return mrb_fixnum_value(z); diff --git a/src/string.c b/src/string.c index 89ab59d4b..955ad57ce 100644 --- a/src/string.c +++ b/src/string.c @@ -2115,7 +2115,7 @@ mrb_str_len_to_inum(mrb_state *mrb, const char *str, mrb_int len, mrb_int base, else #endif { - mrb_raisef(mrb, E_ARGUMENT_ERROR, "string (%S) too big for integer", + mrb_raisef(mrb, E_RANGE_ERROR, "string (%S) too big for integer", mrb_str_new(mrb, str, pend-str)); } } -- cgit v1.2.3 From 35943e7beb0e4fd22f2096b56817e0cf22b8cf42 Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Tue, 7 May 2019 23:01:13 +0900 Subject: Refactor `mrb_str_to_cstr` and `mrb_string_value_cstr` - Extract null byte check to function. - Avoid string allocation if null byte is included. - Use `str_new` instead of `mrb_str_dup` + `mrb_str_modify` --- mrbgems/mruby-io/test/file.rb | 3 +++ src/string.c | 42 ++++++++++++++++++++++++++---------------- 2 files changed, 29 insertions(+), 16 deletions(-) (limited to 'src/string.c') diff --git a/mrbgems/mruby-io/test/file.rb b/mrbgems/mruby-io/test/file.rb index 88ced31a6..1535ebb44 100644 --- a/mrbgems/mruby-io/test/file.rb +++ b/mrbgems/mruby-io/test/file.rb @@ -33,6 +33,7 @@ assert('File.basename') do assert_equal 'a', File.basename('/a/') assert_equal 'b', File.basename('/a/b') assert_equal 'b', File.basename('../a/b') + assert_raise(ArgumentError) { File.basename("/a/b\0") } end assert('File.dirname') do @@ -106,6 +107,8 @@ assert('File.realpath') do MRubyIOTestUtil.rmdir dir end end + + assert_raise(ArgumentError) { File.realpath("TO\0DO") } end assert("File.readlink") do diff --git a/src/string.c b/src/string.c index f043bfd5a..7fc405a2b 100644 --- a/src/string.c +++ b/src/string.c @@ -194,6 +194,15 @@ str_decref(mrb_state *mrb, mrb_shared_string *shared) } } +static void +check_null_byte(mrb_state *mrb, mrb_value str) +{ + mrb_to_str(mrb, str); + if (memchr(RSTRING_PTR(str), '\0', RSTRING_LEN(str))) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "string contains null byte"); + } +} + void mrb_gc_free_str(mrb_state *mrb, struct RString *str) { @@ -723,14 +732,8 @@ mrb_str_to_cstr(mrb_state *mrb, mrb_value str0) { struct RString *s; - if (!mrb_string_p(str0)) { - mrb_raise(mrb, E_TYPE_ERROR, "expected String"); - } - + check_null_byte(mrb, str0); s = str_new(mrb, RSTRING_PTR(str0), RSTRING_LEN(str0)); - if ((strlen(RSTR_PTR(s)) ^ RSTR_LEN(s)) != 0) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "string contains null byte"); - } return RSTR_PTR(s); } @@ -2144,20 +2147,27 @@ mrb_cstr_to_inum(mrb_state *mrb, const char *str, mrb_int base, mrb_bool badchec MRB_API const char* mrb_string_value_cstr(mrb_state *mrb, mrb_value *ptr) { - mrb_value str = mrb_to_str(mrb, *ptr); - struct RString *ps = mrb_str_ptr(str); - mrb_int len = mrb_str_strlen(mrb, ps); - char *p = RSTR_PTR(ps); + struct RString *ps; + const char *p; + mrb_int len; - if (!p || p[len] != '\0') { + check_null_byte(mrb, *ptr); + ps = mrb_str_ptr(*ptr); + p = RSTR_PTR(ps); + len = RSTR_LEN(ps); + if (p[len] == '\0') { + return p; + } + else { if (MRB_FROZEN_P(ps)) { - *ptr = str = mrb_str_dup(mrb, str); - ps = mrb_str_ptr(str); + ps = str_new(mrb, p, len); + *ptr = mrb_obj_value(ps); + } + else { + mrb_str_modify(mrb, ps); } - mrb_str_modify(mrb, ps); return RSTR_PTR(ps); } - return p; } MRB_API mrb_value -- cgit v1.2.3 From 1975dedb214b9d181630c337374702a1b4725288 Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Wed, 8 May 2019 20:35:03 +0900 Subject: Use `mrb_string_value_cstr` in `mrb_str_to_dbl` --- mrbgems/mruby-kernel-ext/test/kernel.rb | 2 ++ src/string.c | 17 +---------------- 2 files changed, 3 insertions(+), 16 deletions(-) (limited to 'src/string.c') diff --git a/mrbgems/mruby-kernel-ext/test/kernel.rb b/mrbgems/mruby-kernel-ext/test/kernel.rb index 28f089007..ad9177165 100644 --- a/mrbgems/mruby-kernel-ext/test/kernel.rb +++ b/mrbgems/mruby-kernel-ext/test/kernel.rb @@ -65,6 +65,8 @@ assert('Kernel#Float') do assert_equal(123.456, Float(123.456)) assert_equal(123.456, Float("123.456")) assert_raise(TypeError) { Float(nil) } + assert_raise(ArgumentError) { Float("1.5a") } + assert_raise(ArgumentError) { Float("1.5\0") } end assert('Kernel#String') do diff --git a/src/string.c b/src/string.c index 7fc405a2b..578e3bdcc 100644 --- a/src/string.c +++ b/src/string.c @@ -2281,22 +2281,7 @@ bad: MRB_API double mrb_str_to_dbl(mrb_state *mrb, mrb_value str, mrb_bool badcheck) { - char *s; - mrb_int len; - - mrb_to_str(mrb, str); - s = RSTRING_PTR(str); - len = RSTRING_LEN(str); - if (s) { - if (badcheck && memchr(s, '\0', len)) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "string for Float contains null byte"); - } - if (s[len]) { /* no sentinel somehow */ - struct RString *temp_str = str_new(mrb, s, len); - s = RSTR_PTR(temp_str); - } - } - return mrb_cstr_to_dbl(mrb, s, badcheck); + return mrb_cstr_to_dbl(mrb, mrb_string_value_cstr(mrb, &str), badcheck); } /* 15.2.10.5.39 */ -- cgit v1.2.3 From 56e0e1934d4ec751d83f9f54ce93ca74b0e21194 Mon Sep 17 00:00:00 2001 From: dearblue Date: Sat, 25 May 2019 12:12:21 +0900 Subject: Name the return value of `mrb_range_beg_len()` --- include/mruby/range.h | 8 +++++++- mrbgems/mruby-array-ext/src/array.c | 2 +- mrbgems/mruby-kernel-ext/src/kernel.c | 2 +- mrbgems/mruby-string-ext/src/string.c | 6 +++--- src/array.c | 8 ++++---- src/range.c | 12 ++++++------ src/string.c | 4 ++-- 7 files changed, 24 insertions(+), 18 deletions(-) (limited to 'src/string.c') diff --git a/include/mruby/range.h b/include/mruby/range.h index b5626993a..ee6eb8d1d 100644 --- a/include/mruby/range.h +++ b/include/mruby/range.h @@ -64,7 +64,13 @@ MRB_API struct RRange* mrb_range_ptr(mrb_state *mrb, mrb_value range); */ MRB_API mrb_value mrb_range_new(mrb_state *mrb, mrb_value start, mrb_value end, mrb_bool exclude); -MRB_API mrb_int mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len, mrb_bool trunc); +enum mrb_range_beg_len { + MRB_RANGE_TYPE_MISMATCH = 0, /* (failure) not range */ + MRB_RANGE_OK = 1, /* (success) range */ + MRB_RANGE_OUT = 2 /* (failure) out of range */ +}; + +MRB_API enum mrb_range_beg_len mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len, mrb_bool trunc); mrb_value mrb_get_values_at(mrb_state *mrb, mrb_value obj, mrb_int olen, mrb_int argc, const mrb_value *argv, mrb_value (*func)(mrb_state*, mrb_value, mrb_int)); void mrb_gc_mark_range(mrb_state *mrb, struct RRange *r); diff --git a/mrbgems/mruby-array-ext/src/array.c b/mrbgems/mruby-array-ext/src/array.c index b6d9c9c80..20c771a97 100644 --- a/mrbgems/mruby-array-ext/src/array.c +++ b/mrbgems/mruby-array-ext/src/array.c @@ -145,7 +145,7 @@ mrb_ary_slice_bang(mrb_state *mrb, mrb_value self) mrb_get_args(mrb, "o|i", &index, &len); switch (mrb_type(index)) { case MRB_TT_RANGE: - if (mrb_range_beg_len(mrb, index, &i, &len, ARY_LEN(a), TRUE) == 1) { + if (mrb_range_beg_len(mrb, index, &i, &len, ARY_LEN(a), TRUE) == MRB_RANGE_OK) { goto delete_pos_len; } else { diff --git a/mrbgems/mruby-kernel-ext/src/kernel.c b/mrbgems/mruby-kernel-ext/src/kernel.c index 9288b0e6f..8e7e03c56 100644 --- a/mrbgems/mruby-kernel-ext/src/kernel.c +++ b/mrbgems/mruby-kernel-ext/src/kernel.c @@ -22,7 +22,7 @@ mrb_f_caller(mrb_state *mrb, mrb_value self) case 1: if (mrb_type(v) == MRB_TT_RANGE) { mrb_int beg, len; - if (mrb_range_beg_len(mrb, v, &beg, &len, bt_len, TRUE) == 1) { + if (mrb_range_beg_len(mrb, v, &beg, &len, bt_len, TRUE) == MRB_RANGE_OK) { lev = beg; n = len; } diff --git a/mrbgems/mruby-string-ext/src/string.c b/mrbgems/mruby-string-ext/src/string.c index ba7e3c610..85180516c 100644 --- a/mrbgems/mruby-string-ext/src/string.c +++ b/mrbgems/mruby-string-ext/src/string.c @@ -58,11 +58,11 @@ mrb_str_byteslice(mrb_state *mrb, mrb_value str) len = RSTRING_LEN(str); switch (mrb_range_beg_len(mrb, a1, &beg, &len, len, TRUE)) { - case 0: /* not range */ + case MRB_RANGE_TYPE_MISMATCH: break; - case 1: /* range */ + case MRB_RANGE_OK: return mrb_str_substr(mrb, str, beg, len); - case 2: /* out of range */ + case MRB_RANGE_OUT: mrb_raisef(mrb, E_RANGE_ERROR, "%S out of range", a1); break; } diff --git a/src/array.c b/src/array.c index d4302cb22..bd9b4d358 100644 --- a/src/array.c +++ b/src/array.c @@ -858,7 +858,7 @@ mrb_ary_aget(mrb_state *mrb, mrb_value self) switch (mrb_type(index)) { /* a[n..m] */ case MRB_TT_RANGE: - if (mrb_range_beg_len(mrb, index, &i, &len, ARY_LEN(a), TRUE) == 1) { + if (mrb_range_beg_len(mrb, index, &i, &len, ARY_LEN(a), TRUE) == MRB_RANGE_OK) { return ary_subseq(mrb, a, i, len); } else { @@ -927,13 +927,13 @@ mrb_ary_aset(mrb_state *mrb, mrb_value self) if (mrb_get_args(mrb, "oo|o", &v1, &v2, &v3) == 2) { /* a[n..m] = v */ switch (mrb_range_beg_len(mrb, v1, &i, &len, RARRAY_LEN(self), FALSE)) { - case 0: /* not range */ + case MRB_RANGE_TYPE_MISMATCH: mrb_ary_set(mrb, self, aget_index(mrb, v1), v2); break; - case 1: /* range */ + case MRB_RANGE_OK: mrb_ary_splice(mrb, self, i, len, v2); break; - case 2: /* out of range */ + case MRB_RANGE_OUT: mrb_raisef(mrb, E_RANGE_ERROR, "%S out of range", v1); break; } diff --git a/src/range.c b/src/range.c index 21771c8ec..9036ef093 100644 --- a/src/range.c +++ b/src/range.c @@ -352,7 +352,7 @@ mrb_get_values_at(mrb_state *mrb, mrb_value obj, mrb_int olen, mrb_int argc, con if (mrb_fixnum_p(argv[i])) { mrb_ary_push(mrb, result, func(mrb, obj, mrb_fixnum(argv[i]))); } - else if (mrb_range_beg_len(mrb, argv[i], &beg, &len, olen, FALSE) == 1) { + else if (mrb_range_beg_len(mrb, argv[i], &beg, &len, olen, FALSE) == MRB_RANGE_OK) { mrb_int const end = olen < beg + len ? olen : beg + len; for (j = beg; j < end; ++j) { mrb_ary_push(mrb, result, func(mrb, obj, j)); @@ -398,13 +398,13 @@ mrb_range_new(mrb_state *mrb, mrb_value beg, mrb_value end, mrb_bool excl) return mrb_range_value(r); } -MRB_API mrb_int +MRB_API enum mrb_range_beg_len mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len, mrb_bool trunc) { mrb_int beg, end; struct RRange *r; - if (mrb_type(range) != MRB_TT_RANGE) return 0; + if (mrb_type(range) != MRB_TT_RANGE) return MRB_RANGE_TYPE_MISMATCH; r = mrb_range_ptr(mrb, range); beg = mrb_int(mrb, RANGE_BEG(r)); @@ -412,11 +412,11 @@ mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, if (beg < 0) { beg += len; - if (beg < 0) return 2; + if (beg < 0) return MRB_RANGE_OUT; } if (trunc) { - if (beg > len) return 2; + if (beg > len) return MRB_RANGE_OUT; if (end > len) end = len; } @@ -427,7 +427,7 @@ mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, *begp = beg; *lenp = len; - return 1; + return MRB_RANGE_OK; } void diff --git a/src/string.c b/src/string.c index 578e3bdcc..db2d73e32 100644 --- a/src/string.c +++ b/src/string.c @@ -1041,9 +1041,9 @@ num_index: len = RSTRING_CHAR_LEN(str); switch (mrb_range_beg_len(mrb, indx, &beg, &len, len, TRUE)) { - case 1: + case MRB_RANGE_OK: return str_subseq(mrb, str, beg, len); - case 2: + case MRB_RANGE_OUT: return mrb_nil_value(); default: break; -- cgit v1.2.3 From ecfca8def78043f891bcbe6bc1eb036048996169 Mon Sep 17 00:00:00 2001 From: dearblue Date: Sat, 25 May 2019 22:24:08 +0900 Subject: Fix double rounded by negative index - Before patched: ``` $ mruby -e 'p (-12..-1).map { |i| "Hello"[i] }.join' "HelloHello" ``` - After patched: ``` $ mruby -e 'p (-12..-1).map { |i| "Hello"[i] }.join' "Hello" ``` --- src/string.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/string.c') diff --git a/src/string.c b/src/string.c index db2d73e32..bfe73b359 100644 --- a/src/string.c +++ b/src/string.c @@ -449,9 +449,6 @@ str_substr(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len) if (clen == 0) { len = 0; } - else if (beg < 0) { - beg = clen + beg; - } if (beg > clen) return mrb_nil_value(); if (beg < 0) { beg += clen; -- cgit v1.2.3 From 758353902940e43530dbbbab0d9ce6ded5884923 Mon Sep 17 00:00:00 2001 From: dearblue Date: Sat, 22 Jun 2019 16:48:22 +0900 Subject: Fix potential overflow in `utf8len()` For example on 32 bit mode, when `p = 0xfffffffd`, `e = 0xfffffffe` and `len = 4`, the sum of `p` and `len` can be to `1`, and comparison with `e` will to be false. As a result, a segmentation fault occurs by referring to address 0. --- src/string.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/string.c') diff --git a/src/string.c b/src/string.c index bfe73b359..ed58c484b 100644 --- a/src/string.c +++ b/src/string.c @@ -234,7 +234,7 @@ utf8len(const char* p, const char* e) mrb_int i; len = utf8len_codepage[(unsigned char)*p]; - if (p + len > e) return 1; + if (len > e - p) return 1; for (i = 1; i < len; ++i) if ((p[i] & 0xc0) != 0x80) return 1; -- cgit v1.2.3 From 7c6d6effaea6ec3cbac01cffc4f094744d53d8b9 Mon Sep 17 00:00:00 2001 From: dearblue Date: Sat, 22 Jun 2019 16:30:36 +0900 Subject: Replacement to function for string reversing --- src/string.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'src/string.c') diff --git a/src/string.c b/src/string.c index bfe73b359..282f8d776 100644 --- a/src/string.c +++ b/src/string.c @@ -1671,6 +1671,18 @@ mrb_ptr_to_str(mrb_state *mrb, void *p) return mrb_obj_value(p_str); } +static inline void +str_reverse(char *p, char *e) +{ + char c; + + while (p < e) { + c = *p; + *p++ = *e; + *e-- = c; + } +} + /* 15.2.10.5.30 */ /* * call-seq: @@ -1714,17 +1726,12 @@ mrb_str_reverse_bang(mrb_state *mrb, mrb_value str) { struct RString *s = mrb_str_ptr(str); char *p, *e; - char c; mrb_str_modify(mrb, s); if (RSTR_LEN(s) > 1) { p = RSTR_PTR(s); e = p + RSTR_LEN(s) - 1; - while (p < e) { - c = *p; - *p++ = *e; - *e-- = c; - } + str_reverse(p, e); } return str; } -- cgit v1.2.3 From bd2c93c2dfbb944f57b10b7b9c056caf852a5053 Mon Sep 17 00:00:00 2001 From: dearblue Date: Sat, 22 Jun 2019 16:32:17 +0900 Subject: Change to UTF-8 string reversing with in place MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reverses UTF-8 strings without allocated heap for working memory. 1. String before reversing: ``` "!yburmの界世" # byte unit [33, 121, 98, 117, 114, 109, 227, 129, 174, 231, 149, 140, 228, 184, 150] ``` 2. Reverse the byte order of each character: ``` [33, 121, 98, 117, 114, 109, 174, 129, 227, 140, 149, 231, 150, 184, 228] ``` 3. Reverse the whole byte order and complete: ``` [228, 184, 150, 231, 149, 140, 227, 129, 174, 109, 114, 117, 98, 121, 33] # string "世界のmruby!" ``` --- src/string.c | 28 ++++++++-------------------- 1 file changed, 8 insertions(+), 20 deletions(-) (limited to 'src/string.c') diff --git a/src/string.c b/src/string.c index 282f8d776..6d01b773c 100644 --- a/src/string.c +++ b/src/string.c @@ -1693,40 +1693,28 @@ str_reverse(char *p, char *e) static mrb_value mrb_str_reverse_bang(mrb_state *mrb, mrb_value str) { + struct RString *s = mrb_str_ptr(str); + char *p, *e; + #ifdef MRB_UTF8_STRING mrb_int utf8_len = RSTRING_CHAR_LEN(str); - mrb_int len = RSTRING_LEN(str); + mrb_int len = RSTR_LEN(s); if (utf8_len == len) goto bytes; if (utf8_len > 1) { - char *buf; - char *p, *e, *r; - - mrb_str_modify(mrb, mrb_str_ptr(str)); - len = RSTRING_LEN(str); - buf = (char*)mrb_malloc(mrb, (size_t)len); - p = buf; - e = buf + len; - - memcpy(buf, RSTRING_PTR(str), len); - r = RSTRING_PTR(str) + len; - + mrb_str_modify(mrb, s); + p = RSTR_PTR(s); + e = p + RSTR_LEN(s); while (p 1) { p = RSTR_PTR(s); -- cgit v1.2.3 From 567075aab939dd262e816832195cb11594abade9 Mon Sep 17 00:00:00 2001 From: dearblue Date: Sat, 22 Jun 2019 22:58:18 +0900 Subject: Fix string brakes for one UTF-8 charactor --- src/string.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src/string.c') diff --git a/src/string.c b/src/string.c index 6d01b773c..a35262eb4 100644 --- a/src/string.c +++ b/src/string.c @@ -1700,8 +1700,8 @@ mrb_str_reverse_bang(mrb_state *mrb, mrb_value str) mrb_int utf8_len = RSTRING_CHAR_LEN(str); mrb_int len = RSTR_LEN(s); - if (utf8_len == len) goto bytes; - if (utf8_len > 1) { + if (utf8_len < 2) return str; + if (utf8_len < len) { mrb_str_modify(mrb, s); p = RSTR_PTR(s); e = p + RSTR_LEN(s); @@ -1711,8 +1711,6 @@ mrb_str_reverse_bang(mrb_state *mrb, mrb_value str) p += clen; } } - - bytes: #endif { mrb_str_modify(mrb, s); -- cgit v1.2.3 From ec03e3f54af55af8c461a19b2f7cf0a984282997 Mon Sep 17 00:00:00 2001 From: dearblue Date: Sat, 22 Jun 2019 23:02:29 +0900 Subject: Delete the unnecessary block brace in `mrb_str_reverse_bang` --- src/string.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'src/string.c') diff --git a/src/string.c b/src/string.c index a35262eb4..2cfdc337e 100644 --- a/src/string.c +++ b/src/string.c @@ -1712,15 +1712,14 @@ mrb_str_reverse_bang(mrb_state *mrb, mrb_value str) } } #endif - { - mrb_str_modify(mrb, s); - if (RSTR_LEN(s) > 1) { - p = RSTR_PTR(s); - e = p + RSTR_LEN(s) - 1; - str_reverse(p, e); - } - return str; + + mrb_str_modify(mrb, s); + if (RSTR_LEN(s) > 1) { + p = RSTR_PTR(s); + e = p + RSTR_LEN(s) - 1; + str_reverse(p, e); } + return str; } /* ---------------------------------- */ -- cgit v1.2.3 From 11e09dc5dbd6ddaabf145bbee62741f4191eca79 Mon Sep 17 00:00:00 2001 From: dearblue Date: Sat, 22 Jun 2019 23:09:36 +0900 Subject: Fix the unnecessary `mrb_str_modify()` call Now to be calls `mrb_str_modify()` only once when 2 or more characters. --- src/string.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/string.c') diff --git a/src/string.c b/src/string.c index 2cfdc337e..2d9d176d4 100644 --- a/src/string.c +++ b/src/string.c @@ -1710,11 +1710,13 @@ mrb_str_reverse_bang(mrb_state *mrb, mrb_value str) str_reverse(p, p + clen - 1); p += clen; } + goto bytes; } #endif - mrb_str_modify(mrb, s); if (RSTR_LEN(s) > 1) { + mrb_str_modify(mrb, s); + bytes: p = RSTR_PTR(s); e = p + RSTR_LEN(s) - 1; str_reverse(p, e); -- cgit v1.2.3 From dc21024ec795bcfcd3018825fa3c272731439a7e Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 25 Jun 2019 18:05:33 +0900 Subject: Fix `mrb_str_to_str()` to handle symbols. --- src/string.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/string.c') diff --git a/src/string.c b/src/string.c index ed58c484b..856e908af 100644 --- a/src/string.c +++ b/src/string.c @@ -973,6 +973,8 @@ mrb_str_to_str(mrb_state *mrb, mrb_value str) switch (mrb_type(str)) { case MRB_TT_STRING: return str; + case MRB_TT_SYMBOL: + return mrb_sym2str(mrb, mrb_symbol(str)); case MRB_TT_FIXNUM: return mrb_fixnum_to_str(mrb, str, 10); case MRB_TT_CLASS: -- cgit v1.2.3 From 75df13a97334c162b2cf743c3e37c4933a4b0d1c Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Tue, 25 Jun 2019 22:58:21 +0900 Subject: Fix `String#byteslice` with `MRB_UTF8_STRING` and some edge cases MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Example: $ bin/mruby -e ' p "あa".byteslice(1) p "bar".byteslice(3) p "bar".byteslice(4..0) ' Before this patch: "a" "" RangeError (4..0 out of range) After this patch (same as Ruby): "\x81" nil nil --- include/mruby/string.h | 3 ++ mrbgems/mruby-string-ext/src/string.c | 58 +++++++++++++-------------------- mrbgems/mruby-string-ext/test/string.rb | 51 +++++++++++++++++++++++++++++ src/string.c | 49 ++++++++++++++-------------- 4 files changed, 102 insertions(+), 59 deletions(-) (limited to 'src/string.c') diff --git a/include/mruby/string.h b/include/mruby/string.h index 22445f654..b563541cb 100644 --- a/include/mruby/string.h +++ b/include/mruby/string.h @@ -438,6 +438,9 @@ mrb_value mrb_str_inspect(mrb_state *mrb, mrb_value str); #define mrb_str_buf_cat(mrb, str, ptr, len) mrb_str_cat(mrb, str, ptr, len) #define mrb_str_buf_append(mrb, str, str2) mrb_str_cat_str(mrb, str, str2) +mrb_bool mrb_str_beg_len(mrb_int str_len, mrb_int *begp, mrb_int *lenp); +mrb_value mrb_str_byte_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len); + #ifdef MRB_UTF8_STRING mrb_int mrb_utf8_len(const char *str, mrb_int byte_len); #endif diff --git a/mrbgems/mruby-string-ext/src/string.c b/mrbgems/mruby-string-ext/src/string.c index d9ebb7392..50a4e5582 100644 --- a/mrbgems/mruby-string-ext/src/string.c +++ b/mrbgems/mruby-string-ext/src/string.c @@ -42,44 +42,32 @@ mrb_str_setbyte(mrb_state *mrb, mrb_value str) static mrb_value mrb_str_byteslice(mrb_state *mrb, mrb_value str) { - mrb_value a1; - mrb_int len; - - if (mrb_get_argc(mrb) == 2) { - mrb_int pos; - mrb_get_args(mrb, "ii", &pos, &len); - return mrb_str_substr(mrb, str, pos, len); + mrb_value a1, a2; + mrb_int str_len = RSTRING_LEN(str), beg, len; + mrb_bool empty = TRUE; + + if (mrb_get_args(mrb, "o|o", &a1, &a2) == 2) { + beg = mrb_fixnum(mrb_to_int(mrb, a1)); + len = mrb_fixnum(mrb_to_int(mrb, a2)); + goto subseq; } - mrb_get_args(mrb, "o|i", &a1, &len); - switch (mrb_type(a1)) { - case MRB_TT_RANGE: - { - mrb_int beg; - - len = RSTRING_LEN(str); - switch (mrb_range_beg_len(mrb, a1, &beg, &len, len, TRUE)) { - case MRB_RANGE_TYPE_MISMATCH: - break; - case MRB_RANGE_OK: - return mrb_str_substr(mrb, str, beg, len); - case MRB_RANGE_OUT: - mrb_raisef(mrb, E_RANGE_ERROR, "%S out of range", a1); - break; - } - return mrb_nil_value(); + if (mrb_type(a1) == MRB_TT_RANGE) { + if (mrb_range_beg_len(mrb, a1, &beg, &len, str_len, TRUE) == MRB_RANGE_OK) { + goto subseq; } -#ifndef MRB_WITHOUT_FLOAT - case MRB_TT_FLOAT: - a1 = mrb_fixnum_value((mrb_int)mrb_float(a1)); - /* fall through */ -#endif - case MRB_TT_FIXNUM: - return mrb_str_substr(mrb, str, mrb_fixnum(a1), 1); - default: - mrb_raise(mrb, E_TYPE_ERROR, "wrong type of argument"); + return mrb_nil_value(); + } + + beg = mrb_fixnum(mrb_to_int(mrb, a1)); + len = 1; + empty = FALSE; +subseq: + if (mrb_str_beg_len(str_len, &beg, &len) && (empty || len != 0)) { + return mrb_str_byte_subseq(mrb, str, beg, len); + } + else { + return mrb_nil_value(); } - /* not reached */ - return mrb_nil_value(); } /* diff --git a/mrbgems/mruby-string-ext/test/string.rb b/mrbgems/mruby-string-ext/test/string.rb index 02777e594..bf633bcef 100644 --- a/mrbgems/mruby-string-ext/test/string.rb +++ b/mrbgems/mruby-string-ext/test/string.rb @@ -26,10 +26,61 @@ end assert('String#byteslice') do str1 = "hello" + str2 = "\u3042ab" # "\xE3\x81\x82ab" + + assert_equal("h", str1.byteslice(0)) assert_equal("e", str1.byteslice(1)) + assert_equal(nil, str1.byteslice(5)) assert_equal("o", str1.byteslice(-1)) + assert_equal(nil, str1.byteslice(-6)) + assert_equal("\xE3", str2.byteslice(0)) + assert_equal("\x81", str2.byteslice(1)) + assert_equal(nil, str2.byteslice(5)) + assert_equal("b", str2.byteslice(-1)) + assert_equal(nil, str2.byteslice(-6)) + + assert_equal("", str1.byteslice(0, 0)) + assert_equal(str1, str1.byteslice(0, 6)) + assert_equal("el", str1.byteslice(1, 2)) + assert_equal("", str1.byteslice(5, 1)) + assert_equal("o", str1.byteslice(-1, 6)) + assert_equal(nil, str1.byteslice(-6, 1)) + assert_equal(nil, str1.byteslice(0, -1)) + assert_equal("", str2.byteslice(0, 0)) + assert_equal(str2, str2.byteslice(0, 6)) + assert_equal("\x81\x82", str2.byteslice(1, 2)) + assert_equal("", str2.byteslice(5, 1)) + assert_equal("b", str2.byteslice(-1, 6)) + assert_equal(nil, str2.byteslice(-6, 1)) + assert_equal(nil, str2.byteslice(0, -1)) + assert_equal("ell", str1.byteslice(1..3)) assert_equal("el", str1.byteslice(1...3)) + assert_equal("h", str1.byteslice(0..0)) + assert_equal("", str1.byteslice(5..0)) + assert_equal("o", str1.byteslice(4..5)) + assert_equal(nil, str1.byteslice(6..0)) + assert_equal("", str1.byteslice(-1..0)) + assert_equal("llo", str1.byteslice(-3..5)) + assert_equal("\x81\x82a", str2.byteslice(1..3)) + assert_equal("\x81\x82", str2.byteslice(1...3)) + assert_equal("\xE3", str2.byteslice(0..0)) + assert_equal("", str2.byteslice(5..0)) + assert_equal("b", str2.byteslice(4..5)) + assert_equal(nil, str2.byteslice(6..0)) + assert_equal("", str2.byteslice(-1..0)) + assert_equal("\x82ab", str2.byteslice(-3..5)) + + assert_raise(ArgumentError) { str1.byteslice } + assert_raise(ArgumentError) { str1.byteslice(1, 2, 3) } + assert_raise(TypeError) { str1.byteslice("1") } + assert_raise(TypeError) { str1.byteslice("1", 2) } + assert_raise(TypeError) { str1.byteslice(1, "2") } + assert_raise(TypeError) { str1.byteslice(1..2, 3) } + + skip unless Object.const_defined?(:Float) + assert_equal("o", str1.byteslice(4.0)) + assert_equal("\x82ab", str2.byteslice(2.0, 3.0)) end assert('String#dump') do diff --git a/src/string.c b/src/string.c index ed58c484b..f5fb936a6 100644 --- a/src/string.c +++ b/src/string.c @@ -410,8 +410,8 @@ str_make_shared(mrb_state *mrb, struct RString *orig, struct RString *s) } } -static mrb_value -byte_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len) +mrb_value +mrb_str_byte_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len) { struct RString *orig, *s; @@ -434,32 +434,33 @@ str_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len) beg = chars2bytes(str, 0, beg); len = chars2bytes(str, beg, len); - return byte_subseq(mrb, str, beg, len); + return mrb_str_byte_subseq(mrb, str, beg, len); } #else -#define str_subseq(mrb, str, beg, len) byte_subseq(mrb, str, beg, len) +#define str_subseq(mrb, str, beg, len) mrb_str_byte_subseq(mrb, str, beg, len) #endif -static mrb_value -str_substr(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len) +mrb_bool +mrb_str_beg_len(mrb_int str_len, mrb_int *begp, mrb_int *lenp) { - mrb_int clen = RSTRING_CHAR_LEN(str); - - if (len < 0) return mrb_nil_value(); - if (clen == 0) { - len = 0; + if (str_len < *begp || *lenp < 0) return FALSE; + if (*begp < 0) { + *begp += str_len; + if (*begp < 0) return FALSE; } - if (beg > clen) return mrb_nil_value(); - if (beg < 0) { - beg += clen; - if (beg < 0) return mrb_nil_value(); + if (*lenp > str_len - *begp) + *lenp = str_len - *begp; + if (*lenp <= 0) { + *lenp = 0; } - if (len > clen - beg) - len = clen - beg; - if (len <= 0) { - len = 0; - } - return str_subseq(mrb, str, beg, len); + return TRUE; +} + +static mrb_value +str_substr(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len) +{ + return mrb_str_beg_len(RSTRING_CHAR_LEN(str), &beg, &len) ? + str_subseq(mrb, str, beg, len) : mrb_nil_value(); } MRB_API mrb_int @@ -1917,7 +1918,7 @@ mrb_str_split_m(mrb_state *mrb, mrb_value str) } } else if (ISSPACE(c)) { - mrb_ary_push(mrb, result, byte_subseq(mrb, str, beg, end-beg)); + mrb_ary_push(mrb, result, mrb_str_byte_subseq(mrb, str, beg, end-beg)); mrb_gc_arena_restore(mrb, ai); skip = TRUE; beg = idx; @@ -1942,7 +1943,7 @@ mrb_str_split_m(mrb_state *mrb, mrb_value str) else { end = chars2bytes(str, idx, 1); } - mrb_ary_push(mrb, result, byte_subseq(mrb, str, idx, end)); + mrb_ary_push(mrb, result, mrb_str_byte_subseq(mrb, str, idx, end)); mrb_gc_arena_restore(mrb, ai); idx += end + pat_len; if (lim_p && lim <= ++i) break; @@ -1954,7 +1955,7 @@ mrb_str_split_m(mrb_state *mrb, mrb_value str) tmp = mrb_str_new_empty(mrb, str); } else { - tmp = byte_subseq(mrb, str, beg, RSTRING_LEN(str)-beg); + tmp = mrb_str_byte_subseq(mrb, str, beg, RSTRING_LEN(str)-beg); } mrb_ary_push(mrb, result, tmp); } -- cgit v1.2.3 From 28c510cf41767ee40dbea9b0b1f165a28da956d1 Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Wed, 26 Jun 2019 15:38:20 +0900 Subject: Silence unused label warnings from gcc; ref #4524 mruby/mruby/src/string.c:1722:4: warning: label 'bytes' defined but not used [-Wunused-label] bytes: ^~~~~ --- src/string.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'src/string.c') diff --git a/src/string.c b/src/string.c index b980ee760..c8a9e61ec 100644 --- a/src/string.c +++ b/src/string.c @@ -1719,12 +1719,15 @@ mrb_str_reverse_bang(mrb_state *mrb, mrb_value str) if (RSTR_LEN(s) > 1) { mrb_str_modify(mrb, s); - bytes: - p = RSTR_PTR(s); - e = p + RSTR_LEN(s) - 1; - str_reverse(p, e); + goto bytes; } return str; + + bytes: + p = RSTR_PTR(s); + e = p + RSTR_LEN(s) - 1; + str_reverse(p, e); + return str; } /* ---------------------------------- */ -- cgit v1.2.3 From 0d452073f46fc46496200db610ce785e514cdb65 Mon Sep 17 00:00:00 2001 From: dearblue Date: Tue, 21 May 2019 22:02:11 +0900 Subject: Replace `String#[]=` method by C implements The purpose is to eliminate string objects that are temporarily created during processing. --- mrblib/string.rb | 54 ----------------- src/string.c | 176 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 173 insertions(+), 57 deletions(-) (limited to 'src/string.c') diff --git a/mrblib/string.rb b/mrblib/string.rb index b0fe4033e..c26cdb1e2 100644 --- a/mrblib/string.rb +++ b/mrblib/string.rb @@ -177,60 +177,6 @@ class String self end - ## - # Modify +self+ by replacing the content of +self+. - # The portion of the string affected is determined using the same criteria as +String#[]+. - def []=(*args) - anum = args.size - if anum == 2 - pos, value = args[0], args[1].__to_str - case pos - when String - posnum = self.index(pos) - if posnum - b = self[0, posnum] - a = self[(posnum + pos.length)..-1] - self.replace([b, value, a].join('')) - else - raise IndexError, "string not matched" - end - when Range - head = pos.begin - tail = pos.end - tail += self.length if tail < 0 - unless pos.exclude_end? - tail += 1 - end - return self[head, tail-head]=value - else - pos = pos.__to_int - pos += self.length if pos < 0 - if pos < 0 || pos > self.length - raise IndexError, "index #{args[0]} out of string" - end - b = self[0, pos] - a = self[pos + 1..-1] - self.replace([b, value, a].join('')) - end - return value - elsif anum == 3 - pos, len, value = args[0].__to_int, args[1].__to_int, args[2].__to_str - pos += self.length if pos < 0 - if pos < 0 || pos > self.length - raise IndexError, "index #{args[0]} out of string" - end - if len < 0 - raise IndexError, "negative length #{len}" - end - b = self[0, pos] - a = self[pos + len..-1] - self.replace([b, value, a].join('')) - return value - else - raise ArgumentError, "wrong number of arguments (#{anum} for 2..3)" - end - end - # those two methods requires Regexp that is optional in mruby ## # ISO 15.2.10.5.3 diff --git a/src/string.c b/src/string.c index c8a9e61ec..43bf8a841 100644 --- a/src/string.c +++ b/src/string.c @@ -427,13 +427,18 @@ mrb_str_byte_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len) } return mrb_obj_value(s); } + +static void +str_range_to_bytes(mrb_value str, mrb_int *pos, mrb_int *len) +{ + *pos = chars2bytes(str, 0, *pos); + *len = chars2bytes(str, *pos, *len); +} #ifdef MRB_UTF8_STRING static inline mrb_value str_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len) { - beg = chars2bytes(str, 0, beg); - len = chars2bytes(str, beg, len); - + str_range_to_bytes(str, &beg, &len); return mrb_str_byte_subseq(mrb, str, beg, len); } #else @@ -1010,6 +1015,68 @@ mrb_str_dup(mrb_state *mrb, mrb_value str) return str_replace(mrb, dup, s); } +enum str_convert_range { + /* `beg` and `len` are byte unit in `0 ... str.bytesize` */ + STR_BYTE_RANGE_CORRECTED = 1, + + /* `beg` and `len` are char unit in any range */ + STR_CHAR_RANGE = 2, + + /* `beg` and `len` are char unit in `0 ... str.size` */ + STR_CHAR_RANGE_CORRECTED = 3, + + /* `beg` is out of range */ + STR_OUT_OF_RANGE = -1 +}; + +static enum str_convert_range +str_convert_range(mrb_state *mrb, mrb_value str, mrb_value indx, mrb_value alen, mrb_int *beg, mrb_int *len) +{ + if (!mrb_undef_p(alen)) { + *beg = mrb_int(mrb, indx); + *len = mrb_int(mrb, alen); + return STR_CHAR_RANGE; + } + else { + switch (mrb_type(indx)) { + case MRB_TT_FIXNUM: + *beg = mrb_fixnum(indx); + *len = 1; + return STR_CHAR_RANGE; + + case MRB_TT_STRING: + *beg = str_index_str(mrb, str, indx, 0); + if (*beg < 0) { break; } + *len = RSTRING_LEN(indx); + return STR_BYTE_RANGE_CORRECTED; + + case MRB_TT_RANGE: + goto range_arg; + + default: + indx = mrb_to_int(mrb, indx); + if (mrb_fixnum_p(indx)) { + *beg = mrb_fixnum(indx); + *len = 1; + return STR_CHAR_RANGE; + } +range_arg: + *len = RSTRING_CHAR_LEN(str); + switch (mrb_range_beg_len(mrb, indx, beg, len, *len, TRUE)) { + case MRB_RANGE_OK: + return STR_CHAR_RANGE_CORRECTED; + case MRB_RANGE_OUT: + return STR_OUT_OF_RANGE; + default: + break; + } + + mrb_raise(mrb, E_TYPE_ERROR, "can't convert to Fixnum"); + } + } + return STR_OUT_OF_RANGE; +} + static mrb_value mrb_str_aref(mrb_state *mrb, mrb_value str, mrb_value indx) { @@ -1113,6 +1180,108 @@ mrb_str_aref_m(mrb_state *mrb, mrb_value str) return mrb_str_aref(mrb, str, a1); } +static mrb_noreturn void +str_out_of_index(mrb_state *mrb, mrb_value index) +{ + mrb_raisef(mrb, E_INDEX_ERROR, "index %S out of string", index); +} + +static mrb_value +str_replace_partial(mrb_state *mrb, mrb_value src, mrb_int pos, mrb_int end, mrb_value rep) +{ + const mrb_int shrink_threshold = 256; + struct RString *str = mrb_str_ptr(src); + mrb_int len = RSTR_LEN(str); + mrb_int replen, newlen; + char *strp; + + if (end > len) { end = len; } + + if (pos < 0 || pos > len) { + str_out_of_index(mrb, mrb_fixnum_value(pos)); + } + + replen = (mrb_nil_p(rep) ? 0 : RSTRING_LEN(rep)); + newlen = replen + len - (end - pos); + + if (newlen >= MRB_INT_MAX || newlen < replen /* overflowed */) { + mrb_raise(mrb, E_RUNTIME_ERROR, "string size too big"); + } + + mrb_str_modify(mrb, str); + + if (len < newlen || len - newlen >= shrink_threshold) { + resize_capa(mrb, str, newlen); + } + + strp = RSTR_PTR(str); + + memmove(strp + newlen - (len - end), strp + end, len - end); + if (!mrb_nil_p(rep)) { + memcpy(strp + pos, RSTRING_PTR(rep), replen); + } + RSTR_SET_LEN(str, newlen); + strp[newlen] = '\0'; + + return src; +} + +static void +mrb_str_aset(mrb_state *mrb, mrb_value str, mrb_value indx, mrb_value alen, mrb_value replace) +{ + mrb_int beg, len, charlen; + + replace = mrb_to_str(mrb, replace); + + switch (str_convert_range(mrb, str, indx, alen, &beg, &len)) { + case STR_OUT_OF_RANGE: + default: + mrb_raise(mrb, E_INDEX_ERROR, "string not matched"); + case STR_CHAR_RANGE: + if (len < 0) { + mrb_raisef(mrb, E_INDEX_ERROR, "negative length %S", alen); + } + charlen = RSTRING_CHAR_LEN(str); + if (beg < 0) { beg += charlen; } + if (beg < 0 || beg > charlen) { str_out_of_index(mrb, indx); } + /* fall through */ + case STR_CHAR_RANGE_CORRECTED: + str_range_to_bytes(str, &beg, &len); + /* fall through */ + case STR_BYTE_RANGE_CORRECTED: + str_replace_partial(mrb, str, beg, beg + len, replace); + } +} + +/* + * call-seq: + * str[fixnum] = replace + * str[fixnum, fixnum] = replace + * str[range] = replace + * str[regexp] = replace + * str[regexp, fixnum] = replace + * str[other_str] = replace + * + * Modify +self+ by replacing the content of +self+. + * The portion of the string affected is determined using the same criteria as +String#[]+. + */ +static mrb_value +mrb_str_aset_m(mrb_state *mrb, mrb_value str) +{ + mrb_value indx, alen, replace; + + switch (mrb_get_args(mrb, "oo|S!", &indx, &alen, &replace)) { + case 2: + replace = alen; + alen = mrb_undef_value(); + break; + case 3: + break; + } + mrb_str_aset(mrb, str, indx, alen, replace); + return str; +} + /* 15.2.10.5.8 */ /* * call-seq: @@ -2678,6 +2847,7 @@ mrb_init_string(mrb_state *mrb) mrb_define_method(mrb, s, "+", mrb_str_plus_m, MRB_ARGS_REQ(1)); /* 15.2.10.5.4 */ mrb_define_method(mrb, s, "*", mrb_str_times, MRB_ARGS_REQ(1)); /* 15.2.10.5.5 */ mrb_define_method(mrb, s, "[]", mrb_str_aref_m, MRB_ARGS_ANY()); /* 15.2.10.5.6 */ + mrb_define_method(mrb, s, "[]=", mrb_str_aset_m, MRB_ARGS_ANY()); mrb_define_method(mrb, s, "capitalize", mrb_str_capitalize, MRB_ARGS_NONE()); /* 15.2.10.5.7 */ mrb_define_method(mrb, s, "capitalize!", mrb_str_capitalize_bang, MRB_ARGS_NONE()); /* 15.2.10.5.8 */ mrb_define_method(mrb, s, "chomp", mrb_str_chomp, MRB_ARGS_ANY()); /* 15.2.10.5.9 */ -- cgit v1.2.3 From 0ad1cacff30c744fcf07869990cbab7bc51c4c68 Mon Sep 17 00:00:00 2001 From: dearblue Date: Thu, 27 Jun 2019 20:46:49 +0900 Subject: Simplify `mrb_str_aref_m()` and `mrb_str_aref()` It is integration with part of argument parsing used in `mrb_str_aset_m()`. --- src/string.c | 66 ++++++++++++++++++------------------------------------------ 1 file changed, 20 insertions(+), 46 deletions(-) (limited to 'src/string.c') diff --git a/src/string.c b/src/string.c index 43bf8a841..6938418fb 100644 --- a/src/string.c +++ b/src/string.c @@ -1078,50 +1078,28 @@ range_arg: } static mrb_value -mrb_str_aref(mrb_state *mrb, mrb_value str, mrb_value indx) +mrb_str_aref(mrb_state *mrb, mrb_value str, mrb_value indx, mrb_value alen) { - mrb_int idx; + mrb_int beg, len; - switch (mrb_type(indx)) { - case MRB_TT_FIXNUM: - idx = mrb_fixnum(indx); - -num_index: - str = str_substr(mrb, str, idx, 1); - if (!mrb_nil_p(str) && RSTRING_LEN(str) == 0) return mrb_nil_value(); + switch (str_convert_range(mrb, str, indx, alen, &beg, &len)) { + case STR_CHAR_RANGE_CORRECTED: + return str_subseq(mrb, str, beg, len); + case STR_CHAR_RANGE: + str = str_substr(mrb, str, beg, len); + if (mrb_undef_p(alen) && !mrb_nil_p(str) && RSTRING_LEN(str) == 0) return mrb_nil_value(); return str; - - case MRB_TT_STRING: - if (str_index_str(mrb, str, indx, 0) != -1) + case STR_BYTE_RANGE_CORRECTED: + if (mrb_string_p(indx)) { return mrb_str_dup(mrb, indx); - return mrb_nil_value(); - - case MRB_TT_RANGE: - goto range_arg; - - default: - indx = mrb_Integer(mrb, indx); - if (mrb_nil_p(indx)) { - range_arg: - { - mrb_int beg, len; - - len = RSTRING_CHAR_LEN(str); - switch (mrb_range_beg_len(mrb, indx, &beg, &len, len, TRUE)) { - case MRB_RANGE_OK: - return str_subseq(mrb, str, beg, len); - case MRB_RANGE_OUT: - return mrb_nil_value(); - default: - break; - } - } - mrb_raise(mrb, E_TYPE_ERROR, "can't convert to Fixnum"); } - idx = mrb_fixnum(indx); - goto num_index; + else { + return mrb_str_byte_subseq(mrb, str, beg, len); + } + case STR_OUT_OF_RANGE: + default: + return mrb_nil_value(); } - return mrb_nil_value(); /* not reached */ } /* 15.2.10.5.6 */ @@ -1168,16 +1146,12 @@ static mrb_value mrb_str_aref_m(mrb_state *mrb, mrb_value str) { mrb_value a1, a2; - mrb_int argc; - argc = mrb_get_args(mrb, "o|o", &a1, &a2); - if (argc == 2) { - mrb_int n1, n2; - - mrb_get_args(mrb, "ii", &n1, &n2); - return str_substr(mrb, str, n1, n2); + if (mrb_get_args(mrb, "o|o", &a1, &a2) == 1) { + a2 = mrb_undef_value(); } - return mrb_str_aref(mrb, str, a1); + + return mrb_str_aref(mrb, str, a1, a2); } static mrb_noreturn void -- cgit v1.2.3 From 2bb30481b6d6aed0f869dd089a56ebe24e8e2349 Mon Sep 17 00:00:00 2001 From: dearblue Date: Thu, 4 Jul 2019 21:49:07 +0900 Subject: Fix heap buffer overflow; ref #4549 This patch is showed in #4549. --- src/string.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/string.c') diff --git a/src/string.c b/src/string.c index 6938418fb..7a094b3a7 100644 --- a/src/string.c +++ b/src/string.c @@ -1184,7 +1184,7 @@ str_replace_partial(mrb_state *mrb, mrb_value src, mrb_int pos, mrb_int end, mrb mrb_str_modify(mrb, str); - if (len < newlen || len - newlen >= shrink_threshold) { + if (len < newlen) { resize_capa(mrb, str, newlen); } @@ -1197,6 +1197,10 @@ str_replace_partial(mrb_state *mrb, mrb_value src, mrb_int pos, mrb_int end, mrb RSTR_SET_LEN(str, newlen); strp[newlen] = '\0'; + if (len - newlen >= shrink_threshold) { + resize_capa(mrb, str, newlen); + } + return src; } -- cgit v1.2.3 From 991bdd4ed7b0aa6fd6bee4fa5c62283365dcf15d Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Thu, 4 Jul 2019 23:01:16 +0900 Subject: Rename `MRB_STR_NO_UTF` to 'MRB_STR_ASCII`; close #4550 In #4550, @shuuji proposed the name name `MRB_STR_NO_MULTI_BYTE` for more precise description. Although I agree that the name name is correct, but the flag means the string does not contain multi byte UTF-8 characters, i.e. all characters fit in the range of ASCII. --- include/mruby/string.h | 2 +- src/string.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src/string.c') diff --git a/include/mruby/string.h b/include/mruby/string.h index b563541cb..9484e20d7 100644 --- a/include/mruby/string.h +++ b/include/mruby/string.h @@ -87,7 +87,7 @@ MRB_API mrb_int mrb_str_strlen(mrb_state*, struct RString*); #define MRB_STR_FSHARED 2 #define MRB_STR_NOFREE 4 #define MRB_STR_POOL 8 -#define MRB_STR_NO_UTF 16 +#define MRB_STR_ASCII 16 #define MRB_STR_EMBED 32 #define MRB_STR_EMBED_LEN_MASK 0x7c0 #define MRB_STR_EMBED_LEN_SHIFT 6 diff --git a/src/string.c b/src/string.c index 7a094b3a7..805cf01dc 100644 --- a/src/string.c +++ b/src/string.c @@ -260,12 +260,12 @@ utf8_strlen(mrb_value str) { mrb_int byte_len = RSTRING_LEN(str); - if (RSTRING(str)->flags & MRB_STR_NO_UTF) { + if (RSTRING(str)->flags & MRB_STR_ASCII) { return byte_len; } else { mrb_int utf8_len = mrb_utf8_len(RSTRING_PTR(str), byte_len); - if (byte_len == utf8_len) RSTRING(str)->flags |= MRB_STR_NO_UTF; + if (byte_len == utf8_len) RSTRING(str)->flags |= MRB_STR_ASCII; return utf8_len; } } @@ -512,8 +512,8 @@ str_replace(mrb_state *mrb, struct RString *s1, struct RString *s2) mrb_check_frozen(mrb, s1); if (s1 == s2) return mrb_obj_value(s1); - s1->flags &= ~MRB_STR_NO_UTF; - s1->flags |= s2->flags&MRB_STR_NO_UTF; + s1->flags &= ~MRB_STR_ASCII; + s1->flags |= s2->flags&MRB_STR_ASCII; len = RSTR_LEN(s2); if (RSTR_SHARED_P(s1)) { str_decref(mrb, s1->as.heap.aux.shared); @@ -651,7 +651,7 @@ MRB_API void mrb_str_modify(mrb_state *mrb, struct RString *s) { mrb_check_frozen(mrb, s); - s->flags &= ~MRB_STR_NO_UTF; + s->flags &= ~MRB_STR_ASCII; if (RSTR_SHARED_P(s)) { mrb_shared_string *shared = s->as.heap.aux.shared; -- cgit v1.2.3 From f9bf2d9d8e2531b2bfebb5a80362b43ab559b56f Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Fri, 5 Jul 2019 20:37:59 +0900 Subject: Read/write `MRB_STR_ASCII` flag only when `MRB_UTF8_STRING` is defined --- include/mruby/string.h | 14 ++++++++++++++ src/string.c | 14 +++++++------- 2 files changed, 21 insertions(+), 7 deletions(-) (limited to 'src/string.c') diff --git a/include/mruby/string.h b/include/mruby/string.h index 9484e20d7..d648d856c 100644 --- a/include/mruby/string.h +++ b/include/mruby/string.h @@ -68,6 +68,20 @@ struct RString { #define RSTR_SET_NOFREE_FLAG(s) ((s)->flags |= MRB_STR_NOFREE) #define RSTR_UNSET_NOFREE_FLAG(s) ((s)->flags &= ~MRB_STR_NOFREE) +#ifdef MRB_UTF8_STRING +# define RSTR_ASCII_P(s) ((s)->flags & MRB_STR_ASCII) +# define RSTR_SET_ASCII_FLAG(s) ((s)->flags |= MRB_STR_ASCII) +# define RSTR_UNSET_ASCII_FLAG(s) ((s)->flags &= ~MRB_STR_ASCII) +# define RSTR_WRITE_ASCII_FLAG(s, v) (RSTR_UNSET_ASCII_FLAG(s), (s)->flags |= v) +# define RSTR_COPY_ASCII_FLAG(dst, src) RSTR_WRITE_ASCII_FLAG(dst, RSTR_ASCII_P(src)) +#else +# define RSTR_ASCII_P(s) (void)0 +# define RSTR_SET_ASCII_FLAG(s) (void)0 +# define RSTR_UNSET_ASCII_FLAG(s) (void)0 +# define RSTR_WRITE_ASCII_FLAG(s, v) (void)0 +# define RSTR_COPY_ASCII_FLAG(dst, src) (void)0 +#endif + #define RSTR_POOL_P(s) ((s)->flags & MRB_STR_POOL) #define RSTR_SET_POOL_FLAG(s) ((s)->flags |= MRB_STR_POOL) diff --git a/src/string.c b/src/string.c index 805cf01dc..078c028d8 100644 --- a/src/string.c +++ b/src/string.c @@ -258,14 +258,15 @@ mrb_utf8_len(const char *str, mrb_int byte_len) static mrb_int utf8_strlen(mrb_value str) { - mrb_int byte_len = RSTRING_LEN(str); + struct RString *s = mrb_str_ptr(str); + mrb_int byte_len = RSTR_LEN(s); - if (RSTRING(str)->flags & MRB_STR_ASCII) { + if (RSTR_ASCII_P(s)) { return byte_len; } else { - mrb_int utf8_len = mrb_utf8_len(RSTRING_PTR(str), byte_len); - if (byte_len == utf8_len) RSTRING(str)->flags |= MRB_STR_ASCII; + mrb_int utf8_len = mrb_utf8_len(RSTR_PTR(s), byte_len); + if (byte_len == utf8_len) RSTR_SET_ASCII_FLAG(s); return utf8_len; } } @@ -512,8 +513,7 @@ str_replace(mrb_state *mrb, struct RString *s1, struct RString *s2) mrb_check_frozen(mrb, s1); if (s1 == s2) return mrb_obj_value(s1); - s1->flags &= ~MRB_STR_ASCII; - s1->flags |= s2->flags&MRB_STR_ASCII; + RSTR_COPY_ASCII_FLAG(s1, s2); len = RSTR_LEN(s2); if (RSTR_SHARED_P(s1)) { str_decref(mrb, s1->as.heap.aux.shared); @@ -651,7 +651,7 @@ MRB_API void mrb_str_modify(mrb_state *mrb, struct RString *s) { mrb_check_frozen(mrb, s); - s->flags &= ~MRB_STR_ASCII; + RSTR_UNSET_ASCII_FLAG(s); if (RSTR_SHARED_P(s)) { mrb_shared_string *shared = s->as.heap.aux.shared; -- cgit v1.2.3 From 80f78ca196790e2900b89f447c5ab83433d69d89 Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Wed, 10 Jul 2019 21:53:17 +0900 Subject: Remove an unused argument of `str_with_class()` --- src/string.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/string.c') diff --git a/src/string.c b/src/string.c index 078c028d8..3ef86eb53 100644 --- a/src/string.c +++ b/src/string.c @@ -83,7 +83,7 @@ str_new(mrb_state *mrb, const char *p, size_t len) } static inline void -str_with_class(mrb_state *mrb, struct RString *s, mrb_value obj) +str_with_class(struct RString *s, mrb_value obj) { s->c = mrb_str_ptr(obj)->c; } @@ -93,7 +93,7 @@ mrb_str_new_empty(mrb_state *mrb, mrb_value str) { struct RString *s = str_new(mrb, 0, 0); - str_with_class(mrb, s, str); + str_with_class(s, str); return mrb_obj_value(s); } @@ -830,7 +830,7 @@ mrb_str_times(mrb_state *mrb, mrb_value self) len = RSTRING_LEN(self)*times; str2 = str_new(mrb, 0, len); - str_with_class(mrb, str2, self); + str_with_class(str2, self); p = RSTR_PTR(str2); if (len > 0) { n = RSTRING_LEN(self); @@ -1011,7 +1011,7 @@ mrb_str_dup(mrb_state *mrb, mrb_value str) struct RString *s = mrb_str_ptr(str); struct RString *dup = str_new(mrb, 0, 0); - str_with_class(mrb, dup, str); + str_with_class(dup, str); return str_replace(mrb, dup, s); } @@ -2561,7 +2561,7 @@ mrb_str_dump(mrb_state *mrb, mrb_value str) } result = str_new(mrb, 0, len); - str_with_class(mrb, result, str); + str_with_class(result, str); p = RSTRING_PTR(str); pend = p + RSTRING_LEN(str); q = RSTR_PTR(result); *q++ = '"'; -- cgit v1.2.3 From 8c0d9ba1a363683bbeab8cb7c22acdb07621352d Mon Sep 17 00:00:00 2001 From: dearblue Date: Thu, 11 Jul 2019 21:52:05 +0900 Subject: Improve performance `String#index` with UTF-8 Based on Boyer-Moore-Horspool algorithm (Quick Search algorithm). As a side effect, the correct position is returned even if an invalid UTF-8 string is given. ```console % ./mruby@master -e 'p ("\xd1" * 100 + "#").index("#")' 50 % ./mruby@improve-index -e 'p ("\xd1" * 100 + "#").index("#")' 100 ``` The other behavior should be the same as the current implementation. --- src/string.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 63 insertions(+), 5 deletions(-) (limited to 'src/string.c') diff --git a/src/string.c b/src/string.c index 3ef86eb53..0700f81fa 100644 --- a/src/string.c +++ b/src/string.c @@ -304,12 +304,73 @@ bytes2chars(char *p, mrb_int bi) return i; } +static mrb_int +str_index_str_by_char_search(mrb_state *mrb, const char *p, const char *pend, const char *s, const mrb_int slen, mrb_int off) +{ + /* Based on Quick Search algorithm (Boyer-Moore-Horspool algorithm) */ + + ptrdiff_t qstable[1 << CHAR_BIT]; + + /* Preprocessing */ + { + size_t i; + + for (i = 0; i < 1 << CHAR_BIT; i ++) { + qstable[i] = slen; + } + for (i = 0; i < slen; i ++) { + qstable[(unsigned char)s[i]] = slen - (i + 1); + } + } + + /* Searching */ + if (p < pend && pend - p >= slen) { + for (;;) { + const char *pivot; + + if (memcmp(p, s, slen) == 0) { + return off; + } + + pivot = p + qstable[(unsigned char)p[slen - 1]]; + if (pivot > pend || pivot < p /* overflowed */) { return -1; } + + do { + p += utf8len(p, pend); + off ++; + } while (p < pivot); + } + } + + return -1; +} + +static mrb_int +str_index_str_by_char(mrb_state *mrb, mrb_value str, mrb_value sub, mrb_int pos) +{ + const char *p = RSTRING_PTR(str); + const char *pend = p + RSTRING_LEN(str); + const char *s = RSTRING_PTR(sub); + const mrb_int slen = RSTRING_LEN(sub); + mrb_int off = pos; + + for (; pos > 0; pos --) { + if (pend - p < 1) { return -1; } + p += utf8len(p, pend); + } + + if (slen < 1) { return off; } + + return str_index_str_by_char_search(mrb, p, pend, s, slen, off); +} + #define BYTES_ALIGN_CHECK(pos) if (pos < 0) return mrb_nil_value(); #else #define RSTRING_CHAR_LEN(s) RSTRING_LEN(s) #define chars2bytes(p, off, ci) (ci) #define bytes2chars(p, bi) (bi) #define BYTES_ALIGN_CHECK(pos) +#define str_index_str_by_char(mrb, str, sub, pos) str_index_str(mrb, str, sub, pos) #endif static inline mrb_int @@ -1680,15 +1741,13 @@ mrb_str_index_m(mrb_state *mrb, mrb_value str) else sub = mrb_nil_value(); } - clen = RSTRING_CHAR_LEN(str); if (pos < 0) { + clen = RSTRING_CHAR_LEN(str); pos += clen; if (pos < 0) { return mrb_nil_value(); } } - if (pos > clen) return mrb_nil_value(); - pos = chars2bytes(str, 0, pos); switch (mrb_type(sub)) { default: { @@ -1702,12 +1761,11 @@ mrb_str_index_m(mrb_state *mrb, mrb_value str) } /* fall through */ case MRB_TT_STRING: - pos = str_index_str(mrb, str, sub, pos); + pos = str_index_str_by_char(mrb, str, sub, pos); break; } if (pos == -1) return mrb_nil_value(); - pos = bytes2chars(RSTRING_PTR(str), pos); BYTES_ALIGN_CHECK(pos); return mrb_fixnum_value(pos); } -- cgit v1.2.3 From bde2f35a9f2d894ec88ad693633e89279b0560b9 Mon Sep 17 00:00:00 2001 From: dearblue Date: Fri, 12 Jul 2019 21:23:55 +0900 Subject: Fix heap buffer overflow; fix #4569 --- src/string.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) (limited to 'src/string.c') diff --git a/src/string.c b/src/string.c index 0700f81fa..056348921 100644 --- a/src/string.c +++ b/src/string.c @@ -324,22 +324,20 @@ str_index_str_by_char_search(mrb_state *mrb, const char *p, const char *pend, co } /* Searching */ - if (p < pend && pend - p >= slen) { - for (;;) { - const char *pivot; + while (p < pend && pend - p >= slen) { + const char *pivot; - if (memcmp(p, s, slen) == 0) { - return off; - } + if (memcmp(p, s, slen) == 0) { + return off; + } - pivot = p + qstable[(unsigned char)p[slen - 1]]; - if (pivot > pend || pivot < p /* overflowed */) { return -1; } + pivot = p + qstable[(unsigned char)p[slen - 1]]; + if (pivot > pend || pivot < p /* overflowed */) { return -1; } - do { - p += utf8len(p, pend); - off ++; - } while (p < pivot); - } + do { + p += utf8len(p, pend); + off ++; + } while (p < pivot); } return -1; -- cgit v1.2.3 From 9741df100bb84a858725dba58705a908e5bdca4c Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sat, 13 Jul 2019 13:13:21 +0900 Subject: Change type of a variable for signedness mismatch; ref #4573 --- src/string.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/string.c') diff --git a/src/string.c b/src/string.c index 056348921..a6aa9d906 100644 --- a/src/string.c +++ b/src/string.c @@ -313,7 +313,7 @@ str_index_str_by_char_search(mrb_state *mrb, const char *p, const char *pend, co /* Preprocessing */ { - size_t i; + mrb_int i; for (i = 0; i < 1 << CHAR_BIT; i ++) { qstable[i] = slen; -- cgit v1.2.3 From 7b260d9c2de4436d6e8b09ba4fd524782934153f Mon Sep 17 00:00:00 2001 From: dearblue Date: Sun, 14 Jul 2019 18:55:38 +0900 Subject: Improve `utf8len()` performance with UTF-8 --- src/string.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/string.c') diff --git a/src/string.c b/src/string.c index a6aa9d906..be623deda 100644 --- a/src/string.c +++ b/src/string.c @@ -233,7 +233,9 @@ utf8len(const char* p, const char* e) mrb_int len; mrb_int i; + if ((unsigned char)*p < 0x80) return 1; len = utf8len_codepage[(unsigned char)*p]; + if (len == 1) return 1; if (len > e - p) return 1; for (i = 1; i < len; ++i) if ((p[i] & 0xc0) != 0x80) -- cgit v1.2.3 From 380805ece257147275bbed3eb83277f374296d9a Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Sun, 14 Jul 2019 19:13:19 +0900 Subject: Keep `MRB_STR_ASCII` flag in some methods of `String` --- include/mruby/string.h | 9 ++++++++- src/string.c | 15 +++++++-------- 2 files changed, 15 insertions(+), 9 deletions(-) (limited to 'src/string.c') diff --git a/include/mruby/string.h b/include/mruby/string.h index d648d856c..4615b4384 100644 --- a/include/mruby/string.h +++ b/include/mruby/string.h @@ -107,7 +107,6 @@ MRB_API mrb_int mrb_str_strlen(mrb_state*, struct RString*); #define MRB_STR_EMBED_LEN_SHIFT 6 void mrb_gc_free_str(mrb_state*, struct RString*); -MRB_API void mrb_str_modify(mrb_state*, struct RString*); /* * Finds the index of a substring in a string @@ -454,6 +453,14 @@ mrb_value mrb_str_inspect(mrb_state *mrb, mrb_value str); mrb_bool mrb_str_beg_len(mrb_int str_len, mrb_int *begp, mrb_int *lenp); mrb_value mrb_str_byte_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len); +void mrb_str_modify_keep_ascii(mrb_state *mrb, struct RString *s); + +MRB_INLINE void +mrb_str_modify(mrb_state *mrb, struct RString *s) +{ + mrb_str_modify_keep_ascii(mrb, s); + RSTR_UNSET_ASCII_FLAG(s); +} #ifdef MRB_UTF8_STRING mrb_int mrb_utf8_len(const char *str, mrb_int byte_len); diff --git a/src/string.c b/src/string.c index a6aa9d906..8706bfd1b 100644 --- a/src/string.c +++ b/src/string.c @@ -706,11 +706,10 @@ mrb_locale_from_utf8(const char *utf8, int len) } #endif -MRB_API void -mrb_str_modify(mrb_state *mrb, struct RString *s) +void +mrb_str_modify_keep_ascii(mrb_state *mrb, struct RString *s) { mrb_check_frozen(mrb, s); - RSTR_UNSET_ASCII_FLAG(s); if (RSTR_SHARED_P(s)) { mrb_shared_string *shared = s->as.heap.aux.shared; @@ -1339,7 +1338,7 @@ mrb_str_capitalize_bang(mrb_state *mrb, mrb_value str) mrb_bool modify = FALSE; struct RString *s = mrb_str_ptr(str); - mrb_str_modify(mrb, s); + mrb_str_modify_keep_ascii(mrb, s); if (RSTR_LEN(s) == 0 || !RSTR_PTR(s)) return mrb_nil_value(); p = RSTR_PTR(s); pend = RSTR_PTR(s) + RSTR_LEN(s); if (ISLOWER(*p)) { @@ -1398,7 +1397,7 @@ mrb_str_chomp_bang(mrb_state *mrb, mrb_value str) struct RString *s = mrb_str_ptr(str); argc = mrb_get_args(mrb, "|S", &rs); - mrb_str_modify(mrb, s); + mrb_str_modify_keep_ascii(mrb, s); len = RSTR_LEN(s); if (argc == 0) { if (len == 0) return mrb_nil_value(); @@ -1497,7 +1496,7 @@ mrb_str_chop_bang(mrb_state *mrb, mrb_value str) { struct RString *s = mrb_str_ptr(str); - mrb_str_modify(mrb, s); + mrb_str_modify_keep_ascii(mrb, s); if (RSTR_LEN(s) > 0) { mrb_int len; #ifdef MRB_UTF8_STRING @@ -1566,7 +1565,7 @@ mrb_str_downcase_bang(mrb_state *mrb, mrb_value str) mrb_bool modify = FALSE; struct RString *s = mrb_str_ptr(str); - mrb_str_modify(mrb, s); + mrb_str_modify_keep_ascii(mrb, s); p = RSTR_PTR(s); pend = RSTR_PTR(s) + RSTR_LEN(s); while (p < pend) { @@ -2536,7 +2535,7 @@ mrb_str_upcase_bang(mrb_state *mrb, mrb_value str) char *p, *pend; mrb_bool modify = FALSE; - mrb_str_modify(mrb, s); + mrb_str_modify_keep_ascii(mrb, s); p = RSTRING_PTR(str); pend = RSTRING_END(str); while (p < pend) { -- cgit v1.2.3 From 9093f3403f76b0a70d2b29b6c04ca7f203c242e6 Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Mon, 15 Jul 2019 07:39:57 +0900 Subject: Add `MRB_API` to `mrb_str_modify_keep_ascii()` --- include/mruby/string.h | 3 ++- src/string.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'src/string.c') diff --git a/include/mruby/string.h b/include/mruby/string.h index 4615b4384..77f6becf6 100644 --- a/include/mruby/string.h +++ b/include/mruby/string.h @@ -108,6 +108,8 @@ MRB_API mrb_int mrb_str_strlen(mrb_state*, struct RString*); void mrb_gc_free_str(mrb_state*, struct RString*); +MRB_API void mrb_str_modify_keep_ascii(mrb_state *mrb, struct RString *s); + /* * Finds the index of a substring in a string */ @@ -453,7 +455,6 @@ mrb_value mrb_str_inspect(mrb_state *mrb, mrb_value str); mrb_bool mrb_str_beg_len(mrb_int str_len, mrb_int *begp, mrb_int *lenp); mrb_value mrb_str_byte_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len); -void mrb_str_modify_keep_ascii(mrb_state *mrb, struct RString *s); MRB_INLINE void mrb_str_modify(mrb_state *mrb, struct RString *s) diff --git a/src/string.c b/src/string.c index 8706bfd1b..c1a001634 100644 --- a/src/string.c +++ b/src/string.c @@ -706,7 +706,7 @@ mrb_locale_from_utf8(const char *utf8, int len) } #endif -void +MRB_API void mrb_str_modify_keep_ascii(mrb_state *mrb, struct RString *s) { mrb_check_frozen(mrb, s); -- cgit v1.2.3 From 31492a177c34485e9bcc441e74c208366920f7b2 Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Tue, 16 Jul 2019 21:56:58 +0900 Subject: Copy receiver's `MRB_STR_ASCII` flag in some methods of `String` --- src/string.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/string.c') diff --git a/src/string.c b/src/string.c index 39b3515a3..6b7cced13 100644 --- a/src/string.c +++ b/src/string.c @@ -487,6 +487,7 @@ mrb_str_byte_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len) s->as.heap.ptr += beg; s->as.heap.len = len; } + RSTR_COPY_ASCII_FLAG(s, orig); return mrb_obj_value(s); } @@ -902,6 +903,7 @@ mrb_str_times(mrb_state *mrb, mrb_value self) memcpy(p + n, p, len-n); } p[RSTR_LEN(str2)] = '\0'; + RSTR_COPY_ASCII_FLAG(str2, mrb_str_ptr(self)); return mrb_obj_value(str2); } @@ -2837,6 +2839,7 @@ mrb_str_inspect(mrb_state *mrb, mrb_value str) } } mrb_str_cat_lit(mrb, result, "\""); + RSTR_COPY_ASCII_FLAG(mrb_str_ptr(result), mrb_str_ptr(str)); return result; } -- cgit v1.2.3 From b22bde6596ece6f9e3ef245bbab13a9f664907a8 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 17 Jul 2019 00:29:33 +0900 Subject: Avoid `MRB_INLINE` for `mrb_str_modify()`; ref #4579 Functions that are called infrequently need not to be inline. --- include/mruby/string.h | 9 ++------- src/string.c | 7 +++++++ 2 files changed, 9 insertions(+), 7 deletions(-) (limited to 'src/string.c') diff --git a/include/mruby/string.h b/include/mruby/string.h index 77f6becf6..d17ac1c1d 100644 --- a/include/mruby/string.h +++ b/include/mruby/string.h @@ -108,6 +108,8 @@ MRB_API mrb_int mrb_str_strlen(mrb_state*, struct RString*); void mrb_gc_free_str(mrb_state*, struct RString*); +MRB_API void mrb_str_modify(mrb_state *mrb, struct RString *s); +/* mrb_str_modify() with keeping ASCII flag if set */ MRB_API void mrb_str_modify_keep_ascii(mrb_state *mrb, struct RString *s); /* @@ -456,13 +458,6 @@ mrb_value mrb_str_inspect(mrb_state *mrb, mrb_value str); mrb_bool mrb_str_beg_len(mrb_int str_len, mrb_int *begp, mrb_int *lenp); mrb_value mrb_str_byte_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len); -MRB_INLINE void -mrb_str_modify(mrb_state *mrb, struct RString *s) -{ - mrb_str_modify_keep_ascii(mrb, s); - RSTR_UNSET_ASCII_FLAG(s); -} - #ifdef MRB_UTF8_STRING mrb_int mrb_utf8_len(const char *str, mrb_int byte_len); #endif diff --git a/src/string.c b/src/string.c index 6b7cced13..de8a15ba9 100644 --- a/src/string.c +++ b/src/string.c @@ -770,6 +770,13 @@ mrb_str_modify_keep_ascii(mrb_state *mrb, struct RString *s) } } +MRB_API void +mrb_str_modify(mrb_state *mrb, struct RString *s) +{ + mrb_str_modify_keep_ascii(mrb, s); + RSTR_UNSET_ASCII_FLAG(s); +} + MRB_API mrb_value mrb_str_resize(mrb_state *mrb, mrb_value str, mrb_int len) { -- cgit v1.2.3 From fe8b463c4ee84a89c116102a86181b2e7084e038 Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Mon, 22 Jul 2019 19:39:25 +0900 Subject: Set `MRB_STR_ASCII` flag in `String#inspect` `String#inspect` can set `MRB_STR_ASCII` flag to receiver and return value because it checks character byte length. --- src/string.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src/string.c') diff --git a/src/string.c b/src/string.c index de8a15ba9..ecbe21a22 100644 --- a/src/string.c +++ b/src/string.c @@ -2789,6 +2789,9 @@ mrb_str_inspect(mrb_state *mrb, mrb_value str) const char *p, *pend; char buf[CHAR_ESC_LEN + 1]; mrb_value result = mrb_str_new_lit(mrb, "\""); +#ifdef MRB_UTF8_STRING + uint32_t ascii_flag = MRB_STR_ASCII; +#endif p = RSTRING_PTR(str); pend = RSTRING_END(str); for (;p < pend; p++) { @@ -2805,6 +2808,7 @@ mrb_str_inspect(mrb_state *mrb, mrb_value str) } mrb_str_cat(mrb, result, buf, clen); p += clen-1; + ascii_flag = 0; continue; } #endif @@ -2846,7 +2850,10 @@ mrb_str_inspect(mrb_state *mrb, mrb_value str) } } mrb_str_cat_lit(mrb, result, "\""); - RSTR_COPY_ASCII_FLAG(mrb_str_ptr(result), mrb_str_ptr(str)); +#ifdef MRB_UTF8_STRING + mrb_str_ptr(str)->flags |= ascii_flag; + mrb_str_ptr(result)->flags |= ascii_flag; +#endif return result; } -- cgit v1.2.3 From 334afb167c0a1fa478a53c3844f37c0f1fd866dd Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Mon, 5 Aug 2019 12:41:15 +0900 Subject: Use new specifiers/modifiers of `mrb_vfromat()` The binary sizes (gems are only `mruby-bin-mruby`) are reduced slightly in my environment than before the introduction of new specifiers/modifiers (5116789a) with this change. ------------+-------------------+-------------------+-------- BINARY | BEFORE (5116789a) | AFTER (This PR) | RATIO ------------+-------------------+-------------------+-------- mruby | 593416 bytes | 593208 bytes | -0.04% libmruby.a | 769048 bytes | 767264 bytes | -0.23% ------------+-------------------+-------------------+-------- BTW, I accidentally changed `tasks/toolchains/visualcpp.rake` at #4613, so I put it back. --- mrbgems/mruby-compiler/core/codegen.c | 2 +- mrbgems/mruby-compiler/core/parse.y | 2 +- mrbgems/mruby-complex/src/complex.c | 4 +-- mrbgems/mruby-eval/src/eval.c | 14 ++++----- mrbgems/mruby-io/src/file.c | 6 ++-- mrbgems/mruby-io/src/io.c | 20 +++++-------- mrbgems/mruby-io/test/mruby_io_test.c | 6 ++-- mrbgems/mruby-kernel-ext/src/kernel.c | 13 ++++---- mrbgems/mruby-math/src/math.c | 3 +- mrbgems/mruby-metaprog/src/metaprog.c | 11 +++---- mrbgems/mruby-method/src/method.c | 12 ++------ mrbgems/mruby-pack/src/pack.c | 13 ++++---- mrbgems/mruby-socket/src/socket.c | 8 ++--- mrbgems/mruby-sprintf/src/sprintf.c | 36 +++++++++++----------- mrbgems/mruby-string-ext/src/string.c | 11 ++++--- mrbgems/mruby-struct/src/struct.c | 28 ++++++++---------- mrbgems/mruby-time/src/time.c | 4 +-- src/array.c | 10 +++---- src/backtrace.c | 4 +-- src/class.c | 56 +++++++++++++++-------------------- src/error.c | 11 ++++--- src/etc.c | 12 ++++---- src/gc.c | 2 +- src/kernel.c | 8 ++--- src/numeric.c | 8 ++--- src/object.c | 37 ++++++----------------- src/proc.c | 4 +-- src/range.c | 2 +- src/string.c | 20 ++++++------- src/variable.c | 5 ++-- src/vm.c | 14 ++++----- tasks/toolchains/visualcpp.rake | 2 +- 32 files changed, 163 insertions(+), 225 deletions(-) (limited to 'src/string.c') diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index ed8fc3150..5cade970c 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -2373,7 +2373,7 @@ codegen(codegen_scope *s, node *tree, int val) mrb_value str; int sym; - str = mrb_format(mrb, "$%S", mrb_fixnum_value(nint(tree))); + str = mrb_format(mrb, "$%d", nint(tree)); sym = new_sym(s, mrb_intern_str(mrb, str)); genop_2(s, OP_GETGV, cursp(), sym); push(); diff --git a/mrbgems/mruby-compiler/core/parse.y b/mrbgems/mruby-compiler/core/parse.y index f6d543c5d..3a55c8e70 100644 --- a/mrbgems/mruby-compiler/core/parse.y +++ b/mrbgems/mruby-compiler/core/parse.y @@ -3831,7 +3831,7 @@ backref_error(parser_state *p, node *n) yyerror_c(p, "can't set variable $", (char)intn(n->cdr)); } else { - mrb_bug(p->mrb, "Internal error in backref_error() : n=>car == %S", mrb_fixnum_value(c)); + mrb_bug(p->mrb, "Internal error in backref_error() : n=>car == %d", c); } } diff --git a/mrbgems/mruby-complex/src/complex.c b/mrbgems/mruby-complex/src/complex.c index aa2afc2ce..a87b95dea 100644 --- a/mrbgems/mruby-complex/src/complex.c +++ b/mrbgems/mruby-complex/src/complex.c @@ -101,7 +101,7 @@ complex_to_f(mrb_state *mrb, mrb_value self) struct mrb_complex *p = complex_ptr(mrb, self); if (p->imaginary != 0) { - mrb_raisef(mrb, E_RANGE_ERROR, "can't convert %S into Float", self); + mrb_raisef(mrb, E_RANGE_ERROR, "can't convert %v into Float", self); } return mrb_float_value(mrb, p->real); @@ -113,7 +113,7 @@ complex_to_i(mrb_state *mrb, mrb_value self) struct mrb_complex *p = complex_ptr(mrb, self); if (p->imaginary != 0) { - mrb_raisef(mrb, E_RANGE_ERROR, "can't convert %S into Float", self); + mrb_raisef(mrb, E_RANGE_ERROR, "can't convert %v into Float", self); } return mrb_int_value(mrb, p->real); } diff --git a/mrbgems/mruby-eval/src/eval.c b/mrbgems/mruby-eval/src/eval.c index 30534aaec..e8f1d3e95 100644 --- a/mrbgems/mruby-eval/src/eval.c +++ b/mrbgems/mruby-eval/src/eval.c @@ -254,15 +254,15 @@ create_proc_from_string(mrb_state *mrb, char *s, mrb_int len, mrb_value binding, mrb_value str; if (file) { - str = mrb_format(mrb, " file %S line %S: %S", - mrb_str_new_cstr(mrb, file), - mrb_fixnum_value(p->error_buffer[0].lineno), - mrb_str_new_cstr(mrb, p->error_buffer[0].message)); + str = mrb_format(mrb, "file %s line %d: %s", + file, + p->error_buffer[0].lineno, + p->error_buffer[0].message); } else { - str = mrb_format(mrb, " line %S: %S", - mrb_fixnum_value(p->error_buffer[0].lineno), - mrb_str_new_cstr(mrb, p->error_buffer[0].message)); + str = mrb_format(mrb, "line %d: %s", + p->error_buffer[0].lineno, + p->error_buffer[0].message); } mrb_parser_free(p); mrbc_context_free(mrb, cxt); diff --git a/mrbgems/mruby-io/src/file.c b/mrbgems/mruby-io/src/file.c index 243f634b4..5e6c849f0 100644 --- a/mrbgems/mruby-io/src/file.c +++ b/mrbgems/mruby-io/src/file.c @@ -146,7 +146,7 @@ mrb_file_s_rename(mrb_state *mrb, mrb_value obj) #endif mrb_locale_free(src); mrb_locale_free(dst); - mrb_sys_fail(mrb, RSTRING_PTR(mrb_format(mrb, "(%S, %S)", from, to))); + mrb_sys_fail(mrb, RSTRING_PTR(mrb_format(mrb, "(%v, %v)", from, to))); } mrb_locale_free(src); mrb_locale_free(dst); @@ -307,7 +307,7 @@ mrb_file__gethome(mrb_state *mrb, mrb_value klass) } home = pwd->pw_dir; if (!mrb_file_is_absolute_path(home)) { - mrb_raisef(mrb, E_ARGUMENT_ERROR, "non-absolute home of ~%S", username); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "non-absolute home of ~%v", username); } } home = mrb_locale_from_utf8(home, -1); @@ -398,7 +398,7 @@ mrb_file_s_symlink(mrb_state *mrb, mrb_value klass) if (symlink(src, dst) == -1) { mrb_locale_free(src); mrb_locale_free(dst); - mrb_sys_fail(mrb, mrb_str_to_cstr(mrb, mrb_format(mrb, "(%S, %S)", from, to))); + mrb_sys_fail(mrb, RSTRING_PTR(mrb_format(mrb, "(%v, %v)", from, to))); } mrb_locale_free(src); mrb_locale_free(dst); diff --git a/mrbgems/mruby-io/src/io.c b/mrbgems/mruby-io/src/io.c index 99441f16b..a0b6c6780 100644 --- a/mrbgems/mruby-io/src/io.c +++ b/mrbgems/mruby-io/src/io.c @@ -127,7 +127,7 @@ mrb_io_modestr_to_flags(mrb_state *mrb, const char *mode) flags |= FMODE_WRITABLE | FMODE_APPEND | FMODE_CREATE; break; default: - mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal access mode %S", mrb_str_new_cstr(mrb, mode)); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal access mode %s", mode); } while (*m) { @@ -141,7 +141,7 @@ mrb_io_modestr_to_flags(mrb_state *mrb, const char *mode) case ':': /* XXX: PASSTHROUGH*/ default: - mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal access mode %S", mrb_str_new_cstr(mrb, mode)); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal access mode %s", mode); } } @@ -191,8 +191,7 @@ mrb_fd_cloexec(mrb_state *mrb, int fd) flags = fcntl(fd, F_GETFD); if (flags == -1) { - mrb_bug(mrb, "mrb_fd_cloexec: fcntl(%S, F_GETFD) failed: %S", - mrb_fixnum_value(fd), mrb_fixnum_value(errno)); + mrb_bug(mrb, "mrb_fd_cloexec: fcntl(%d, F_GETFD) failed: %d", fd, errno); } if (fd <= 2) { flags2 = flags & ~FD_CLOEXEC; /* Clear CLOEXEC for standard file descriptors: 0, 1, 2. */ @@ -202,8 +201,7 @@ mrb_fd_cloexec(mrb_state *mrb, int fd) } if (flags != flags2) { if (fcntl(fd, F_SETFD, flags2) == -1) { - mrb_bug(mrb, "mrb_fd_cloexec: fcntl(%S, F_SETFD, %S) failed: %S", - mrb_fixnum_value(fd), mrb_fixnum_value(flags2), mrb_fixnum_value(errno)); + mrb_bug(mrb, "mrb_fd_cloexec: fcntl(%d, F_SETFD, %d) failed: %d", fd, flags2, errno); } } #endif @@ -381,7 +379,7 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass) CloseHandle(ifd[1]); CloseHandle(ofd[0]); CloseHandle(ofd[1]); - mrb_raisef(mrb, E_IO_ERROR, "command not found: %S", cmd); + mrb_raisef(mrb, E_IO_ERROR, "command not found: %v", cmd); } CloseHandle(pi.hThread); CloseHandle(ifd[0]); @@ -494,7 +492,7 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass) close(fd); } mrb_proc_exec(pname); - mrb_raisef(mrb, E_IO_ERROR, "command not found: %S", cmd); + mrb_raisef(mrb, E_IO_ERROR, "command not found: %v", cmd); _exit(127); } result = mrb_nil_value(); @@ -783,9 +781,7 @@ reopen: } } - emsg = mrb_format(mrb, "open %S", mrb_str_new_cstr(mrb, pathname)); - mrb_str_modify(mrb, mrb_str_ptr(emsg)); - mrb_sys_fail(mrb, RSTRING_PTR(emsg)); + mrb_sys_fail(mrb, RSTRING_PTR(mrb_format(mrb, "open %s", pathname))); } mrb_locale_free(fname); @@ -1068,7 +1064,7 @@ mrb_io_s_select(mrb_state *mrb, mrb_value klass) mrb_get_args(mrb, "*", &argv, &argc); if (argc < 1 || argc > 4) { - mrb_raisef(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (%S for 1..4)", mrb_fixnum_value(argc)); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (%i for 1..4)", argc); } timeout = mrb_nil_value(); diff --git a/mrbgems/mruby-io/test/mruby_io_test.c b/mrbgems/mruby-io/test/mruby_io_test.c index 3312d6c7e..2c8a75fc9 100644 --- a/mrbgems/mruby-io/test/mruby_io_test.c +++ b/mrbgems/mruby-io/test/mruby_io_test.c @@ -136,9 +136,9 @@ mrb_io_test_io_setup(mrb_state *mrb, mrb_value self) sun0.sun_family = AF_UNIX; snprintf(sun0.sun_path, sizeof(sun0.sun_path), "%s", socketname); if (bind(fd3, (struct sockaddr *)&sun0, sizeof(sun0)) == -1) { - mrb_raisef(mrb, E_RUNTIME_ERROR, "can't bind AF_UNIX socket to %S: %S", - mrb_str_new_cstr(mrb, sun0.sun_path), - mrb_fixnum_value(errno)); + mrb_raisef(mrb, E_RUNTIME_ERROR, "can't bind AF_UNIX socket to %s: %d", + sun0.sun_path, + errno); } close(fd3); #endif diff --git a/mrbgems/mruby-kernel-ext/src/kernel.c b/mrbgems/mruby-kernel-ext/src/kernel.c index 8e7e03c56..376751e10 100644 --- a/mrbgems/mruby-kernel-ext/src/kernel.c +++ b/mrbgems/mruby-kernel-ext/src/kernel.c @@ -31,22 +31,21 @@ mrb_f_caller(mrb_state *mrb, mrb_value self) } } else { - v = mrb_to_int(mrb, v); - lev = mrb_fixnum(v); + lev = mrb_int(mrb, v); if (lev < 0) { - mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative level (%S)", v); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative level (%v)", v); } n = bt_len - lev; } break; case 2: - lev = mrb_fixnum(mrb_to_int(mrb, v)); - n = mrb_fixnum(mrb_to_int(mrb, length)); + lev = mrb_int(mrb, v); + n = mrb_int(mrb, length); if (lev < 0) { - mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative level (%S)", v); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative level (%v)", v); } if (n < 0) { - mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative size (%S)", length); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative size (%v)", length); } break; default: diff --git a/mrbgems/mruby-math/src/math.c b/mrbgems/mruby-math/src/math.c index c6d4ca414..88b33771b 100644 --- a/mrbgems/mruby-math/src/math.c +++ b/mrbgems/mruby-math/src/math.c @@ -18,8 +18,7 @@ domain_error(mrb_state *mrb, const char *func) { struct RClass *math = mrb_module_get(mrb, "Math"); struct RClass *domainerror = mrb_class_get_under(mrb, math, "DomainError"); - mrb_value str = mrb_str_new_cstr(mrb, func); - mrb_raisef(mrb, domainerror, "Numerical argument is out of domain - %S", str); + mrb_raisef(mrb, domainerror, "Numerical argument is out of domain - %s", func); } /* math functions not provided by Microsoft Visual C++ 2012 or older */ diff --git a/mrbgems/mruby-metaprog/src/metaprog.c b/mrbgems/mruby-metaprog/src/metaprog.c index 62daa5227..97f53051f 100644 --- a/mrbgems/mruby-metaprog/src/metaprog.c +++ b/mrbgems/mruby-metaprog/src/metaprog.c @@ -414,7 +414,7 @@ check_cv_name_sym(mrb_state *mrb, mrb_sym id) mrb_int len; const char *name = mrb_sym2name_len(mrb, id, &len); if (!cv_name_p(mrb, name, len)) { - mrb_name_error(mrb, id, "'%S' is not allowed as a class variable name", mrb_sym2str(mrb, id)); + mrb_name_error(mrb, id, "'%n' is not allowed as a class variable name", id); } } @@ -454,12 +454,10 @@ mrb_mod_remove_cvar(mrb_state *mrb, mrb_value mod) if (!mrb_undef_p(val)) return val; if (mrb_cv_defined(mrb, mod, id)) { - mrb_name_error(mrb, id, "cannot remove %S for %S", - mrb_sym2str(mrb, id), mod); + mrb_name_error(mrb, id, "cannot remove %n for %v", id, mod); } - mrb_name_error(mrb, id, "class variable %S not defined for %S", - mrb_sym2str(mrb, id), mod); + mrb_name_error(mrb, id, "class variable %n not defined for %v", id, mod); /* not reached */ return mrb_nil_value(); @@ -622,8 +620,7 @@ remove_method(mrb_state *mrb, mrb_value mod, mrb_sym mid) } } - mrb_name_error(mrb, mid, "method '%S' not defined in %S", - mrb_sym2str(mrb, mid), mod); + mrb_name_error(mrb, mid, "method '%n' not defined in %v", mid, mod); } /* 15.2.2.4.41 */ diff --git a/mrbgems/mruby-method/src/method.c b/mrbgems/mruby-method/src/method.c index d94db1cb2..b5050368d 100644 --- a/mrbgems/mruby-method/src/method.c +++ b/mrbgems/mruby-method/src/method.c @@ -29,8 +29,7 @@ unbound_method_bind(mrb_state *mrb, mrb_value self) if (mrb_type(owner) == MRB_TT_SCLASS) { mrb_raise(mrb, E_TYPE_ERROR, "singleton method called for a different object"); } else { - const char *s = mrb_class_name(mrb, mrb_class_ptr(owner)); - mrb_raisef(mrb, E_TYPE_ERROR, "bind argument must be an instance of %S", mrb_str_new_static(mrb, s, strlen(s))); + mrb_raisef(mrb, E_TYPE_ERROR, "bind argument must be an instance of %v", owner); } } me = method_object_alloc(mrb, mrb_class_get(mrb, "Method")); @@ -289,7 +288,6 @@ static void mrb_search_method_owner(mrb_state *mrb, struct RClass *c, mrb_value obj, mrb_sym name, struct RClass **owner, struct RProc **proc, mrb_bool unbound) { mrb_value ret; - const char *s; *owner = c; *proc = method_search_vm(mrb, owner, name); @@ -313,13 +311,7 @@ mrb_search_method_owner(mrb_state *mrb, struct RClass *c, mrb_value obj, mrb_sym return; name_error: - s = mrb_class_name(mrb, c); - mrb_raisef( - mrb, E_NAME_ERROR, - "undefined method '%S' for class '%S'", - mrb_sym2str(mrb, name), - mrb_str_new_static(mrb, s, strlen(s)) - ); + mrb_raisef(mrb, E_NAME_ERROR, "undefined method '%n' for class '%C'", name, c); } static mrb_value diff --git a/mrbgems/mruby-pack/src/pack.c b/mrbgems/mruby-pack/src/pack.c index 9f091194b..159ba09ac 100644 --- a/mrbgems/mruby-pack/src/pack.c +++ b/mrbgems/mruby-pack/src/pack.c @@ -529,8 +529,8 @@ utf8_to_uv(mrb_state *mrb, const char *p, long *lenp) mrb_raise(mrb, E_ARGUMENT_ERROR, "malformed UTF-8 character"); } if (n > *lenp) { - mrb_raisef(mrb, E_ARGUMENT_ERROR, "malformed UTF-8 character (expected %S bytes, given %S bytes)", - mrb_fixnum_value(n), mrb_fixnum_value(*lenp)); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "malformed UTF-8 character (expected %d bytes, given %d bytes)", + n, *lenp); } *lenp = n--; if (n != 0) { @@ -976,7 +976,7 @@ alias: case 4: t = 'L'; goto alias; case 8: t = 'Q'; goto alias; default: - mrb_raisef(mrb, E_RUNTIME_ERROR, "mruby-pack does not support sizeof(int) == %S", mrb_fixnum_value(sizeof(int))); + mrb_raisef(mrb, E_RUNTIME_ERROR, "mruby-pack does not support sizeof(int) == %d", (int)sizeof(int)); } break; case 'i': @@ -985,7 +985,7 @@ alias: case 4: t = 'l'; goto alias; case 8: t = 'q'; goto alias; default: - mrb_raisef(mrb, E_RUNTIME_ERROR, "mruby-pack does not support sizeof(int) == %S", mrb_fixnum_value(sizeof(int))); + mrb_raisef(mrb, E_RUNTIME_ERROR, "mruby-pack does not support sizeof(int) == %d", (int)sizeof(int)); } break; case 'L': @@ -1086,8 +1086,7 @@ alias: count = -1; } else if (ch == '_' || ch == '!' || ch == '<' || ch == '>') { if (strchr("sSiIlLqQ", (int)t) == NULL) { - char ch_str = (char)ch; - mrb_raisef(mrb, E_ARGUMENT_ERROR, "'%S' allowed only after types sSiIlLqQ", mrb_str_new(mrb, &ch_str, 1)); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "'%c' allowed only after types sSiIlLqQ", ch); } if (ch == '_' || ch == '!') { flags |= PACK_FLAG_s; @@ -1156,7 +1155,7 @@ mrb_pack_pack(mrb_state *mrb, mrb_value ary) #endif else if (type == PACK_TYPE_STRING) { if (!mrb_string_p(o)) { - mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %S into String", mrb_class_path(mrb, mrb_obj_class(mrb, o))); + mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %T into String", o); } } diff --git a/mrbgems/mruby-socket/src/socket.c b/mrbgems/mruby-socket/src/socket.c index 9b06274dc..eaca27779 100644 --- a/mrbgems/mruby-socket/src/socket.c +++ b/mrbgems/mruby-socket/src/socket.c @@ -171,7 +171,7 @@ mrb_addrinfo_getaddrinfo(mrb_state *mrb, mrb_value klass) error = getaddrinfo(hostname, servname, &hints, &res0); if (error) { - mrb_raisef(mrb, E_SOCKET_ERROR, "getaddrinfo: %S", mrb_str_new_cstr(mrb, gai_strerror(error))); + mrb_raisef(mrb, E_SOCKET_ERROR, "getaddrinfo: %s", gai_strerror(error)); } mrb_cv_set(mrb, klass, mrb_intern_lit(mrb, "_lastai"), mrb_cptr_value(mrb, res0)); @@ -206,7 +206,7 @@ mrb_addrinfo_getnameinfo(mrb_state *mrb, mrb_value self) } error = getnameinfo((struct sockaddr *)RSTRING_PTR(sastr), (socklen_t)RSTRING_LEN(sastr), RSTRING_PTR(host), NI_MAXHOST, RSTRING_PTR(serv), NI_MAXSERV, (int)flags); if (error) { - mrb_raisef(mrb, E_SOCKET_ERROR, "getnameinfo: %S", mrb_str_new_cstr(mrb, gai_strerror(error))); + mrb_raisef(mrb, E_SOCKET_ERROR, "getnameinfo: %s", gai_strerror(error)); } ary = mrb_ary_new_capa(mrb, 2); mrb_str_resize(mrb, host, strlen(RSTRING_PTR(host))); @@ -476,7 +476,7 @@ mrb_basicsocket_setsockopt(mrb_state *mrb, mrb_value self) optname = mrb_fixnum(mrb_funcall(mrb, so, "optname", 0)); optval = mrb_funcall(mrb, so, "data", 0); } else { - mrb_raisef(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (%S for 3)", mrb_fixnum_value(argc)); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (%i for 3)", argc); } s = socket_fd(mrb, self); @@ -702,7 +702,7 @@ mrb_socket_sockaddr_un(mrb_state *mrb, mrb_value klass) mrb_get_args(mrb, "S", &path); if ((size_t)RSTRING_LEN(path) > sizeof(sunp->sun_path) - 1) { - mrb_raisef(mrb, E_ARGUMENT_ERROR, "too long unix socket path (max: %S bytes)", mrb_fixnum_value(sizeof(sunp->sun_path) - 1)); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "too long unix socket path (max: %d bytes)", (int)sizeof(sunp->sun_path) - 1); } s = mrb_str_buf_new(mrb, sizeof(struct sockaddr_un)); sunp = (struct sockaddr_un *)RSTRING_PTR(s); diff --git a/mrbgems/mruby-sprintf/src/sprintf.c b/mrbgems/mruby-sprintf/src/sprintf.c index 985ffe276..c8d51962e 100644 --- a/mrbgems/mruby-sprintf/src/sprintf.c +++ b/mrbgems/mruby-sprintf/src/sprintf.c @@ -81,7 +81,7 @@ mrb_fix2binstr(mrb_state *mrb, mrb_value x, int base) char d; if (base != 2) { - mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid radix %S", mrb_fixnum_value(base)); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid radix %d", base); } if (val == 0) { return mrb_str_new_lit(mrb, "0"); @@ -144,10 +144,10 @@ check_next_arg(mrb_state *mrb, int posarg, int nextarg) { switch (posarg) { case -1: - mrb_raisef(mrb, E_ARGUMENT_ERROR, "unnumbered(%S) mixed with numbered", mrb_fixnum_value(nextarg)); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "unnumbered(%d) mixed with numbered", nextarg); break; case -2: - mrb_raisef(mrb, E_ARGUMENT_ERROR, "unnumbered(%S) mixed with named", mrb_fixnum_value(nextarg)); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "unnumbered(%d) mixed with named", nextarg); break; default: break; @@ -158,26 +158,26 @@ static void check_pos_arg(mrb_state *mrb, mrb_int posarg, mrb_int n) { if (posarg > 0) { - mrb_raisef(mrb, E_ARGUMENT_ERROR, "numbered(%S) after unnumbered(%S)", - mrb_fixnum_value(n), mrb_fixnum_value(posarg)); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "numbered(%i) after unnumbered(%i)", + n, posarg); } if (posarg == -2) { - mrb_raisef(mrb, E_ARGUMENT_ERROR, "numbered(%S) after named", mrb_fixnum_value(n)); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "numbered(%i) after named", n); } if (n < 1) { - mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid index - %S$", mrb_fixnum_value(n)); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid index - %i$", n); } } static void -check_name_arg(mrb_state *mrb, int posarg, const char *name, mrb_int len) +check_name_arg(mrb_state *mrb, int posarg, const char *name, size_t len) { if (posarg > 0) { - mrb_raisef(mrb, E_ARGUMENT_ERROR, "named%S after unnumbered(%S)", - mrb_str_new(mrb, (name), (len)), mrb_fixnum_value(posarg)); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "named%l after unnumbered(%d)", + name, len, posarg); } if (posarg == -1) { - mrb_raisef(mrb, E_ARGUMENT_ERROR, "named%S after numbered", mrb_str_new(mrb, (name), (len))); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "named%l after numbered", name, len); } } @@ -580,7 +580,7 @@ mrb_str_format(mrb_state *mrb, mrb_int argc, const mrb_value *argv, mrb_value fm retry: switch (*p) { default: - mrb_raisef(mrb, E_ARGUMENT_ERROR, "malformed format string - \\%%S", mrb_str_new(mrb, p, 1)); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "malformed format string - %%%c", *p); break; case ' ': @@ -619,7 +619,7 @@ retry: GETNUM(n, width); if (*p == '$') { if (!mrb_undef_p(nextvalue)) { - mrb_raisef(mrb, E_ARGUMENT_ERROR, "value given twice - %S$", mrb_fixnum_value(n)); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "value given twice - %i$", n); } nextvalue = GETPOSARG(n); p++; @@ -639,14 +639,14 @@ retry: for (; p < end && *p != term; ) p++; if (id) { - mrb_raisef(mrb, E_ARGUMENT_ERROR, "name%S after <%S>", - mrb_str_new(mrb, start, p - start + 1), mrb_sym2str(mrb, id)); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "name%l after <%n>", + start, p - start + 1, id); } symname = mrb_str_new(mrb, start + 1, p - start - 1); id = mrb_intern_str(mrb, symname); - nextvalue = GETNAMEARG(mrb_symbol_value(id), start, (mrb_int)(p - start + 1)); + nextvalue = GETNAMEARG(mrb_symbol_value(id), start, p - start + 1); if (mrb_undef_p(nextvalue)) { - mrb_raisef(mrb, E_KEY_ERROR, "key%S not found", mrb_str_new(mrb, start, p - start + 1)); + mrb_raisef(mrb, E_KEY_ERROR, "key%l not found", start, p - start + 1); } if (term == '}') goto format_s; p++; @@ -1089,7 +1089,7 @@ retry: if (posarg >= 0 && nextarg < argc) { const char *mesg = "too many arguments for format string"; if (mrb_test(ruby_debug)) mrb_raise(mrb, E_ARGUMENT_ERROR, mesg); - if (mrb_test(ruby_verbose)) mrb_warn(mrb, "%S", mrb_str_new_cstr(mrb, mesg)); + if (mrb_test(ruby_verbose)) mrb_warn(mrb, "%s", mesg); } #endif mrb_str_resize(mrb, result, blen); diff --git a/mrbgems/mruby-string-ext/src/string.c b/mrbgems/mruby-string-ext/src/string.c index 80b277444..a946140dd 100644 --- a/mrbgems/mruby-string-ext/src/string.c +++ b/mrbgems/mruby-string-ext/src/string.c @@ -40,7 +40,7 @@ int_chr_binary(mrb_state *mrb, mrb_value num) mrb_value str; if (cp < 0 || 0xff < cp) { - mrb_raisef(mrb, E_RANGE_ERROR, "%S out of char range", num); + mrb_raisef(mrb, E_RANGE_ERROR, "%v out of char range", num); } c = (char)cp; str = mrb_str_new(mrb, &c, 1); @@ -59,7 +59,7 @@ int_chr_utf8(mrb_state *mrb, mrb_value num) uint32_t ascii_flag = 0; if (cp < 0 || 0x10FFFF < cp) { - mrb_raisef(mrb, E_RANGE_ERROR, "%S out of char range", num); + mrb_raisef(mrb, E_RANGE_ERROR, "%v out of char range", num); } if (cp < 0x80) { utf8[0] = (char)cp; @@ -114,7 +114,7 @@ mrb_str_setbyte(mrb_state *mrb, mrb_value str) len = RSTRING_LEN(str); if (pos < -len || len <= pos) - mrb_raisef(mrb, E_INDEX_ERROR, "index %S out of string", mrb_fixnum_value(pos)); + mrb_raisef(mrb, E_INDEX_ERROR, "index %i out of string", pos); if (pos < 0) pos += len; @@ -583,8 +583,7 @@ str_tr(mrb_state *mrb, mrb_value str, mrb_value p1, mrb_value p2, mrb_bool squee continue; } if (c > 0x80) { - mrb_raisef(mrb, E_ARGUMENT_ERROR, "character (%S) out of range", - mrb_fixnum_value((mrb_int)c)); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "character (%i) out of range", c); } lastch = c; s[i] = (char)c; @@ -956,7 +955,7 @@ mrb_int_chr(mrb_state *mrb, mrb_value num) } #endif else { - mrb_raisef(mrb, E_ARGUMENT_ERROR, "unknown encoding name - %S", enc); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "unknown encoding name - %v", enc); } /* not reached */ return mrb_nil_value(); diff --git a/mrbgems/mruby-struct/src/struct.c b/mrbgems/mruby-struct/src/struct.c index e04fe13ad..ebe711ed3 100644 --- a/mrbgems/mruby-struct/src/struct.c +++ b/mrbgems/mruby-struct/src/struct.c @@ -66,8 +66,8 @@ struct_members(mrb_state *mrb, mrb_value s) } else { mrb_raisef(mrb, E_TYPE_ERROR, - "struct size differs (%S required %S given)", - mrb_fixnum_value(RARRAY_LEN(members)), mrb_fixnum_value(RSTRUCT_LEN(s))); + "struct size differs (%i required %i given)", + RARRAY_LEN(members), RSTRUCT_LEN(s)); } } return members; @@ -205,10 +205,10 @@ make_struct(mrb_state *mrb, mrb_value name, mrb_value members, struct RClass *kl mrb_to_str(mrb, name); id = mrb_obj_to_sym(mrb, name); if (!mrb_const_name_p(mrb, RSTRING_PTR(name), RSTRING_LEN(name))) { - mrb_name_error(mrb, id, "identifier %S needs to be constant", name); + mrb_name_error(mrb, id, "identifier %v needs to be constant", name); } if (mrb_const_defined_at(mrb, mrb_obj_value(klass), id)) { - mrb_warn(mrb, "redefining constant Struct::%S", name); + mrb_warn(mrb, "redefining constant Struct::%v", name); mrb_const_remove(mrb, mrb_obj_value(klass), id); } c = mrb_define_class_under(mrb, klass, RSTRING_PTR(name), klass); @@ -388,7 +388,7 @@ struct_aref_sym(mrb_state *mrb, mrb_value obj, mrb_sym id) return ptr[i]; } } - mrb_name_error(mrb, id, "no member '%S' in struct", mrb_sym2str(mrb, id)); + mrb_name_error(mrb, id, "no member '%n' in struct", id); return mrb_nil_value(); /* not reached */ } @@ -399,12 +399,10 @@ struct_aref_int(mrb_state *mrb, mrb_value s, mrb_int i) if (idx < 0) mrb_raisef(mrb, E_INDEX_ERROR, - "offset %S too small for struct(size:%S)", - mrb_fixnum_value(i), mrb_fixnum_value(RSTRUCT_LEN(s))); + "offset %i too small for struct(size:%i)", i, RSTRUCT_LEN(s)); if (RSTRUCT_LEN(s) <= idx) mrb_raisef(mrb, E_INDEX_ERROR, - "offset %S too large for struct(size:%S)", - mrb_fixnum_value(i), mrb_fixnum_value(RSTRUCT_LEN(s))); + "offset %i too large for struct(size:%i)", i, RSTRUCT_LEN(s)); return RSTRUCT_PTR(s)[idx]; } @@ -437,7 +435,7 @@ mrb_struct_aref(mrb_state *mrb, mrb_value s) mrb_value sym = mrb_check_intern_str(mrb, idx); if (mrb_nil_p(sym)) { - mrb_name_error(mrb, mrb_intern_str(mrb, idx), "no member '%S' in struct", idx); + mrb_name_error(mrb, mrb_intern_str(mrb, idx), "no member '%v' in struct", idx); } idx = sym; } @@ -465,7 +463,7 @@ mrb_struct_aset_sym(mrb_state *mrb, mrb_value s, mrb_sym id, mrb_value val) return val; } } - mrb_name_error(mrb, id, "no member '%S' in struct", mrb_sym2str(mrb, id)); + mrb_name_error(mrb, id, "no member '%n' in struct", id); return val; /* not reach */ } @@ -504,7 +502,7 @@ mrb_struct_aset(mrb_state *mrb, mrb_value s) mrb_value sym = mrb_check_intern_str(mrb, idx); if (mrb_nil_p(sym)) { - mrb_name_error(mrb, mrb_intern_str(mrb, idx), "no member '%S' in struct", idx); + mrb_name_error(mrb, mrb_intern_str(mrb, idx), "no member '%v' in struct", idx); } idx = sym; } @@ -516,13 +514,11 @@ mrb_struct_aset(mrb_state *mrb, mrb_value s) if (i < 0) i = RSTRUCT_LEN(s) + i; if (i < 0) { mrb_raisef(mrb, E_INDEX_ERROR, - "offset %S too small for struct(size:%S)", - mrb_fixnum_value(i), mrb_fixnum_value(RSTRUCT_LEN(s))); + "offset %i too small for struct(size:%i)", i, RSTRUCT_LEN(s)); } if (RSTRUCT_LEN(s) <= i) { mrb_raisef(mrb, E_INDEX_ERROR, - "offset %S too large for struct(size:%S)", - mrb_fixnum_value(i), mrb_fixnum_value(RSTRUCT_LEN(s))); + "offset %i too large for struct(size:%i)", i, RSTRUCT_LEN(s)); } mrb_struct_modify(mrb, s); return RSTRUCT_PTR(s)[i] = val; diff --git a/mrbgems/mruby-time/src/time.c b/mrbgems/mruby-time/src/time.c index 16461095c..9b0549bea 100644 --- a/mrbgems/mruby-time/src/time.c +++ b/mrbgems/mruby-time/src/time.c @@ -267,7 +267,7 @@ mrb_to_time_t(mrb_state *mrb, mrb_value obj, time_t *usec) return t; out_of_range: - mrb_raisef(mrb, E_ARGUMENT_ERROR, "%S out of Time range", obj); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "%v out of Time range", obj); /* not reached */ if (usec) { *usec = 0; } @@ -293,7 +293,7 @@ time_update_datetime(mrb_state *mrb, struct mrb_time *self, int dealloc) mrb_sec sec = (mrb_sec)t; if (dealloc) mrb_free(mrb, self); - mrb_raisef(mrb, E_ARGUMENT_ERROR, "%S out of Time range", mrb_sec_value(mrb, sec)); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "%v out of Time range", mrb_sec_value(mrb, sec)); /* not reached */ return NULL; } diff --git a/src/array.c b/src/array.c index 8cf813743..06c23dcd3 100644 --- a/src/array.c +++ b/src/array.c @@ -668,7 +668,7 @@ mrb_ary_set(mrb_state *mrb, mrb_value ary, mrb_int n, mrb_value val) if (n < 0) { n += len; if (n < 0) { - mrb_raisef(mrb, E_INDEX_ERROR, "index %S out of array", mrb_fixnum_value(n - len)); + mrb_raisef(mrb, E_INDEX_ERROR, "index %i out of array", n - len); } } if (len <= n) { @@ -700,7 +700,7 @@ mrb_ary_splice(mrb_state *mrb, mrb_value ary, mrb_int head, mrb_int len, mrb_val ary_modify(mrb, a); /* len check */ - if (len < 0) mrb_raisef(mrb, E_INDEX_ERROR, "negative length (%S)", mrb_fixnum_value(len)); + if (len < 0) mrb_raisef(mrb, E_INDEX_ERROR, "negative length (%i)", len); /* range check */ if (head < 0) { @@ -734,7 +734,7 @@ mrb_ary_splice(mrb_state *mrb, mrb_value ary, mrb_int head, mrb_int len, mrb_val } if (head >= alen) { if (head > ARY_MAX_SIZE - argc) { - mrb_raisef(mrb, E_INDEX_ERROR, "index %S too big", mrb_fixnum_value(head)); + mrb_raisef(mrb, E_INDEX_ERROR, "index %i too big", head); } len = head + argc; if (len > ARY_CAPA(a)) { @@ -750,7 +750,7 @@ mrb_ary_splice(mrb_state *mrb, mrb_value ary, mrb_int head, mrb_int len, mrb_val mrb_int newlen; if (alen - len > ARY_MAX_SIZE - argc) { - mrb_raisef(mrb, E_INDEX_ERROR, "index %S too big", mrb_fixnum_value(alen + argc - len)); + mrb_raisef(mrb, E_INDEX_ERROR, "index %i too big", alen + argc - len); } newlen = alen + argc - len; if (newlen > ARY_CAPA(a)) { @@ -934,7 +934,7 @@ mrb_ary_aset(mrb_state *mrb, mrb_value self) mrb_ary_splice(mrb, self, i, len, v2); break; case MRB_RANGE_OUT: - mrb_raisef(mrb, E_RANGE_ERROR, "%S out of range", v1); + mrb_raisef(mrb, E_RANGE_ERROR, "%v out of range", v1); break; } return v2; diff --git a/src/backtrace.c b/src/backtrace.c index 991a67d00..c9a223e07 100644 --- a/src/backtrace.c +++ b/src/backtrace.c @@ -246,9 +246,7 @@ mrb_unpack_backtrace(mrb_state *mrb, mrb_value backtrace) mrb_value btline; if (entry->filename == NULL) continue; - btline = mrb_format(mrb, "%S:%S", - mrb_str_new_cstr(mrb, entry->filename), - mrb_fixnum_value(entry->lineno)); + btline = mrb_format(mrb, "%s:%d", entry->filename, entry->lineno); if (entry->method_id != 0) { mrb_str_cat_lit(mrb, btline, ":in "); mrb_str_cat_cstr(mrb, btline, mrb_sym2name(mrb, entry->method_id)); diff --git a/src/class.c b/src/class.c index 65d21ad4f..ff55de0e6 100644 --- a/src/class.c +++ b/src/class.c @@ -177,7 +177,7 @@ static void check_if_class_or_module(mrb_state *mrb, mrb_value obj) { if (!class_ptr_p(obj)) { - mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a class/module", mrb_inspect(mrb, obj)); + mrb_raisef(mrb, E_TYPE_ERROR, "%!v is not a class/module", obj); } } @@ -215,7 +215,7 @@ mrb_vm_define_module(mrb_state *mrb, mrb_value outer, mrb_sym id) mrb_value old = mrb_const_get(mrb, outer, id); if (mrb_type(old) != MRB_TT_MODULE) { - mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a module", mrb_inspect(mrb, old)); + mrb_raisef(mrb, E_TYPE_ERROR, "%!v is not a module", old); } return mrb_class_ptr(old); } @@ -248,9 +248,8 @@ define_class(mrb_state *mrb, mrb_sym name, struct RClass *super, struct RClass * c = class_from_sym(mrb, outer, name); MRB_CLASS_ORIGIN(c); if (super && mrb_class_real(c->super) != super) { - mrb_raisef(mrb, E_TYPE_ERROR, "superclass mismatch for Class %S (%S not %S)", - mrb_sym2str(mrb, name), - mrb_obj_value(c->super), mrb_obj_value(super)); + mrb_raisef(mrb, E_TYPE_ERROR, "superclass mismatch for Class %n (%C not %C)", + name, c->super, super); } return c; } @@ -265,7 +264,7 @@ MRB_API struct RClass* mrb_define_class_id(mrb_state *mrb, mrb_sym name, struct RClass *super) { if (!super) { - mrb_warn(mrb, "no super class for '%S', Object assumed", mrb_sym2str(mrb, name)); + mrb_warn(mrb, "no super class for '%n', Object assumed", name); } return define_class(mrb, name, super, mrb->object_class); } @@ -313,8 +312,7 @@ mrb_vm_define_class(mrb_state *mrb, mrb_value outer, mrb_value super, mrb_sym id if (!mrb_nil_p(super)) { if (mrb_type(super) != MRB_TT_CLASS) { - mrb_raisef(mrb, E_TYPE_ERROR, "superclass must be a Class (%S given)", - mrb_inspect(mrb, super)); + mrb_raisef(mrb, E_TYPE_ERROR, "superclass must be a Class (%!v given)", super); } s = mrb_class_ptr(super); } @@ -326,13 +324,13 @@ mrb_vm_define_class(mrb_state *mrb, mrb_value outer, mrb_value super, mrb_sym id mrb_value old = mrb_const_get(mrb, outer, id); if (mrb_type(old) != MRB_TT_CLASS) { - mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a class", mrb_inspect(mrb, old)); + mrb_raisef(mrb, E_TYPE_ERROR, "%!v is not a class", old); } c = mrb_class_ptr(old); if (s) { /* check super class */ if (mrb_class_real(c->super) != s) { - mrb_raisef(mrb, E_TYPE_ERROR, "superclass mismatch for class %S", old); + mrb_raisef(mrb, E_TYPE_ERROR, "superclass mismatch for class %v", old); } } return c; @@ -431,8 +429,7 @@ mrb_define_class_under(mrb_state *mrb, struct RClass *outer, const char *name, s #if 0 if (!super) { - mrb_warn(mrb, "no super class for '%S::%S', Object assumed", - mrb_obj_value(outer), mrb_sym2str(mrb, id)); + mrb_warn(mrb, "no super class for '%C::%n', Object assumed", outer, id); } #endif c = define_class(mrb, id, super, outer); @@ -489,8 +486,7 @@ mrb_notimplement(mrb_state *mrb) mrb_callinfo *ci = mrb->c->ci; if (ci->mid) { - mrb_value str = mrb_sym2str(mrb, ci->mid); - mrb_raisef(mrb, E_NOTIMP_ERROR, "%S() function is unimplemented on this machine", str); + mrb_raisef(mrb, E_NOTIMP_ERROR, "%n() function is unimplemented on this machine", ci->mid); } } @@ -505,7 +501,7 @@ mrb_notimplement_m(mrb_state *mrb, mrb_value self) #define CHECK_TYPE(mrb, val, t, c) do { \ if (mrb_type(val) != (t)) {\ - mrb_raisef(mrb, E_TYPE_ERROR, "expected %S", mrb_str_new_lit(mrb, c));\ + mrb_raisef(mrb, E_TYPE_ERROR, "expected %l", c, sizeof(c "")-1);\ }\ } while (0) @@ -669,7 +665,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) ss = ARGV[arg_i++]; if (!class_ptr_p(ss)) { - mrb_raisef(mrb, E_TYPE_ERROR, "%S is not class/module", ss); + mrb_raisef(mrb, E_TYPE_ERROR, "%v is not class/module", ss); } *p = ss; i++; @@ -816,7 +812,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) ss = ARGV[arg_i]; if (mrb_type(ss) != MRB_TT_ISTRUCT) { - mrb_raisef(mrb, E_TYPE_ERROR, "%S is not inline struct", ss); + mrb_raisef(mrb, E_TYPE_ERROR, "%v is not inline struct", ss); } *p = mrb_istruct_ptr(ss); arg_i++; @@ -964,7 +960,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) } break; default: - mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid argument specifier %S", mrb_str_new(mrb, &c, 1)); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid argument specifier %c", c); break; } } @@ -1357,8 +1353,7 @@ mrb_method_search(mrb_state *mrb, struct RClass* c, mrb_sym mid) if (mrb_string_p(inspect) && RSTRING_LEN(inspect) > 64) { inspect = mrb_any_to_s(mrb, mrb_obj_value(c)); } - mrb_name_error(mrb, mid, "undefined method '%S' for class %S", - mrb_sym2str(mrb, mid), inspect); + mrb_name_error(mrb, mid, "undefined method '%n' for class %v", mid, inspect); } return m; } @@ -1479,7 +1474,7 @@ mrb_instance_alloc(mrb_state *mrb, mrb_value cv) if (ttype == 0) ttype = MRB_TT_OBJECT; if (ttype <= MRB_TT_CPTR) { - mrb_raisef(mrb, E_TYPE_ERROR, "can't create instance of %S", cv); + mrb_raisef(mrb, E_TYPE_ERROR, "can't create instance of %v", cv); } o = (struct RObject*)mrb_obj_alloc(mrb, ttype, c); return mrb_obj_value(o); @@ -1706,7 +1701,7 @@ static void mrb_check_inheritable(mrb_state *mrb, struct RClass *super) { if (super->tt != MRB_TT_CLASS) { - mrb_raisef(mrb, E_TYPE_ERROR, "superclass must be a Class (%S given)", mrb_obj_value(super)); + mrb_raisef(mrb, E_TYPE_ERROR, "superclass must be a Class (%C given)", super); } if (super->tt == MRB_TT_SCLASS) { mrb_raise(mrb, E_TYPE_ERROR, "can't make subclass of singleton class"); @@ -1835,7 +1830,7 @@ void mrb_undef_method_id(mrb_state *mrb, struct RClass *c, mrb_sym a) { if (!mrb_obj_respond_to(mrb, c, a)) { - mrb_name_error(mrb, a, "undefined method '%S' for class '%S'", mrb_sym2str(mrb, a), mrb_obj_value(c)); + mrb_name_error(mrb, a, "undefined method '%n' for class '%C'", a, c); } else { mrb_method_t m; @@ -1878,7 +1873,7 @@ check_const_name_sym(mrb_state *mrb, mrb_sym id) mrb_int len; const char *name = mrb_sym2name_len(mrb, id, &len); if (!mrb_const_name_p(mrb, name, len)) { - mrb_name_error(mrb, id, "wrong constant name %S", mrb_sym2str(mrb, id)); + mrb_name_error(mrb, id, "wrong constant name %n", id); } } @@ -1935,7 +1930,7 @@ mrb_mod_const_get(mrb_state *mrb, mrb_value mod) else { off = end + 2; if (off == len) { /* trailing "::" */ - mrb_name_error(mrb, id, "wrong constant name '%S'", path); + mrb_name_error(mrb, id, "wrong constant name '%v'", path); } } } @@ -1965,7 +1960,7 @@ mrb_mod_remove_const(mrb_state *mrb, mrb_value mod) check_const_name_sym(mrb, id); val = mrb_iv_remove(mrb, mod, id); if (mrb_undef_p(val)) { - mrb_name_error(mrb, id, "constant %S not defined", mrb_sym2str(mrb, id)); + mrb_name_error(mrb, id, "constant %n not defined", id); } return val; } @@ -1978,13 +1973,10 @@ mrb_mod_const_missing(mrb_state *mrb, mrb_value mod) mrb_get_args(mrb, "n", &sym); if (mrb_class_real(mrb_class_ptr(mod)) != mrb->object_class) { - mrb_name_error(mrb, sym, "uninitialized constant %S::%S", - mod, - mrb_sym2str(mrb, sym)); + mrb_name_error(mrb, sym, "uninitialized constant %v::%n", mod, sym); } else { - mrb_name_error(mrb, sym, "uninitialized constant %S", - mrb_sym2str(mrb, sym)); + mrb_name_error(mrb, sym, "uninitialized constant %n", sym); } /* not reached */ return mrb_nil_value(); @@ -2045,7 +2037,7 @@ mod_define_method(mrb_state *mrb, mrb_value self) /* ignored */ break; default: - mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %S (expected Proc)", mrb_obj_value(mrb_obj_class(mrb, proc))); + mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %T (expected Proc)", proc); break; } if (mrb_nil_p(blk)) { diff --git a/src/error.c b/src/error.c index 0ca7f5917..664da3fd6 100644 --- a/src/error.c +++ b/src/error.c @@ -151,14 +151,14 @@ exc_inspect(mrb_state *mrb, mrb_value exc) str = mrb_str_new_cstr(mrb, cname); if (mrb_string_p(file) && mrb_fixnum_p(line)) { if (append_mesg) { - str = mrb_format(mrb, "%S:%S: %S (%S)", file, line, mesg, str); + str = mrb_format(mrb, "%v:%v: %v (%v)", file, line, mesg, str); } else { - str = mrb_format(mrb, "%S:%S: %S", file, line, str); + str = mrb_format(mrb, "%v:%v: %v", file, line, str); } } else if (append_mesg) { - str = mrb_format(mrb, "%S: %S", str, mesg); + str = mrb_format(mrb, "%v: %v", str, mesg); } return str; } @@ -523,7 +523,7 @@ exception_call: break; default: - mrb_raisef(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (%S for 0..3)", mrb_fixnum_value(argc)); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (%i for 0..3)", argc); break; } if (argc > 0) { @@ -576,8 +576,7 @@ mrb_no_method_error(mrb_state *mrb, mrb_sym id, mrb_value args, char const* fmt, MRB_API mrb_noreturn void mrb_frozen_error(mrb_state *mrb, void *frozen_obj) { - mrb_raisef(mrb, E_FROZEN_ERROR, "can't modify frozen %S", - mrb_obj_value(mrb_class(mrb, mrb_obj_value(frozen_obj)))); + mrb_raisef(mrb, E_FROZEN_ERROR, "can't modify frozen %t", mrb_obj_value(frozen_obj)); } void diff --git a/src/etc.c b/src/etc.c index 18d2839d9..bf6586748 100644 --- a/src/etc.c +++ b/src/etc.c @@ -31,14 +31,12 @@ mrb_data_check_type(mrb_state *mrb, mrb_value obj, const mrb_data_type *type) const mrb_data_type *t2 = DATA_TYPE(obj); if (t2) { - mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %S (expected %S)", - mrb_str_new_cstr(mrb, t2->struct_name), mrb_str_new_cstr(mrb, type->struct_name)); + mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %s (expected %s)", + t2->struct_name, type->struct_name); } else { - struct RClass *c = mrb_class(mrb, obj); - - mrb_raisef(mrb, E_TYPE_ERROR, "uninitialized %S (expected %S)", - mrb_obj_value(c), mrb_str_new_cstr(mrb, type->struct_name)); + mrb_raisef(mrb, E_TYPE_ERROR, "uninitialized %t (expected %s)", + obj, type->struct_name); } } } @@ -67,7 +65,7 @@ mrb_obj_to_sym(mrb_state *mrb, mrb_value name) { if (mrb_symbol_p(name)) return mrb_symbol(name); if (mrb_string_p(name)) return mrb_intern_str(mrb, name); - mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a symbol nor a string", mrb_inspect(mrb, name)); + mrb_raisef(mrb, E_TYPE_ERROR, "%!v is not a symbol nor a string", name); return 0; /* not reached */ } diff --git a/src/gc.c b/src/gc.c index b05d929a1..a7a67ebfa 100644 --- a/src/gc.c +++ b/src/gc.c @@ -542,7 +542,7 @@ mrb_obj_alloc(mrb_state *mrb, enum mrb_vtype ttype, struct RClass *cls) ttype != MRB_TT_ICLASS && ttype != MRB_TT_ENV && ttype != tt) { - mrb_raisef(mrb, E_TYPE_ERROR, "allocation failure of %S", mrb_obj_value(cls)); + mrb_raisef(mrb, E_TYPE_ERROR, "allocation failure of %C", cls); } } diff --git a/src/kernel.c b/src/kernel.c index f223be9fc..f0935a2f8 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -325,7 +325,7 @@ mrb_obj_clone(mrb_state *mrb, mrb_value self) mrb_value clone; if (mrb_immediate_p(self)) { - mrb_raisef(mrb, E_TYPE_ERROR, "can't clone %S", self); + mrb_raisef(mrb, E_TYPE_ERROR, "can't clone %v", self); } if (mrb_type(self) == MRB_TT_SCLASS) { mrb_raise(mrb, E_TYPE_ERROR, "can't clone singleton class"); @@ -366,7 +366,7 @@ mrb_obj_dup(mrb_state *mrb, mrb_value obj) mrb_value dup; if (mrb_immediate_p(obj)) { - mrb_raisef(mrb, E_TYPE_ERROR, "can't dup %S", obj); + mrb_raisef(mrb, E_TYPE_ERROR, "can't dup %v", obj); } if (mrb_type(obj) == MRB_TT_SCLASS) { mrb_raise(mrb, E_TYPE_ERROR, "can't dup singleton class"); @@ -641,7 +641,7 @@ mrb_obj_remove_instance_variable(mrb_state *mrb, mrb_value self) mrb_iv_name_sym_check(mrb, sym); val = mrb_iv_remove(mrb, self, sym); if (mrb_undef_p(val)) { - mrb_name_error(mrb, sym, "instance variable %S not defined", mrb_sym2str(mrb, sym)); + mrb_name_error(mrb, sym, "instance variable %n not defined", sym); } return val; } @@ -649,7 +649,7 @@ mrb_obj_remove_instance_variable(mrb_state *mrb, mrb_value self) void mrb_method_missing(mrb_state *mrb, mrb_sym name, mrb_value self, mrb_value args) { - mrb_no_method_error(mrb, name, args, "undefined method '%S'", mrb_sym2str(mrb, name)); + mrb_no_method_error(mrb, name, args, "undefined method '%n'", name); } /* 15.3.1.3.30 */ diff --git a/src/numeric.c b/src/numeric.c index b143b2f67..f96498106 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -1257,7 +1257,7 @@ mrb_flo_to_fixnum(mrb_state *mrb, mrb_value x) z = (mrb_int)d; } else { - mrb_raisef(mrb, E_RANGE_ERROR, "number (%S) too big for integer", x); + mrb_raisef(mrb, E_RANGE_ERROR, "number (%v) too big for integer", x); } } return mrb_fixnum_value(z); @@ -1389,7 +1389,7 @@ mrb_fixnum_to_str(mrb_state *mrb, mrb_value x, mrb_int base) mrb_int val = mrb_fixnum(x); if (base < 2 || 36 < base) { - mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid radix %S", mrb_fixnum_value(base)); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid radix %i", base); } if (val == 0) { @@ -1501,9 +1501,7 @@ integral_cmp(mrb_state *mrb, mrb_value self) static void cmperr(mrb_state *mrb, mrb_value v1, mrb_value v2) { - mrb_raisef(mrb, E_ARGUMENT_ERROR, "comparison of %S with %S failed", - mrb_obj_value(mrb_class(mrb, v1)), - mrb_obj_value(mrb_class(mrb, v2))); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "comparison of %t with %t failed", v1, v2); } static mrb_value diff --git a/src/object.c b/src/object.c index 7c1879019..ee36da320 100644 --- a/src/object.c +++ b/src/object.c @@ -296,17 +296,6 @@ mrb_init_object(mrb_state *mrb) mrb_define_method(mrb, f, "inspect", false_to_s, MRB_ARGS_NONE()); } -static mrb_value -inspect_type(mrb_state *mrb, mrb_value val) -{ - if (mrb_type(val) == MRB_TT_FALSE || mrb_type(val) == MRB_TT_TRUE) { - return mrb_inspect(mrb, val); - } - else { - return mrb_str_new_cstr(mrb, mrb_obj_classname(mrb, val)); - } -} - static mrb_value convert_type(mrb_state *mrb, mrb_value val, const char *tname, const char *method, mrb_bool raise) { @@ -315,7 +304,7 @@ convert_type(mrb_state *mrb, mrb_value val, const char *tname, const char *metho m = mrb_intern_cstr(mrb, method); if (!mrb_respond_to(mrb, val, m)) { if (raise) { - mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %S into %S", inspect_type(mrb, val), mrb_str_new_cstr(mrb, tname)); + mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %Y into %s", val, tname); } return mrb_nil_value(); } @@ -330,8 +319,7 @@ mrb_convert_type(mrb_state *mrb, mrb_value val, enum mrb_vtype type, const char if (mrb_type(val) == type) return val; v = convert_type(mrb, val, tname, method, TRUE); if (mrb_type(v) != type) { - mrb_raisef(mrb, E_TYPE_ERROR, "%S cannot be converted to %S by #%S", val, - mrb_str_new_cstr(mrb, tname), mrb_str_new_cstr(mrb, method)); + mrb_raisef(mrb, E_TYPE_ERROR, "%v cannot be converted to %s by #%s", val, tname, method); } return v; } @@ -405,13 +393,12 @@ mrb_check_type(mrb_state *mrb, mrb_value x, enum mrb_vtype t) else { etype = mrb_obj_classname(mrb, x); } - mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %S (expected %S)", - mrb_str_new_cstr(mrb, etype), mrb_str_new_cstr(mrb, type->name)); + mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %s (expected %s)", + etype, type->name); } type++; } - mrb_raisef(mrb, E_TYPE_ERROR, "unknown type %S (%S given)", - mrb_fixnum_value(t), mrb_fixnum_value(mrb_type(x))); + mrb_raisef(mrb, E_TYPE_ERROR, "unknown type %d (%d given)", t, mrb_type(x)); } } @@ -499,15 +486,12 @@ mrb_to_int(mrb_state *mrb, mrb_value val) { if (!mrb_fixnum_p(val)) { - mrb_value type; - #ifndef MRB_WITHOUT_FLOAT if (mrb_float_p(val)) { return mrb_flo_to_fixnum(mrb, val); } #endif - type = inspect_type(mrb, val); - mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %S to Integer", type); + mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %Y to Integer", val); } return val; } @@ -598,8 +582,7 @@ MRB_API mrb_value mrb_ensure_string_type(mrb_state *mrb, mrb_value str) { if (!mrb_string_p(str)) { - mrb_raisef(mrb, E_TYPE_ERROR, "%S cannot be converted to String", - inspect_type(mrb, str)); + mrb_raisef(mrb, E_TYPE_ERROR, "%Y cannot be converted to String", str); } return str; } @@ -615,8 +598,7 @@ MRB_API mrb_value mrb_ensure_array_type(mrb_state *mrb, mrb_value ary) { if (!mrb_array_p(ary)) { - mrb_raisef(mrb, E_TYPE_ERROR, "%S cannot be converted to Array", - inspect_type(mrb, ary)); + mrb_raisef(mrb, E_TYPE_ERROR, "%Y cannot be converted to Array", ary); } return ary; } @@ -632,8 +614,7 @@ MRB_API mrb_value mrb_ensure_hash_type(mrb_state *mrb, mrb_value hash) { if (!mrb_hash_p(hash)) { - mrb_raisef(mrb, E_TYPE_ERROR, "%S cannot be converted to Hash", - inspect_type(mrb, hash)); + mrb_raisef(mrb, E_TYPE_ERROR, "%Y cannot be converted to Hash", hash); } return hash; } diff --git a/src/proc.c b/src/proc.c index 094fff816..a0edf22bc 100644 --- a/src/proc.c +++ b/src/proc.c @@ -153,8 +153,8 @@ mrb_proc_cfunc_env_get(mrb_state *mrb, mrb_int idx) mrb_raise(mrb, E_TYPE_ERROR, "Can't get cfunc env from cfunc Proc without REnv."); } if (idx < 0 || MRB_ENV_STACK_LEN(e) <= idx) { - mrb_raisef(mrb, E_INDEX_ERROR, "Env index out of range: %S (expected: 0 <= index < %S)", - mrb_fixnum_value(idx), mrb_fixnum_value(MRB_ENV_STACK_LEN(e))); + mrb_raisef(mrb, E_INDEX_ERROR, "Env index out of range: %i (expected: 0 <= index < %i)", + idx, MRB_ENV_STACK_LEN(e)); } return e->stack[idx]; diff --git a/src/range.c b/src/range.c index c9dfb2b3c..28862d779 100644 --- a/src/range.c +++ b/src/range.c @@ -363,7 +363,7 @@ mrb_get_values_at(mrb_state *mrb, mrb_value obj, mrb_int olen, mrb_int argc, con } } else { - mrb_raisef(mrb, E_TYPE_ERROR, "invalid values selector: %S", argv[i]); + mrb_raisef(mrb, E_TYPE_ERROR, "invalid values selector: %v", argv[i]); } } diff --git a/src/string.c b/src/string.c index ecbe21a22..71c6e126e 100644 --- a/src/string.c +++ b/src/string.c @@ -1226,7 +1226,7 @@ mrb_str_aref_m(mrb_state *mrb, mrb_value str) static mrb_noreturn void str_out_of_index(mrb_state *mrb, mrb_value index) { - mrb_raisef(mrb, E_INDEX_ERROR, "index %S out of string", index); + mrb_raisef(mrb, E_INDEX_ERROR, "index %v out of string", index); } static mrb_value @@ -1286,7 +1286,7 @@ mrb_str_aset(mrb_state *mrb, mrb_value str, mrb_value indx, mrb_value alen, mrb_ mrb_raise(mrb, E_INDEX_ERROR, "string not matched"); case STR_CHAR_RANGE: if (len < 0) { - mrb_raisef(mrb, E_INDEX_ERROR, "negative length %S", alen); + mrb_raisef(mrb, E_INDEX_ERROR, "negative length %v", alen); } charlen = RSTRING_CHAR_LEN(str); if (beg < 0) { beg += charlen; } @@ -1763,7 +1763,7 @@ mrb_str_index_m(mrb_state *mrb, mrb_value str) tmp = mrb_check_string_type(mrb, sub); if (mrb_nil_p(tmp)) { - mrb_raisef(mrb, E_TYPE_ERROR, "type mismatch: %S given", sub); + mrb_raisef(mrb, E_TYPE_ERROR, "type mismatch: %v given", sub); } sub = tmp; } @@ -2014,7 +2014,7 @@ mrb_str_rindex(mrb_state *mrb, mrb_value str) tmp = mrb_check_string_type(mrb, sub); if (mrb_nil_p(tmp)) { - mrb_raisef(mrb, E_TYPE_ERROR, "type mismatch: %S given", sub); + mrb_raisef(mrb, E_TYPE_ERROR, "type mismatch: %v given", sub); } sub = tmp; } @@ -2265,7 +2265,7 @@ mrb_str_len_to_inum(mrb_state *mrb, const char *str, mrb_int len, mrb_int base, break; default: if (base < 2 || 36 < base) { - mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal radix %S", mrb_fixnum_value(base)); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal radix %i", base); } break; } /* end of switch (base) { */ @@ -2325,8 +2325,7 @@ mrb_str_len_to_inum(mrb_state *mrb, const char *str, mrb_int len, mrb_int base, else #endif { - mrb_raisef(mrb, E_RANGE_ERROR, "string (%S) too big for integer", - mrb_str_new(mrb, str, pend-str)); + mrb_raisef(mrb, E_RANGE_ERROR, "string (%l) too big for integer", str, pend-str); } } } @@ -2342,8 +2341,7 @@ mrb_str_len_to_inum(mrb_state *mrb, const char *str, mrb_int len, mrb_int base, mrb_raise(mrb, E_ARGUMENT_ERROR, "string contains null byte"); /* not reached */ bad: - mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid string for number(%S)", - mrb_inspect(mrb, mrb_str_new(mrb, str, pend-str))); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid string for number(%!l)", str, pend-str); /* not reached */ return mrb_fixnum_value(0); } @@ -2419,7 +2417,7 @@ mrb_str_to_i(mrb_state *mrb, mrb_value self) mrb_get_args(mrb, "|i", &base); if (base < 0) { - mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal radix %S", mrb_fixnum_value(base)); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal radix %i", base); } return mrb_str_to_inum(mrb, self, base, FALSE); } @@ -2444,7 +2442,7 @@ mrb_cstr_to_dbl(mrb_state *mrb, const char * p, mrb_bool badcheck) if (p == end) { if (badcheck) { bad: - mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid string for float(%S)", mrb_str_new_cstr(mrb, p)); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid string for float(%s)", p); /* not reached */ } return d; diff --git a/src/variable.c b/src/variable.c index e6f2f397e..32416da4e 100644 --- a/src/variable.c +++ b/src/variable.c @@ -446,7 +446,7 @@ MRB_API void mrb_iv_name_sym_check(mrb_state *mrb, mrb_sym iv_name) { if (!mrb_iv_name_sym_p(mrb, iv_name)) { - mrb_name_error(mrb, iv_name, "'%S' is not allowed as an instance variable name", mrb_sym2str(mrb, iv_name)); + mrb_name_error(mrb, iv_name, "'%n' is not allowed as an instance variable name", iv_name); } } @@ -654,8 +654,7 @@ mrb_mod_cv_get(mrb_state *mrb, struct RClass *c, mrb_sym sym) if (given) return v; } } - mrb_name_error(mrb, sym, "uninitialized class variable %S in %S", - mrb_sym2str(mrb, sym), mrb_obj_value(cls)); + mrb_name_error(mrb, sym, "uninitialized class variable %n in %C", sym, cls); /* not reached */ return mrb_nil_value(); } diff --git a/src/vm.c b/src/vm.c index 86262650e..12805a8e4 100644 --- a/src/vm.c +++ b/src/vm.c @@ -461,7 +461,7 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc stack_init(mrb); } if (argc < 0) { - mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative argc for funcall (%S)", mrb_fixnum_value(argc)); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative argc for funcall (%i)", argc); } c = mrb_class(mrb, self); m = mrb_method_search_vm(mrb, &c, mid); @@ -878,13 +878,11 @@ argnum_error(mrb_state *mrb, mrb_int num) } } if (mrb->c->ci->mid) { - str = mrb_format(mrb, "'%S': wrong number of arguments (%S for %S)", - mrb_sym2str(mrb, mrb->c->ci->mid), - mrb_fixnum_value(argc), mrb_fixnum_value(num)); + str = mrb_format(mrb, "'%n': wrong number of arguments (%i for %i)", + mrb->c->ci->mid, argc, num); } else { - str = mrb_format(mrb, "wrong number of arguments (%S for %S)", - mrb_fixnum_value(argc), mrb_fixnum_value(num)); + str = mrb_format(mrb, "wrong number of arguments (%i for %i)", argc, num); } exc = mrb_exc_new_str(mrb, E_ARGUMENT_ERROR, str); mrb_exc_set(mrb, exc); @@ -1868,7 +1866,7 @@ RETRY_TRY_BLOCK: mrb_value kdict = regs[mrb->c->ci->argc]; if (!mrb_hash_p(kdict) || !mrb_hash_key_p(mrb, kdict, k)) { - mrb_value str = mrb_format(mrb, "missing keyword: %S", k); + mrb_value str = mrb_format(mrb, "missing keyword: %v", k); mrb_exc_set(mrb, mrb_exc_new_str(mrb, E_ARGUMENT_ERROR, str)); goto L_RAISE; } @@ -1895,7 +1893,7 @@ RETRY_TRY_BLOCK: if (mrb_hash_p(kdict) && !mrb_hash_empty_p(mrb, kdict)) { mrb_value keys = mrb_hash_keys(mrb, kdict); mrb_value key1 = RARRAY_PTR(keys)[0]; - mrb_value str = mrb_format(mrb, "unknown keyword: %S", key1); + mrb_value str = mrb_format(mrb, "unknown keyword: %v", key1); mrb_exc_set(mrb, mrb_exc_new_str(mrb, E_ARGUMENT_ERROR, str)); goto L_RAISE; } diff --git a/tasks/toolchains/visualcpp.rake b/tasks/toolchains/visualcpp.rake index 9bf0f085e..6275059bb 100644 --- a/tasks/toolchains/visualcpp.rake +++ b/tasks/toolchains/visualcpp.rake @@ -2,7 +2,7 @@ MRuby::Toolchain.new(:visualcpp) do |conf, _params| conf.cc do |cc| cc.command = ENV['CC'] || 'cl.exe' # C4013: implicit function declaration - cc.flags = [ENV['CFLAGS'] || %w(/c /nologo /W3 /we4013 /Zi /Zm2000 /MD /O2 /D_CRT_SECURE_NO_WARNINGS)] + cc.flags = [ENV['CFLAGS'] || %w(/c /nologo /W3 /we4013 /Zi /MD /O2 /D_CRT_SECURE_NO_WARNINGS)] cc.defines = %w(MRB_STACK_EXTEND_DOUBLING) cc.option_include_path = '/I%s' cc.option_define = '/D%s' -- cgit v1.2.3 From 98fc887cb3d9458313cc275c4176d16e95c7c0c2 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 7 Aug 2019 15:40:44 +0900 Subject: Reorganize `mrb_string_value_cstr` and related functions. `mrb_string_value_cstr` and `mrb_string_value_len`: obsolete `mrb_string_cstr`: new function to retrieve NULL terminated C string `RSTRING_CSTR`: wrapper macro of `mrb_string_cstr` --- include/mruby/string.h | 16 +++++++--------- mrbgems/mruby-io/src/file.c | 20 ++++++++++---------- mrbgems/mruby-io/src/file_test.c | 2 +- mrbgems/mruby-io/src/io.c | 16 ++++++++-------- mrbgems/mruby-socket/src/socket.c | 4 ++-- mrbgems/mruby-test/vformat.c | 2 +- src/class.c | 2 +- src/string.c | 28 +++++++++++++++++++--------- 8 files changed, 49 insertions(+), 41 deletions(-) (limited to 'src/string.c') diff --git a/include/mruby/string.h b/include/mruby/string.h index d17ac1c1d..7266c9084 100644 --- a/include/mruby/string.h +++ b/include/mruby/string.h @@ -96,6 +96,7 @@ struct RString { #define RSTRING_CAPA(s) RSTR_CAPA(RSTRING(s)) #define RSTRING_END(s) (RSTRING_PTR(s) + RSTRING_LEN(s)) MRB_API mrb_int mrb_str_strlen(mrb_state*, struct RString*); +#define RSTRING_CSTR(mrb,s) mrb_string_cstr(mrb, s) #define MRB_STR_SHARED 1 #define MRB_STR_FSHARED 2 @@ -337,16 +338,13 @@ MRB_API mrb_value mrb_string_type(mrb_state *mrb, mrb_value str); MRB_API mrb_value mrb_str_new_capa(mrb_state *mrb, size_t capa); MRB_API mrb_value mrb_str_buf_new(mrb_state *mrb, size_t capa); -MRB_API const char *mrb_string_value_cstr(mrb_state *mrb, mrb_value *ptr); +/* NULL terminated C string from mrb_value */ +MRB_API const char *mrb_string_cstr(mrb_state *mrb, mrb_value str); +/* NULL terminated C string from mrb_value; `str` will be updated */ +MRB_API const char *mrb_string_value_cstr(mrb_state *mrb, mrb_value *str); +/* obslete: use RSTRING_PTR() */ MRB_API const char *mrb_string_value_ptr(mrb_state *mrb, mrb_value str); -/* - * Returns the length of the Ruby string. - * - * - * @param [mrb_state] mrb The current mruby state. - * @param [mrb_value] str Ruby string. - * @return [mrb_int] The length of the passed in Ruby string. - */ +/* obslete: use RSTRING_LEN() */ MRB_API mrb_int mrb_string_value_len(mrb_state *mrb, mrb_value str); /* diff --git a/mrbgems/mruby-io/src/file.c b/mrbgems/mruby-io/src/file.c index 5e6c849f0..2fbda90af 100644 --- a/mrbgems/mruby-io/src/file.c +++ b/mrbgems/mruby-io/src/file.c @@ -116,7 +116,7 @@ mrb_file_s_unlink(mrb_state *mrb, mrb_value obj) for (i = 0; i < argc; i++) { const char *utf8_path; pathv = mrb_ensure_string_type(mrb, argv[i]); - utf8_path = mrb_string_value_cstr(mrb, &pathv); + utf8_path = RSTRING_CSTR(mrb, pathv); path = mrb_locale_from_utf8(utf8_path, -1); if (UNLINK(path) < 0) { mrb_locale_free(path); @@ -134,8 +134,8 @@ mrb_file_s_rename(mrb_state *mrb, mrb_value obj) char *src, *dst; mrb_get_args(mrb, "SS", &from, &to); - src = mrb_locale_from_utf8(mrb_string_value_cstr(mrb, &from), -1); - dst = mrb_locale_from_utf8(mrb_string_value_cstr(mrb, &to), -1); + src = mrb_locale_from_utf8(RSTRING_CSTR(mrb, from), -1); + dst = mrb_locale_from_utf8(RSTRING_CSTR(mrb, to), -1); if (rename(src, dst) < 0) { #if defined(_WIN32) || defined(_WIN64) if (CHMOD(dst, 0666) == 0 && UNLINK(dst) == 0 && rename(src, dst) == 0) { @@ -146,7 +146,7 @@ mrb_file_s_rename(mrb_state *mrb, mrb_value obj) #endif mrb_locale_free(src); mrb_locale_free(dst); - mrb_sys_fail(mrb, RSTRING_PTR(mrb_format(mrb, "(%v, %v)", from, to))); + mrb_sys_fail(mrb, RSTRING_CSTR(mrb, mrb_format(mrb, "(%v, %v)", from, to))); } mrb_locale_free(src); mrb_locale_free(dst); @@ -248,7 +248,7 @@ mrb_file_realpath(mrb_state *mrb, mrb_value klass) s = mrb_str_append(mrb, s, pathname); pathname = s; } - cpath = mrb_locale_from_utf8(mrb_string_value_cstr(mrb, &pathname), -1); + cpath = mrb_locale_from_utf8(RSTRING_CSTR(mrb, pathname), -1); result = mrb_str_buf_new(mrb, PATH_MAX); if (realpath(cpath, RSTRING_PTR(result)) == NULL) { mrb_locale_free(cpath); @@ -300,7 +300,7 @@ mrb_file__gethome(mrb_state *mrb, mrb_value klass) mrb_raise(mrb, E_ARGUMENT_ERROR, "non-absolute home"); } } else { - const char *cuser = mrb_string_value_cstr(mrb, &username); + const char *cuser = RSTRING_CSTR(mrb, username); struct passwd *pwd = getpwnam(cuser); if (pwd == NULL) { return mrb_nil_value(); @@ -393,12 +393,12 @@ mrb_file_s_symlink(mrb_state *mrb, mrb_value klass) int ai = mrb_gc_arena_save(mrb); mrb_get_args(mrb, "SS", &from, &to); - src = mrb_locale_from_utf8(mrb_string_value_cstr(mrb, &from), -1); - dst = mrb_locale_from_utf8(mrb_string_value_cstr(mrb, &to), -1); + src = mrb_locale_from_utf8(RSTRING_CSTR(mrb, from), -1); + dst = mrb_locale_from_utf8(RSTRING_CSTR(mrb, to), -1); if (symlink(src, dst) == -1) { mrb_locale_free(src); mrb_locale_free(dst); - mrb_sys_fail(mrb, RSTRING_PTR(mrb_format(mrb, "(%v, %v)", from, to))); + mrb_sys_fail(mrb, RSTRING_CSTR(mrb, mrb_format(mrb, "(%v, %v)", from, to))); } mrb_locale_free(src); mrb_locale_free(dst); @@ -416,7 +416,7 @@ mrb_file_s_chmod(mrb_state *mrb, mrb_value klass) { mrb_get_args(mrb, "i*", &mode, &filenames, &argc); for (i = 0; i < argc; i++) { - const char *utf8_path = mrb_string_value_cstr(mrb, &filenames[i]); + const char *utf8_path = RSTRING_CSTR(mrb, filenames[i]); char *path = mrb_locale_from_utf8(utf8_path, -1); if (CHMOD(path, mode) == -1) { mrb_locale_free(path); diff --git a/mrbgems/mruby-io/src/file_test.c b/mrbgems/mruby-io/src/file_test.c index 85a221ff9..445bafde9 100644 --- a/mrbgems/mruby-io/src/file_test.c +++ b/mrbgems/mruby-io/src/file_test.c @@ -54,7 +54,7 @@ mrb_stat0(mrb_state *mrb, mrb_value obj, struct stat *st, int do_lstat) return -1; } else { - char *path = mrb_locale_from_utf8(mrb_string_value_cstr(mrb, &obj), -1); + char *path = mrb_locale_from_utf8(RSTRING_CSTR(mrb, obj), -1); int ret; if (do_lstat) { ret = LSTAT(path, st); diff --git a/mrbgems/mruby-io/src/io.c b/mrbgems/mruby-io/src/io.c index a43ebcb91..eb9c4097b 100644 --- a/mrbgems/mruby-io/src/io.c +++ b/mrbgems/mruby-io/src/io.c @@ -332,8 +332,8 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass) mrb_get_args(mrb, "S|SH", &cmd, &mode, &opt); io = mrb_obj_value(mrb_data_object_alloc(mrb, mrb_class_ptr(klass), NULL, &mrb_io_type)); - pname = mrb_string_value_cstr(mrb, &cmd); - flags = mrb_io_modestr_to_flags(mrb, mrb_string_value_cstr(mrb, &mode)); + pname = RSTRING_CSTR(mrb, cmd); + flags = mrb_io_modestr_to_flags(mrb, RSTRING_CSTR(mrb, mode)); doexec = (strcmp("-", pname) != 0); opt_in = option_to_fd(mrb, opt, "in"); @@ -428,8 +428,8 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass) mrb_get_args(mrb, "S|SH", &cmd, &mode, &opt); io = mrb_obj_value(mrb_data_object_alloc(mrb, mrb_class_ptr(klass), NULL, &mrb_io_type)); - pname = mrb_string_value_cstr(mrb, &cmd); - flags = mrb_io_modestr_to_flags(mrb, mrb_string_value_cstr(mrb, &mode)); + pname = RSTRING_CSTR(mrb, cmd); + flags = mrb_io_modestr_to_flags(mrb, RSTRING_CSTR(mrb, mode)); doexec = (strcmp("-", pname) != 0); opt_in = option_to_fd(mrb, opt, "in"); @@ -626,7 +626,7 @@ mrb_io_initialize(mrb_state *mrb, mrb_value io) opt = mrb_hash_new(mrb); } - flags = mrb_io_modestr_to_flags(mrb, mrb_string_value_cstr(mrb, &mode)); + flags = mrb_io_modestr_to_flags(mrb, RSTRING_CSTR(mrb, mode)); mrb_iv_set(mrb, io, mrb_intern_cstr(mrb, "@buf"), mrb_str_new_cstr(mrb, "")); @@ -780,7 +780,7 @@ reopen: } } - mrb_sys_fail(mrb, RSTRING_PTR(mrb_format(mrb, "open %s", pathname))); + mrb_sys_fail(mrb, RSTRING_CSTR(mrb, mrb_format(mrb, "open %s", pathname))); } mrb_locale_free(fname); @@ -807,8 +807,8 @@ mrb_io_s_sysopen(mrb_state *mrb, mrb_value klass) perm = 0666; } - pat = mrb_string_value_cstr(mrb, &path); - flags = mrb_io_modestr_to_flags(mrb, mrb_string_value_cstr(mrb, &mode)); + pat = RSTRING_CSTR(mrb, path); + flags = mrb_io_modestr_to_flags(mrb, RSTRING_CSTR(mrb, mode)); modenum = mrb_io_flags_to_modenum(mrb, flags); fd = mrb_cloexec_open(mrb, pat, modenum, perm); return mrb_fixnum_value(fd); diff --git a/mrbgems/mruby-socket/src/socket.c b/mrbgems/mruby-socket/src/socket.c index eaca27779..53f761617 100644 --- a/mrbgems/mruby-socket/src/socket.c +++ b/mrbgems/mruby-socket/src/socket.c @@ -131,7 +131,7 @@ mrb_addrinfo_getaddrinfo(mrb_state *mrb, mrb_value klass) mrb_get_args(mrb, "oo|oooi", &nodename, &service, &family, &socktype, &protocol, &flags); if (mrb_string_p(nodename)) { - hostname = mrb_string_value_cstr(mrb, &nodename); + hostname = RSTRING_CSTR(mrb, nodename); } else if (mrb_nil_p(nodename)) { hostname = NULL; } else { @@ -139,7 +139,7 @@ mrb_addrinfo_getaddrinfo(mrb_state *mrb, mrb_value klass) } if (mrb_string_p(service)) { - servname = mrb_string_value_cstr(mrb, &service); + servname = RSTRING_CSTR(mrb, service); } else if (mrb_fixnum_p(service)) { servname = RSTRING_PTR(mrb_fixnum_to_str(mrb, service, 10)); } else if (mrb_nil_p(service)) { diff --git a/mrbgems/mruby-test/vformat.c b/mrbgems/mruby-test/vformat.c index 6e0c2887f..6984aaeb1 100644 --- a/mrbgems/mruby-test/vformat.c +++ b/mrbgems/mruby-test/vformat.c @@ -166,7 +166,7 @@ vf_s_format(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 = mrb_string_value_cstr(mrb, &fmt_str); + const char *fmt = RSTRING_CSTR(mrb, fmt_str); VF_FORMAT_INIT(klass); diff --git a/src/class.c b/src/class.c index ff55de0e6..5b190d28b 100644 --- a/src/class.c +++ b/src/class.c @@ -770,7 +770,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) } if (i < argc) { ss = to_str(mrb, ARGV[arg_i++]); - *ps = mrb_string_value_cstr(mrb, &ss); + *ps = RSTRING_CSTR(mrb, ss); i++; } } diff --git a/src/string.c b/src/string.c index 71c6e126e..50c283593 100644 --- a/src/string.c +++ b/src/string.c @@ -1060,6 +1060,7 @@ mrb_str_to_str(mrb_state *mrb, mrb_value str) } } +/* obslete: use RSTRING_PTR() */ MRB_API const char* mrb_string_value_ptr(mrb_state *mrb, mrb_value str) { @@ -1067,6 +1068,7 @@ mrb_string_value_ptr(mrb_state *mrb, mrb_value str) return RSTRING_PTR(str); } +/* obslete: use RSTRING_LEN() */ MRB_API mrb_int mrb_string_value_len(mrb_state *mrb, mrb_value ptr) { @@ -2352,6 +2354,7 @@ mrb_cstr_to_inum(mrb_state *mrb, const char *str, mrb_int base, mrb_bool badchec return mrb_str_len_to_inum(mrb, str, strlen(str), base, badcheck); } +/* obslete: use RSTRING_CSTR() or mrb_string_cstr() */ MRB_API const char* mrb_string_value_cstr(mrb_state *mrb, mrb_value *ptr) { @@ -2366,16 +2369,23 @@ mrb_string_value_cstr(mrb_state *mrb, mrb_value *ptr) if (p[len] == '\0') { return p; } + if (MRB_FROZEN_P(ps) || RSTR_CAPA(ps) == len) { + ps = str_new(mrb, NULL, len+1); + memcpy(RSTR_PTR(ps), p, len); + RSTR_SET_LEN(ps, len); + *ptr = mrb_obj_value(ps); + } else { - if (MRB_FROZEN_P(ps)) { - ps = str_new(mrb, p, len); - *ptr = mrb_obj_value(ps); - } - else { - mrb_str_modify(mrb, ps); - } - return RSTR_PTR(ps); + mrb_str_modify(mrb, ps); } + RSTR_PTR(ps)[len] = '\0'; + return RSTR_PTR(ps); +} + +MRB_API const char* +mrb_string_cstr(mrb_state *mrb, mrb_value str) +{ + return mrb_string_value_cstr(mrb, &str); } MRB_API mrb_value @@ -2489,7 +2499,7 @@ bad: MRB_API double mrb_str_to_dbl(mrb_state *mrb, mrb_value str, mrb_bool badcheck) { - return mrb_cstr_to_dbl(mrb, mrb_string_value_cstr(mrb, &str), badcheck); + return mrb_cstr_to_dbl(mrb, RSTRING_CSTR(mrb, str), badcheck); } /* 15.2.10.5.39 */ -- cgit v1.2.3 From b377b7d58062d555cc45249ae038c8b2875eec9e Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 7 Aug 2019 16:20:40 +0900 Subject: Update `mrb_to_str` and related functions. Contrary to the name, `mrb_to_str` just checks type, no conversion. --- include/mruby.h | 1 + src/class.c | 23 +++++------------------ src/string.c | 5 +++-- 3 files changed, 9 insertions(+), 20 deletions(-) (limited to 'src/string.c') diff --git a/include/mruby.h b/include/mruby.h index 7deb3cbe2..55505a213 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -1186,6 +1186,7 @@ MRB_API void mrb_gc_unregister(mrb_state *mrb, mrb_value obj); MRB_API mrb_value mrb_to_int(mrb_state *mrb, mrb_value val); #define mrb_int(mrb, val) mrb_fixnum(mrb_to_int(mrb, val)) +/* string type checking (contrary to the name, it doesn't convert) */ MRB_API mrb_value mrb_to_str(mrb_state *mrb, mrb_value val); MRB_API void mrb_check_type(mrb_state *mrb, mrb_value x, enum mrb_vtype t); diff --git a/src/class.c b/src/class.c index 5b190d28b..f66c5794d 100644 --- a/src/class.c +++ b/src/class.c @@ -499,30 +499,17 @@ mrb_notimplement_m(mrb_state *mrb, mrb_value self) return mrb_nil_value(); } -#define CHECK_TYPE(mrb, val, t, c) do { \ - if (mrb_type(val) != (t)) {\ - mrb_raisef(mrb, E_TYPE_ERROR, "expected %l", c, sizeof(c "")-1);\ - }\ -} while (0) - -static mrb_value -to_str(mrb_state *mrb, mrb_value val) -{ - CHECK_TYPE(mrb, val, MRB_TT_STRING, "String"); - return val; -} - static mrb_value to_ary(mrb_state *mrb, mrb_value val) { - CHECK_TYPE(mrb, val, MRB_TT_ARRAY, "Array"); + mrb_check_type(mrb, val, MRB_TT_ARRAY); return val; } static mrb_value to_hash(mrb_state *mrb, mrb_value val) { - CHECK_TYPE(mrb, val, MRB_TT_HASH, "Hash"); + mrb_check_type(mrb, val, MRB_TT_HASH); return val; } @@ -686,7 +673,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) } } if (i < argc) { - *p = to_str(mrb, ARGV[arg_i++]); + *p = mrb_to_str(mrb, ARGV[arg_i++]); i++; } } @@ -747,7 +734,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) } } if (i < argc) { - ss = to_str(mrb, ARGV[arg_i++]); + ss = mrb_to_str(mrb, ARGV[arg_i++]); *ps = RSTRING_PTR(ss); *pl = RSTRING_LEN(ss); i++; @@ -769,7 +756,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) } } if (i < argc) { - ss = to_str(mrb, ARGV[arg_i++]); + ss = mrb_to_str(mrb, ARGV[arg_i++]); *ps = RSTRING_CSTR(mrb, ss); i++; } diff --git a/src/string.c b/src/string.c index 50c283593..daf293368 100644 --- a/src/string.c +++ b/src/string.c @@ -1280,7 +1280,7 @@ mrb_str_aset(mrb_state *mrb, mrb_value str, mrb_value indx, mrb_value alen, mrb_ { mrb_int beg, len, charlen; - replace = mrb_to_str(mrb, replace); + mrb_to_str(mrb, replace); switch (str_convert_range(mrb, str, indx, alen, &beg, &len)) { case STR_OUT_OF_RANGE: @@ -2394,7 +2394,8 @@ mrb_str_to_inum(mrb_state *mrb, mrb_value str, mrb_int base, mrb_bool badcheck) const char *s; mrb_int len; - s = mrb_string_value_ptr(mrb, str); + mrb_to_str(mrb, str); + s = RSTRING_PTR(str); len = RSTRING_LEN(str); return mrb_str_len_to_inum(mrb, s, len, base, badcheck); } -- cgit v1.2.3 From 450684ab33f3b13bde520f831f857fe1e7dc5fd6 Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Sun, 11 Aug 2019 20:48:37 +0900 Subject: `mrb_str_modify_keep_ascii` can embed one more byte The condition to make an embedded string was incorrect. Because there were several similar codes, extracted into `RSTR_EMBEDDABLE_P` macro. --- include/mruby/string.h | 2 ++ src/string.c | 12 ++++++------ 2 files changed, 8 insertions(+), 6 deletions(-) (limited to 'src/string.c') diff --git a/include/mruby/string.h b/include/mruby/string.h index 7266c9084..aacbdbfc0 100644 --- a/include/mruby/string.h +++ b/include/mruby/string.h @@ -52,6 +52,8 @@ struct RString { } while (0) #define RSTR_EMBED_LEN(s)\ (mrb_int)(((s)->flags & MRB_STR_EMBED_LEN_MASK) >> MRB_STR_EMBED_LEN_SHIFT) +#define RSTR_EMBEDDABLE_P(len) ((len) <= RSTRING_EMBED_LEN_MAX) + #define RSTR_PTR(s) ((RSTR_EMBED_P(s)) ? (s)->as.ary : (s)->as.heap.ptr) #define RSTR_LEN(s) ((RSTR_EMBED_P(s)) ? RSTR_EMBED_LEN(s) : (s)->as.heap.len) #define RSTR_CAPA(s) (RSTR_EMBED_P(s) ? RSTRING_EMBED_LEN_MAX : (s)->as.heap.aux.capa) diff --git a/src/string.c b/src/string.c index daf293368..a6031b0ef 100644 --- a/src/string.c +++ b/src/string.c @@ -60,7 +60,7 @@ str_new(mrb_state *mrb, const char *p, size_t len) return str_new_static(mrb, p, len); } s = mrb_obj_alloc_string(mrb); - if (len <= RSTRING_EMBED_LEN_MAX) { + if (RSTR_EMBEDDABLE_P(len)) { RSTR_SET_EMBED_FLAG(s); RSTR_SET_EMBED_LEN(s, len); if (p) { @@ -135,7 +135,7 @@ resize_capa(mrb_state *mrb, struct RString *s, size_t capacity) mrb_assert(capacity < MRB_INT_MAX); #endif if (RSTR_EMBED_P(s)) { - if (RSTRING_EMBED_LEN_MAX < capacity) { + if (!RSTR_EMBEDDABLE_P(capacity)) { char *const tmp = (char *)mrb_malloc(mrb, capacity+1); const mrb_int len = RSTR_EMBED_LEN(s); memcpy(tmp, s->as.ary, len); @@ -478,7 +478,7 @@ mrb_str_byte_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len) struct RString *orig, *s; orig = mrb_str_ptr(str); - if (RSTR_EMBED_P(orig) || RSTR_LEN(orig) == 0 || len <= RSTRING_EMBED_LEN_MAX) { + if (RSTR_EMBED_P(orig) || RSTR_LEN(orig) == 0 || RSTR_EMBEDDABLE_P(len)) { s = str_new(mrb, RSTR_PTR(orig)+beg, len); } else { @@ -588,7 +588,7 @@ str_replace(mrb_state *mrb, struct RString *s1, struct RString *s2) RSTR_UNSET_FSHARED_FLAG(s1); RSTR_UNSET_NOFREE_FLAG(s1); - if (len <= RSTRING_EMBED_LEN_MAX) { + if (RSTR_EMBEDDABLE_P(len)) { RSTR_UNSET_SHARED_FLAG(s1); RSTR_UNSET_FSHARED_FLAG(s1); RSTR_SET_EMBED_FLAG(s1); @@ -728,7 +728,7 @@ mrb_str_modify_keep_ascii(mrb_state *mrb, struct RString *s) p = RSTR_PTR(s); len = s->as.heap.len; - if (len < RSTRING_EMBED_LEN_MAX) { + if (RSTR_EMBEDDABLE_P(len)) { RSTR_SET_EMBED_FLAG(s); RSTR_SET_EMBED_LEN(s, len); ptr = RSTR_PTR(s); @@ -754,7 +754,7 @@ mrb_str_modify_keep_ascii(mrb_state *mrb, struct RString *s) RSTR_UNSET_FSHARED_FLAG(s); RSTR_UNSET_NOFREE_FLAG(s); RSTR_UNSET_FSHARED_FLAG(s); - if (len < RSTRING_EMBED_LEN_MAX) { + if (RSTR_EMBEDDABLE_P(len)) { RSTR_SET_EMBED_FLAG(s); RSTR_SET_EMBED_LEN(s, len); } -- cgit v1.2.3 From 70b53f91c258e23fc5d68dd8f9c7cf5b8e0290f6 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sun, 11 Aug 2019 21:53:23 +0900 Subject: Add `NUL` always to short strings; ref 98fc887 --- src/string.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/string.c') diff --git a/src/string.c b/src/string.c index daf293368..0abc07000 100644 --- a/src/string.c +++ b/src/string.c @@ -594,6 +594,7 @@ str_replace(mrb_state *mrb, struct RString *s1, struct RString *s2) RSTR_SET_EMBED_FLAG(s1); memcpy(s1->as.ary, RSTR_PTR(s2), len); RSTR_SET_EMBED_LEN(s1, len); + RSTR_PTR(s1)[len] = '\0'; } else { str_make_shared(mrb, s2, s1); -- cgit v1.2.3 From 285ce9d8aa9ecfd7b749ae02784a2ba68290293a Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 12 Aug 2019 16:51:01 +0900 Subject: Replacing region may overwrap with the target region; fix #4627 --- src/string.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/string.c') diff --git a/src/string.c b/src/string.c index 0abc07000..1d2f0dec0 100644 --- a/src/string.c +++ b/src/string.c @@ -1264,7 +1264,7 @@ str_replace_partial(mrb_state *mrb, mrb_value src, mrb_int pos, mrb_int end, mrb memmove(strp + newlen - (len - end), strp + end, len - end); if (!mrb_nil_p(rep)) { - memcpy(strp + pos, RSTRING_PTR(rep), replen); + memmove(strp + pos, RSTRING_PTR(rep), replen); } RSTR_SET_LEN(str, newlen); strp[newlen] = '\0'; -- cgit v1.2.3 From 7af0ee099de91214c9f98a019de0fb25b86f911f Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Tue, 13 Aug 2019 22:40:30 +0900 Subject: Extract `struct RString` initialization code to function --- src/string.c | 100 ++++++++++++++++++++++++++--------------------------------- 1 file changed, 44 insertions(+), 56 deletions(-) (limited to 'src/string.c') diff --git a/src/string.c b/src/string.c index 7d3480d2a..21a42a584 100644 --- a/src/string.c +++ b/src/string.c @@ -34,6 +34,33 @@ const char mrb_digitmap[] = "0123456789abcdefghijklmnopqrstuvwxyz"; #define mrb_obj_alloc_string(mrb) ((struct RString*)mrb_obj_alloc((mrb), MRB_TT_STRING, (mrb)->string_class)) +static void +str_init_normal_capa(mrb_state *mrb, struct RString *s, + const char *p, size_t len, size_t capa) +{ + char *dst = (char *)mrb_malloc(mrb, capa + 1); + if (p) memcpy(dst, p, len); + dst[len] = '\0'; + s->as.heap.ptr = dst; + s->as.heap.len = (mrb_int)len; + s->as.heap.aux.capa = (mrb_int)capa; +} + +static void +str_init_normal(mrb_state *mrb, struct RString *s, const char *p, size_t len) +{ + str_init_normal_capa(mrb, s, p, len, len); +} + +static void +str_init_embed(struct RString *s, const char *p, size_t len) +{ + if (p) memcpy(s->as.ary, p, len); + s->as.ary[len] = '\0'; + RSTR_SET_EMBED_FLAG(s); + RSTR_SET_EMBED_LEN(s, len); +} + static struct RString* str_new_static(mrb_state *mrb, const char *p, size_t len) { @@ -61,24 +88,14 @@ str_new(mrb_state *mrb, const char *p, size_t len) } s = mrb_obj_alloc_string(mrb); if (RSTR_EMBEDDABLE_P(len)) { - RSTR_SET_EMBED_FLAG(s); - RSTR_SET_EMBED_LEN(s, len); - if (p) { - memcpy(s->as.ary, p, len); - } + str_init_embed(s, p, len); + } + else if (len >= MRB_INT_MAX) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big"); } else { - if (len >= MRB_INT_MAX) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big"); - } - s->as.heap.ptr = (char *)mrb_malloc(mrb, len+1); - s->as.heap.len = (mrb_int)len; - s->as.heap.aux.capa = (mrb_int)len; - if (p) { - memcpy(s->as.heap.ptr, p, len); - } + str_init_normal(mrb, s, p, len); } - RSTR_PTR(s)[len] = '\0'; return s; } @@ -107,10 +124,7 @@ mrb_str_new_capa(mrb_state *mrb, size_t capa) if (capa >= MRB_INT_MAX) { mrb_raise(mrb, E_ARGUMENT_ERROR, "string capacity size too big"); } - s->as.heap.len = 0; - s->as.heap.aux.capa = (mrb_int)capa; - s->as.heap.ptr = (char *)mrb_malloc(mrb, capa+1); - RSTR_PTR(s)[0] = '\0'; + str_init_normal_capa(mrb, s, NULL, 0, capa); return mrb_obj_value(s); } @@ -136,13 +150,8 @@ resize_capa(mrb_state *mrb, struct RString *s, size_t capacity) #endif if (RSTR_EMBED_P(s)) { if (!RSTR_EMBEDDABLE_P(capacity)) { - char *const tmp = (char *)mrb_malloc(mrb, capacity+1); - const mrb_int len = RSTR_EMBED_LEN(s); - memcpy(tmp, s->as.ary, len); + str_init_normal_capa(mrb, s, s->as.ary, RSTR_EMBED_LEN(s), capacity); RSTR_UNSET_EMBED_FLAG(s); - s->as.heap.ptr = tmp; - s->as.heap.len = len; - s->as.heap.aux.capa = (mrb_int)capacity; } } else { @@ -571,12 +580,11 @@ str_index_str(mrb_state *mrb, mrb_value str, mrb_value str2, mrb_int offset) static mrb_value str_replace(mrb_state *mrb, struct RString *s1, struct RString *s2) { - mrb_int len; + size_t len; mrb_check_frozen(mrb, s1); if (s1 == s2) return mrb_obj_value(s1); RSTR_COPY_ASCII_FLAG(s1, s2); - len = RSTR_LEN(s2); if (RSTR_SHARED_P(s1)) { str_decref(mrb, s1->as.heap.aux.shared); RSTR_UNSET_SHARED_FLAG(s1); @@ -586,15 +594,12 @@ str_replace(mrb_state *mrb, struct RString *s1, struct RString *s2) mrb_free(mrb, s1->as.heap.ptr); } + len = (size_t)RSTR_LEN(s2); RSTR_UNSET_FSHARED_FLAG(s1); RSTR_UNSET_NOFREE_FLAG(s1); if (RSTR_EMBEDDABLE_P(len)) { RSTR_UNSET_SHARED_FLAG(s1); - RSTR_UNSET_FSHARED_FLAG(s1); - RSTR_SET_EMBED_FLAG(s1); - memcpy(s1->as.ary, RSTR_PTR(s2), len); - RSTR_SET_EMBED_LEN(s1, len); - RSTR_PTR(s1)[len] = '\0'; + str_init_embed(s1, RSTR_PTR(s2), len); } else { str_make_shared(mrb, s2, s1); @@ -724,25 +729,15 @@ mrb_str_modify_keep_ascii(mrb_state *mrb, struct RString *s) mrb_free(mrb, shared); } else { - char *ptr, *p; - mrb_int len; + char *p = RSTR_PTR(s); + size_t len = (size_t)s->as.heap.len; - p = RSTR_PTR(s); - len = s->as.heap.len; if (RSTR_EMBEDDABLE_P(len)) { - RSTR_SET_EMBED_FLAG(s); - RSTR_SET_EMBED_LEN(s, len); - ptr = RSTR_PTR(s); + str_init_embed(s, p, len); } else { - ptr = (char *)mrb_malloc(mrb, (size_t)len + 1); - s->as.heap.ptr = ptr; - s->as.heap.aux.capa = len; - } - if (p) { - memcpy(ptr, p, len); + str_init_normal(mrb, s, p, len); } - ptr[len] = '\0'; str_decref(mrb, shared); } RSTR_UNSET_SHARED_FLAG(s); @@ -750,23 +745,16 @@ mrb_str_modify_keep_ascii(mrb_state *mrb, struct RString *s) } if (RSTR_NOFREE_P(s) || RSTR_FSHARED_P(s)) { char *p = s->as.heap.ptr; - mrb_int len = s->as.heap.len; + size_t len = (size_t)s->as.heap.len; - RSTR_UNSET_FSHARED_FLAG(s); RSTR_UNSET_NOFREE_FLAG(s); RSTR_UNSET_FSHARED_FLAG(s); if (RSTR_EMBEDDABLE_P(len)) { - RSTR_SET_EMBED_FLAG(s); - RSTR_SET_EMBED_LEN(s, len); + str_init_embed(s, p, len); } else { - s->as.heap.ptr = (char *)mrb_malloc(mrb, (size_t)len+1); - s->as.heap.aux.capa = len; - } - if (p) { - memcpy(RSTR_PTR(s), p, len); + str_init_normal(mrb, s, p, len); } - RSTR_PTR(s)[len] = '\0'; return; } } -- cgit v1.2.3 From 8ed15fd92e6d3ce7963db8c3162bdebee7b55e1b Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 14 Aug 2019 09:42:41 +0900 Subject: Small refactoring on #4630 --- src/string.c | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) (limited to 'src/string.c') diff --git a/src/string.c b/src/string.c index 21a42a584..2e0b1e301 100644 --- a/src/string.c +++ b/src/string.c @@ -61,6 +61,17 @@ str_init_embed(struct RString *s, const char *p, size_t len) RSTR_SET_EMBED_LEN(s, len); } +static void +str_init(mrb_state *mrb, struct RString *s, const char *p, size_t len) +{ + if (RSTR_EMBEDDABLE_P(len)) { + str_init_embed(s, p, len); + } + else { + str_init_normal(mrb, s, p, len); + } +} + static struct RString* str_new_static(mrb_state *mrb, const char *p, size_t len) { @@ -83,19 +94,14 @@ str_new(mrb_state *mrb, const char *p, size_t len) { struct RString *s; + if (len >= MRB_INT_MAX) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big"); + } if (p && mrb_ro_data_p(p)) { return str_new_static(mrb, p, len); } s = mrb_obj_alloc_string(mrb); - if (RSTR_EMBEDDABLE_P(len)) { - str_init_embed(s, p, len); - } - else if (len >= MRB_INT_MAX) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big"); - } - else { - str_init_normal(mrb, s, p, len); - } + str_init(mrb, s, p, len); return s; } @@ -732,12 +738,7 @@ mrb_str_modify_keep_ascii(mrb_state *mrb, struct RString *s) char *p = RSTR_PTR(s); size_t len = (size_t)s->as.heap.len; - if (RSTR_EMBEDDABLE_P(len)) { - str_init_embed(s, p, len); - } - else { - str_init_normal(mrb, s, p, len); - } + str_init(mrb, s, p, len); str_decref(mrb, shared); } RSTR_UNSET_SHARED_FLAG(s); @@ -749,12 +750,7 @@ mrb_str_modify_keep_ascii(mrb_state *mrb, struct RString *s) RSTR_UNSET_NOFREE_FLAG(s); RSTR_UNSET_FSHARED_FLAG(s); - if (RSTR_EMBEDDABLE_P(len)) { - str_init_embed(s, p, len); - } - else { - str_init_normal(mrb, s, p, len); - } + str_init(mrb, s, p, len); return; } } -- cgit v1.2.3 From af6724c2f6b012316cef4ffc2d0c9eec8bd2853c Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Wed, 14 Aug 2019 22:20:34 +0900 Subject: Extract initialization code of shared and fshared string to function --- src/string.c | 69 +++++++++++++++++++++++++++++++----------------------------- 1 file changed, 36 insertions(+), 33 deletions(-) (limited to 'src/string.c') diff --git a/src/string.c b/src/string.c index 2e0b1e301..d0547ba3f 100644 --- a/src/string.c +++ b/src/string.c @@ -61,6 +61,34 @@ str_init_embed(struct RString *s, const char *p, size_t len) RSTR_SET_EMBED_LEN(s, len); } +static void +str_init_shared(mrb_state *mrb, const struct RString *orig, struct RString *s, mrb_shared_string *shared) +{ + if (shared) { + shared->refcnt++; + } + else { + shared = (mrb_shared_string *)mrb_malloc(mrb, sizeof(mrb_shared_string)); + shared->refcnt = 2; + shared->nofree = !!RSTR_NOFREE_P(orig); + shared->ptr = orig->as.heap.ptr; + shared->len = orig->as.heap.len; + } + s->as.heap.ptr = orig->as.heap.ptr; + s->as.heap.len = orig->as.heap.len; + s->as.heap.aux.shared = shared; + RSTR_SET_SHARED_FLAG(s); +} + +static void +str_init_fshared(const struct RString *orig, struct RString *s, struct RString *fshared) +{ + s->as.heap.ptr = orig->as.heap.ptr; + s->as.heap.len = orig->as.heap.len; + s->as.heap.aux.fshared = fshared; + RSTR_SET_FSHARED_FLAG(s); +} + static void str_init(mrb_state *mrb, struct RString *s, const char *p, size_t len) { @@ -435,54 +463,29 @@ mrb_memsearch(const void *x0, mrb_int m, const void *y0, mrb_int n) static void str_make_shared(mrb_state *mrb, struct RString *orig, struct RString *s) { - mrb_shared_string *shared; mrb_int len = RSTR_LEN(orig); mrb_assert(!RSTR_EMBED_P(orig)); if (RSTR_SHARED_P(orig)) { - shared = orig->as.heap.aux.shared; - shared->refcnt++; - s->as.heap.ptr = orig->as.heap.ptr; - s->as.heap.len = len; - s->as.heap.aux.shared = shared; - RSTR_SET_SHARED_FLAG(s); + str_init_shared(mrb, orig, s, orig->as.heap.aux.shared); RSTR_UNSET_EMBED_FLAG(s); } else if (RSTR_FSHARED_P(orig)) { - struct RString *fs; - - fs = orig->as.heap.aux.fshared; - s->as.heap.ptr = orig->as.heap.ptr; - s->as.heap.len = len; - s->as.heap.aux.fshared = fs; - RSTR_SET_FSHARED_FLAG(s); + str_init_fshared(orig, s, orig->as.heap.aux.fshared); RSTR_UNSET_EMBED_FLAG(s); } else if (MRB_FROZEN_P(orig) && !RSTR_POOL_P(orig)) { - s->as.heap.ptr = orig->as.heap.ptr; - s->as.heap.len = len; - s->as.heap.aux.fshared = orig; - RSTR_SET_FSHARED_FLAG(s); + str_init_fshared(orig, s, orig); RSTR_UNSET_EMBED_FLAG(s); } else { - shared = (mrb_shared_string *)mrb_malloc(mrb, sizeof(mrb_shared_string)); - shared->refcnt = 2; - shared->nofree = !!RSTR_NOFREE_P(orig); - if (!shared->nofree && orig->as.heap.aux.capa > orig->as.heap.len) { - shared->ptr = (char *)mrb_realloc(mrb, orig->as.heap.ptr, len+1); - orig->as.heap.ptr = shared->ptr; - } - else { - shared->ptr = orig->as.heap.ptr; + if (!RSTR_NOFREE_P(orig) && orig->as.heap.aux.capa > orig->as.heap.len) { + orig->as.heap.ptr = (char *)mrb_realloc(mrb, orig->as.heap.ptr, len+1); } - orig->as.heap.aux.shared = shared; + str_init_shared(mrb, orig, s, NULL); + RSTR_UNSET_EMBED_FLAG(s); + orig->as.heap.aux.shared = s->as.heap.aux.shared; RSTR_SET_SHARED_FLAG(orig); - shared->len = len; - s->as.heap.aux.shared = shared; - s->as.heap.ptr = shared->ptr; - s->as.heap.len = len; - RSTR_SET_SHARED_FLAG(s); RSTR_UNSET_EMBED_FLAG(s); } } -- cgit v1.2.3 From 59844ddde0bbf9bfaf358ae6c19688e122db7d73 Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Thu, 15 Aug 2019 12:18:33 +0900 Subject: Remove unneeded `#include` in `src/string.c` --- src/string.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/string.c') diff --git a/src/string.c b/src/string.c index d0547ba3f..241d7638d 100644 --- a/src/string.c +++ b/src/string.c @@ -21,7 +21,6 @@ #include #include #include -#include typedef struct mrb_shared_string { mrb_bool nofree : 1; -- cgit v1.2.3 From 9832e91304347a12e4a2fc53d38a0b1f2486b958 Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Fri, 16 Aug 2019 22:05:58 +0900 Subject: SHARED/FSHARED string is not required when sharing NOFREE string I think the string buffer of NOFREE string always exists and does not need to be released, so it can be shared as another NOFREE string. Also changed the `mrb_shared_string` field order so that eliminate padding if `int` and `mrb_int` sizes are less than pointer size. --- src/gc.c | 2 +- src/string.c | 39 ++++++++++++++++++++++----------------- 2 files changed, 23 insertions(+), 18 deletions(-) (limited to 'src/string.c') diff --git a/src/gc.c b/src/gc.c index a7a67ebfa..211980b19 100644 --- a/src/gc.c +++ b/src/gc.c @@ -748,7 +748,7 @@ gc_mark_children(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) break; case MRB_TT_STRING: - if (RSTR_FSHARED_P(obj) && !RSTR_NOFREE_P(obj)) { + if (RSTR_FSHARED_P(obj)) { struct RString *s = (struct RString*)obj; mrb_gc_mark(mrb, (struct RBasic*)s->as.heap.aux.fshared); } diff --git a/src/string.c b/src/string.c index 241d7638d..2b9a5cfde 100644 --- a/src/string.c +++ b/src/string.c @@ -23,10 +23,9 @@ #include typedef struct mrb_shared_string { - mrb_bool nofree : 1; int refcnt; - char *ptr; mrb_int len; + char *ptr; } mrb_shared_string; const char mrb_digitmap[] = "0123456789abcdefghijklmnopqrstuvwxyz"; @@ -60,6 +59,15 @@ str_init_embed(struct RString *s, const char *p, size_t len) RSTR_SET_EMBED_LEN(s, len); } +static void +str_init_nofree(struct RString *s, const char *p, size_t len) +{ + s->as.heap.ptr = (char *)p; + s->as.heap.len = (mrb_int)len; + s->as.heap.aux.capa = 0; /* nofree */ + RSTR_SET_NOFREE_FLAG(s); +} + static void str_init_shared(mrb_state *mrb, const struct RString *orig, struct RString *s, mrb_shared_string *shared) { @@ -69,7 +77,6 @@ str_init_shared(mrb_state *mrb, const struct RString *orig, struct RString *s, m else { shared = (mrb_shared_string *)mrb_malloc(mrb, sizeof(mrb_shared_string)); shared->refcnt = 2; - shared->nofree = !!RSTR_NOFREE_P(orig); shared->ptr = orig->as.heap.ptr; shared->len = orig->as.heap.len; } @@ -108,10 +115,7 @@ str_new_static(mrb_state *mrb, const char *p, size_t len) mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big"); } s = mrb_obj_alloc_string(mrb); - s->as.heap.len = (mrb_int)len; - s->as.heap.aux.capa = 0; /* nofree */ - s->as.heap.ptr = (char *)p; - s->flags = MRB_STR_NOFREE; + str_init_nofree(s, p, len); return s; } @@ -229,9 +233,7 @@ str_decref(mrb_state *mrb, mrb_shared_string *shared) { shared->refcnt--; if (shared->refcnt == 0) { - if (!shared->nofree) { - mrb_free(mrb, shared->ptr); - } + mrb_free(mrb, shared->ptr); mrb_free(mrb, shared); } } @@ -465,7 +467,11 @@ str_make_shared(mrb_state *mrb, struct RString *orig, struct RString *s) mrb_int len = RSTR_LEN(orig); mrb_assert(!RSTR_EMBED_P(orig)); - if (RSTR_SHARED_P(orig)) { + if (RSTR_NOFREE_P(orig)) { + str_init_nofree(s, orig->as.heap.ptr, len); + RSTR_UNSET_EMBED_FLAG(s); + } + else if (RSTR_SHARED_P(orig)) { str_init_shared(mrb, orig, s, orig->as.heap.aux.shared); RSTR_UNSET_EMBED_FLAG(s); } @@ -478,7 +484,7 @@ str_make_shared(mrb_state *mrb, struct RString *orig, struct RString *s) RSTR_UNSET_EMBED_FLAG(s); } else { - if (!RSTR_NOFREE_P(orig) && orig->as.heap.aux.capa > orig->as.heap.len) { + if (orig->as.heap.aux.capa > orig->as.heap.len) { orig->as.heap.ptr = (char *)mrb_realloc(mrb, orig->as.heap.ptr, len+1); } str_init_shared(mrb, orig, s, NULL); @@ -495,11 +501,11 @@ mrb_str_byte_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len) struct RString *orig, *s; orig = mrb_str_ptr(str); - if (RSTR_EMBED_P(orig) || RSTR_LEN(orig) == 0 || RSTR_EMBEDDABLE_P(len)) { - s = str_new(mrb, RSTR_PTR(orig)+beg, len); + s = mrb_obj_alloc_string(mrb); + if (RSTR_EMBEDDABLE_P(len)) { + str_init_embed(s, RSTR_PTR(orig)+beg, len); } else { - s = mrb_obj_alloc_string(mrb); str_make_shared(mrb, orig, s); s->as.heap.ptr += beg; s->as.heap.len = len; @@ -606,7 +612,6 @@ str_replace(mrb_state *mrb, struct RString *s1, struct RString *s2) RSTR_UNSET_FSHARED_FLAG(s1); RSTR_UNSET_NOFREE_FLAG(s1); if (RSTR_EMBEDDABLE_P(len)) { - RSTR_UNSET_SHARED_FLAG(s1); str_init_embed(s1, RSTR_PTR(s2), len); } else { @@ -730,7 +735,7 @@ mrb_str_modify_keep_ascii(mrb_state *mrb, struct RString *s) if (RSTR_SHARED_P(s)) { mrb_shared_string *shared = s->as.heap.aux.shared; - if (shared->nofree == 0 && shared->refcnt == 1 && s->as.heap.ptr == shared->ptr) { + if (shared->refcnt == 1 && s->as.heap.ptr == shared->ptr) { s->as.heap.ptr = shared->ptr; s->as.heap.aux.capa = shared->len; RSTR_PTR(s)[s->as.heap.len] = '\0'; -- cgit v1.2.3 From bc272730874b5f0e22f0b7126ec46bc761d335b1 Mon Sep 17 00:00:00 2001 From: dearblue Date: Sat, 10 Aug 2019 22:21:49 +0900 Subject: Fix `String#rindex` with invalid UTF-8 string MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously `String#rindex` returned the wrong index when given an invalid UTF-8 string. ```terminal % ruby26 -e 'str = "\xf0☀\xf1☁\xf2☂\xf3☃\xf0☀\xf1☁\xf2☂\xf3☃"; p str.rindex("☁")' 11 % ./mruby-head -e 'str = "\xf0☀\xf1☁\xf2☂\xf3☃\xf0☀\xf1☁\xf2☂\xf3☃"; p str.rindex("☁")' nil % ./mruby-patched -e 'str = "\xf0☀\xf1☁\xf2☂\xf3☃\xf0☀\xf1☁\xf2☂\xf3☃"; p str.rindex("☁")' 11 ``` --- src/string.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 64 insertions(+), 11 deletions(-) (limited to 'src/string.c') diff --git a/src/string.c b/src/string.c index 2b9a5cfde..9d2ff34ad 100644 --- a/src/string.c +++ b/src/string.c @@ -337,19 +337,69 @@ chars2bytes(mrb_value s, mrb_int off, mrb_int idx) /* map byte offset to character index */ static mrb_int -bytes2chars(char *p, mrb_int bi) +bytes2chars(char *p, mrb_int len, mrb_int bi) { - mrb_int i, b, n; + const char *e = p + (size_t)len; + const char *pivot = p + bi; + mrb_int i; - for (b=i=0; b beg || ptr < end) && (*ptr & 0xc0) == 0x80) { + const int utf8_adjust_max = 3; + const char *p; + + if (ptr - beg > utf8_adjust_max) { + beg = ptr - utf8_adjust_max; + } + + p = ptr; + while (p > beg) { + p --; + if ((*p & 0xc0) != 0x80) { + int clen = utf8len(p, end); + if (clen > ptr - p) return p; + break; + } + } + } + + return ptr; +} + +static const char * +char_backtrack(const char *ptr, const char *end) +{ + if (ptr < end) { + const int utf8_bytelen_max = 4; + const char *p; + + if (end - ptr > utf8_bytelen_max) { + ptr = end - utf8_bytelen_max; + } + + p = end; + while (p > ptr) { + p --; + if ((*p & 0xc0) != 0x80) { + int clen = utf8len_codepage[(unsigned char)*p]; + if (clen == end - p) { return p; } + break; + } + } + } + + return end - 1; +} + static mrb_int str_index_str_by_char_search(mrb_state *mrb, const char *p, const char *pend, const char *s, const mrb_int slen, mrb_int off) { @@ -412,7 +462,9 @@ str_index_str_by_char(mrb_state *mrb, mrb_value str, mrb_value sub, mrb_int pos) #else #define RSTRING_CHAR_LEN(s) RSTRING_LEN(s) #define chars2bytes(p, off, ci) (ci) -#define bytes2chars(p, bi) (bi) +#define bytes2chars(p, end, bi) (bi) +#define char_adjust(beg, end, ptr) (ptr) +#define char_backtrack(ptr, end) ((end) - 1) #define BYTES_ALIGN_CHECK(pos) #define str_index_str_by_char(mrb, str, sub, pos) str_index_str(mrb, str, sub, pos) #endif @@ -624,7 +676,7 @@ str_replace(mrb_state *mrb, struct RString *s1, struct RString *s2) static mrb_int str_rindex(mrb_state *mrb, mrb_value str, mrb_value sub, mrb_int pos) { - char *s, *sbeg, *t; + const char *s, *sbeg, *t; struct RString *ps = mrb_str_ptr(str); mrb_int len = RSTRING_LEN(sub); @@ -637,11 +689,12 @@ str_rindex(mrb_state *mrb, mrb_value str, mrb_value sub, mrb_int pos) s = RSTR_PTR(ps) + pos; t = RSTRING_PTR(sub); if (len) { + s = char_adjust(sbeg, sbeg + RSTR_LEN(ps), s); while (sbeg <= s) { if (memcmp(s, t, len) == 0) { return (mrb_int)(s - RSTR_PTR(ps)); } - s--; + s = char_backtrack(sbeg, s); } return -1; } @@ -2016,7 +2069,7 @@ mrb_str_rindex(mrb_state *mrb, mrb_value str) case MRB_TT_STRING: pos = str_rindex(mrb, str, sub, pos); if (pos >= 0) { - pos = bytes2chars(RSTRING_PTR(str), pos); + pos = bytes2chars(RSTRING_PTR(str), RSTRING_LEN(str), pos); BYTES_ALIGN_CHECK(pos); return mrb_fixnum_value(pos); } -- cgit v1.2.3 From caba5fef274ab7df91b7247182ecbf2483b853b8 Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Sat, 17 Aug 2019 21:24:08 +0900 Subject: Refactor set/unset string type flags Introduce `RSTR_SET_TYPE_FLAG` macro to set the specified string type flag and clear the others. --- include/mruby/string.h | 14 ++++++++++---- src/string.c | 41 ++++++++++------------------------------- 2 files changed, 20 insertions(+), 35 deletions(-) (limited to 'src/string.c') diff --git a/include/mruby/string.h b/include/mruby/string.h index aacbdbfc0..51510457d 100644 --- a/include/mruby/string.h +++ b/include/mruby/string.h @@ -34,6 +34,9 @@ struct RString { } as; }; +#define RSTR_SET_TYPE_FLAG(s, type) (RSTR_UNSET_TYPE_FLAG(s), (s)->flags |= MRB_STR_##type) +#define RSTR_UNSET_TYPE_FLAG(s) ((s)->flags &= ~(MRB_STR_TYPE_MASK|MRB_STR_EMBED_LEN_MASK)) + #define RSTR_EMBED_P(s) ((s)->flags & MRB_STR_EMBED) #define RSTR_SET_EMBED_FLAG(s) ((s)->flags |= MRB_STR_EMBED) #define RSTR_UNSET_EMBED_FLAG(s) ((s)->flags &= ~(MRB_STR_EMBED|MRB_STR_EMBED_LEN_MASK)) @@ -103,11 +106,14 @@ MRB_API mrb_int mrb_str_strlen(mrb_state*, struct RString*); #define MRB_STR_SHARED 1 #define MRB_STR_FSHARED 2 #define MRB_STR_NOFREE 4 -#define MRB_STR_POOL 8 -#define MRB_STR_ASCII 16 -#define MRB_STR_EMBED 32 -#define MRB_STR_EMBED_LEN_MASK 0x7c0 +#define MRB_STR_EMBED 8 /* type flags up to here */ +#define MRB_STR_POOL 16 /* status flags from here */ +#define MRB_STR_ASCII 32 #define MRB_STR_EMBED_LEN_SHIFT 6 +#define MRB_STR_EMBED_LEN_BITSIZE 5 +#define MRB_STR_EMBED_LEN_MASK (((1 << MRB_STR_EMBED_LEN_BITSIZE) - 1) << MRB_STR_EMBED_LEN_SHIFT) +#define MRB_STR_TYPE_MASK (MRB_STR_POOL - 1) + void mrb_gc_free_str(mrb_state*, struct RString*); diff --git a/src/string.c b/src/string.c index 2b9a5cfde..34ab2a51a 100644 --- a/src/string.c +++ b/src/string.c @@ -42,6 +42,7 @@ str_init_normal_capa(mrb_state *mrb, struct RString *s, s->as.heap.ptr = dst; s->as.heap.len = (mrb_int)len; s->as.heap.aux.capa = (mrb_int)capa; + RSTR_UNSET_TYPE_FLAG(s); } static void @@ -55,7 +56,7 @@ str_init_embed(struct RString *s, const char *p, size_t len) { if (p) memcpy(s->as.ary, p, len); s->as.ary[len] = '\0'; - RSTR_SET_EMBED_FLAG(s); + RSTR_SET_TYPE_FLAG(s, EMBED); RSTR_SET_EMBED_LEN(s, len); } @@ -65,7 +66,7 @@ str_init_nofree(struct RString *s, const char *p, size_t len) s->as.heap.ptr = (char *)p; s->as.heap.len = (mrb_int)len; s->as.heap.aux.capa = 0; /* nofree */ - RSTR_SET_NOFREE_FLAG(s); + RSTR_SET_TYPE_FLAG(s, NOFREE); } static void @@ -83,7 +84,7 @@ str_init_shared(mrb_state *mrb, const struct RString *orig, struct RString *s, m s->as.heap.ptr = orig->as.heap.ptr; s->as.heap.len = orig->as.heap.len; s->as.heap.aux.shared = shared; - RSTR_SET_SHARED_FLAG(s); + RSTR_SET_TYPE_FLAG(s, SHARED); } static void @@ -92,7 +93,7 @@ str_init_fshared(const struct RString *orig, struct RString *s, struct RString * s->as.heap.ptr = orig->as.heap.ptr; s->as.heap.len = orig->as.heap.len; s->as.heap.aux.fshared = fshared; - RSTR_SET_FSHARED_FLAG(s); + RSTR_SET_TYPE_FLAG(s, FSHARED); } static void @@ -188,7 +189,6 @@ resize_capa(mrb_state *mrb, struct RString *s, size_t capacity) if (RSTR_EMBED_P(s)) { if (!RSTR_EMBEDDABLE_P(capacity)) { str_init_normal_capa(mrb, s, s->as.ary, RSTR_EMBED_LEN(s), capacity); - RSTR_UNSET_EMBED_FLAG(s); } } else { @@ -469,29 +469,23 @@ str_make_shared(mrb_state *mrb, struct RString *orig, struct RString *s) mrb_assert(!RSTR_EMBED_P(orig)); if (RSTR_NOFREE_P(orig)) { str_init_nofree(s, orig->as.heap.ptr, len); - RSTR_UNSET_EMBED_FLAG(s); } else if (RSTR_SHARED_P(orig)) { str_init_shared(mrb, orig, s, orig->as.heap.aux.shared); - RSTR_UNSET_EMBED_FLAG(s); } else if (RSTR_FSHARED_P(orig)) { str_init_fshared(orig, s, orig->as.heap.aux.fshared); - RSTR_UNSET_EMBED_FLAG(s); } else if (MRB_FROZEN_P(orig) && !RSTR_POOL_P(orig)) { str_init_fshared(orig, s, orig); - RSTR_UNSET_EMBED_FLAG(s); } else { if (orig->as.heap.aux.capa > orig->as.heap.len) { orig->as.heap.ptr = (char *)mrb_realloc(mrb, orig->as.heap.ptr, len+1); } str_init_shared(mrb, orig, s, NULL); - RSTR_UNSET_EMBED_FLAG(s); orig->as.heap.aux.shared = s->as.heap.aux.shared; - RSTR_SET_SHARED_FLAG(orig); - RSTR_UNSET_EMBED_FLAG(s); + RSTR_SET_TYPE_FLAG(orig, SHARED); } } @@ -601,7 +595,6 @@ str_replace(mrb_state *mrb, struct RString *s1, struct RString *s2) RSTR_COPY_ASCII_FLAG(s1, s2); if (RSTR_SHARED_P(s1)) { str_decref(mrb, s1->as.heap.aux.shared); - RSTR_UNSET_SHARED_FLAG(s1); } else if (!RSTR_EMBED_P(s1) && !RSTR_NOFREE_P(s1) && !RSTR_FSHARED_P(s1) && s1->as.heap.ptr) { @@ -609,8 +602,6 @@ str_replace(mrb_state *mrb, struct RString *s1, struct RString *s2) } len = (size_t)RSTR_LEN(s2); - RSTR_UNSET_FSHARED_FLAG(s1); - RSTR_UNSET_NOFREE_FLAG(s1); if (RSTR_EMBEDDABLE_P(len)) { str_init_embed(s1, RSTR_PTR(s2), len); } @@ -736,29 +727,17 @@ mrb_str_modify_keep_ascii(mrb_state *mrb, struct RString *s) mrb_shared_string *shared = s->as.heap.aux.shared; if (shared->refcnt == 1 && s->as.heap.ptr == shared->ptr) { - s->as.heap.ptr = shared->ptr; s->as.heap.aux.capa = shared->len; - RSTR_PTR(s)[s->as.heap.len] = '\0'; + s->as.heap.ptr[s->as.heap.len] = '\0'; mrb_free(mrb, shared); } else { - char *p = RSTR_PTR(s); - size_t len = (size_t)s->as.heap.len; - - str_init(mrb, s, p, len); + str_init(mrb, s, s->as.heap.ptr, (size_t)s->as.heap.len); str_decref(mrb, shared); } - RSTR_UNSET_SHARED_FLAG(s); - return; } - if (RSTR_NOFREE_P(s) || RSTR_FSHARED_P(s)) { - char *p = s->as.heap.ptr; - size_t len = (size_t)s->as.heap.len; - - RSTR_UNSET_NOFREE_FLAG(s); - RSTR_UNSET_FSHARED_FLAG(s); - str_init(mrb, s, p, len); - return; + else if (RSTR_NOFREE_P(s) || RSTR_FSHARED_P(s)) { + str_init(mrb, s, s->as.heap.ptr, (size_t)s->as.heap.len); } } -- cgit v1.2.3 From 05a873c25c270072cf979bbe730e7989e8fc4cc9 Mon Sep 17 00:00:00 2001 From: dearblue Date: Sun, 18 Aug 2019 15:34:14 +0900 Subject: Simplify get arguments - `mrb_str_index_m()` and `mrb_str_rindex()` Make `mrb_get_args()` called only once from called twice. - `mrb_str_byteslice()` Replace `goto` with `if ~ else`. --- mrbgems/mruby-string-ext/src/string.c | 17 +++++---- src/string.c | 66 ++++++++++++++++------------------- 2 files changed, 38 insertions(+), 45 deletions(-) (limited to 'src/string.c') diff --git a/mrbgems/mruby-string-ext/src/string.c b/mrbgems/mruby-string-ext/src/string.c index a946140dd..e3b8d9960 100644 --- a/mrbgems/mruby-string-ext/src/string.c +++ b/mrbgems/mruby-string-ext/src/string.c @@ -134,19 +134,18 @@ mrb_str_byteslice(mrb_state *mrb, mrb_value str) if (mrb_get_args(mrb, "o|o", &a1, &a2) == 2) { beg = mrb_fixnum(mrb_to_int(mrb, a1)); len = mrb_fixnum(mrb_to_int(mrb, a2)); - goto subseq; } - if (mrb_type(a1) == MRB_TT_RANGE) { - if (mrb_range_beg_len(mrb, a1, &beg, &len, str_len, TRUE) == MRB_RANGE_OK) { - goto subseq; + else if (mrb_type(a1) == MRB_TT_RANGE) { + if (mrb_range_beg_len(mrb, a1, &beg, &len, str_len, TRUE) != MRB_RANGE_OK) { + return mrb_nil_value(); } - return mrb_nil_value(); + } + else { + beg = mrb_fixnum(mrb_to_int(mrb, a1)); + len = 1; + empty = FALSE; } - beg = mrb_fixnum(mrb_to_int(mrb, a1)); - len = 1; - empty = FALSE; -subseq: if (mrb_str_beg_len(str_len, &beg, &len) && (empty || len != 0)) { return mrb_str_byte_subseq(mrb, str, beg, len); } diff --git a/src/string.c b/src/string.c index ab53c2e69..7c1d32359 100644 --- a/src/string.c +++ b/src/string.c @@ -1759,28 +1759,25 @@ mrb_str_include(mrb_state *mrb, mrb_value self) static mrb_value mrb_str_index_m(mrb_state *mrb, mrb_value str) { - mrb_value *argv; - mrb_int argc; mrb_value sub; - mrb_int pos, clen; + mrb_int pos; - mrb_get_args(mrb, "*!", &argv, &argc); - if (argc == 2) { - mrb_get_args(mrb, "oi", &sub, &pos); - } - else { - pos = 0; - if (argc > 0) - sub = argv[0]; - else + switch (mrb_get_args(mrb, "|oi", &sub, &pos)) { + case 0: sub = mrb_nil_value(); - } - if (pos < 0) { - clen = RSTRING_CHAR_LEN(str); - pos += clen; - if (pos < 0) { - return mrb_nil_value(); - } + /* fall through */ + case 1: + pos = 0; + break; + case 2: + if (pos < 0) { + mrb_int clen = RSTRING_CHAR_LEN(str); + pos += clen; + if (pos < 0) { + return mrb_nil_value(); + } + } + break; } switch (mrb_type(sub)) { @@ -2009,28 +2006,25 @@ mrb_str_reverse(mrb_state *mrb, mrb_value str) static mrb_value mrb_str_rindex(mrb_state *mrb, mrb_value str) { - mrb_value *argv; - mrb_int argc; mrb_value sub; mrb_int pos, len = RSTRING_CHAR_LEN(str); - mrb_get_args(mrb, "*!", &argv, &argc); - if (argc == 2) { - mrb_get_args(mrb, "oi", &sub, &pos); - if (pos < 0) { - pos += len; + switch (mrb_get_args(mrb, "|oi", &sub, &pos)) { + case 0: + sub = mrb_nil_value(); + /* fall through */ + case 1: + pos = len; + break; + case 2: if (pos < 0) { - return mrb_nil_value(); + pos += len; + if (pos < 0) { + return mrb_nil_value(); + } } - } - if (pos > len) pos = len; - } - else { - pos = len; - if (argc > 0) - sub = argv[0]; - else - sub = mrb_nil_value(); + if (pos > len) pos = len; + break; } pos = chars2bytes(str, 0, pos); -- cgit v1.2.3 From aaa509dd076e7de654a6c555bec264083c145388 Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Sun, 18 Aug 2019 19:44:00 +0900 Subject: Also use `str_init_shared` for `orig` in `str_make_shared()` --- src/string.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src/string.c') diff --git a/src/string.c b/src/string.c index ab53c2e69..10e20c3b1 100644 --- a/src/string.c +++ b/src/string.c @@ -77,7 +77,7 @@ str_init_shared(mrb_state *mrb, const struct RString *orig, struct RString *s, m } else { shared = (mrb_shared_string *)mrb_malloc(mrb, sizeof(mrb_shared_string)); - shared->refcnt = 2; + shared->refcnt = 1; shared->ptr = orig->as.heap.ptr; shared->len = orig->as.heap.len; } @@ -516,7 +516,7 @@ mrb_memsearch(const void *x0, mrb_int m, const void *y0, mrb_int n) static void str_make_shared(mrb_state *mrb, struct RString *orig, struct RString *s) { - mrb_int len = RSTR_LEN(orig); + size_t len = (size_t)orig->as.heap.len; mrb_assert(!RSTR_EMBED_P(orig)); if (RSTR_NOFREE_P(orig)) { @@ -536,8 +536,7 @@ str_make_shared(mrb_state *mrb, struct RString *orig, struct RString *s) orig->as.heap.ptr = (char *)mrb_realloc(mrb, orig->as.heap.ptr, len+1); } str_init_shared(mrb, orig, s, NULL); - orig->as.heap.aux.shared = s->as.heap.aux.shared; - RSTR_SET_TYPE_FLAG(orig, SHARED); + str_init_shared(mrb, orig, orig, s->as.heap.aux.shared); } } -- cgit v1.2.3 From d2d201cc821ee46029d98c1fcd4706bc86c78ac6 Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Sun, 18 Aug 2019 20:08:04 +0900 Subject: Rename `mrb_shared_string::len` to `mrb_shared_string::capa` Because this field is used as capacity of string buffer. --- src/string.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/string.c') diff --git a/src/string.c b/src/string.c index ab53c2e69..fe71ffe7c 100644 --- a/src/string.c +++ b/src/string.c @@ -24,7 +24,7 @@ typedef struct mrb_shared_string { int refcnt; - mrb_int len; + mrb_int capa; char *ptr; } mrb_shared_string; @@ -79,7 +79,7 @@ str_init_shared(mrb_state *mrb, const struct RString *orig, struct RString *s, m shared = (mrb_shared_string *)mrb_malloc(mrb, sizeof(mrb_shared_string)); shared->refcnt = 2; shared->ptr = orig->as.heap.ptr; - shared->len = orig->as.heap.len; + shared->capa = orig->as.heap.aux.capa; } s->as.heap.ptr = orig->as.heap.ptr; s->as.heap.len = orig->as.heap.len; @@ -534,6 +534,7 @@ str_make_shared(mrb_state *mrb, struct RString *orig, struct RString *s) else { if (orig->as.heap.aux.capa > orig->as.heap.len) { orig->as.heap.ptr = (char *)mrb_realloc(mrb, orig->as.heap.ptr, len+1); + orig->as.heap.aux.capa = len; } str_init_shared(mrb, orig, s, NULL); orig->as.heap.aux.shared = s->as.heap.aux.shared; @@ -780,7 +781,7 @@ mrb_str_modify_keep_ascii(mrb_state *mrb, struct RString *s) mrb_shared_string *shared = s->as.heap.aux.shared; if (shared->refcnt == 1 && s->as.heap.ptr == shared->ptr) { - s->as.heap.aux.capa = shared->len; + s->as.heap.aux.capa = shared->capa; s->as.heap.ptr[s->as.heap.len] = '\0'; mrb_free(mrb, shared); } -- cgit v1.2.3 From 507dbf984ee27db79ced4d9dfd3554b9dcf37f0d Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Mon, 19 Aug 2019 19:18:52 +0900 Subject: Move `mrb_str_pool` to `src/string.c` to use `str_init` family --- src/state.c | 52 ---------------------------------------------------- src/string.c | 23 +++++++++++++++++++++++ 2 files changed, 23 insertions(+), 52 deletions(-) (limited to 'src/string.c') diff --git a/src/state.c b/src/state.c index 010a8d68a..99b523dd5 100644 --- a/src/state.c +++ b/src/state.c @@ -141,58 +141,6 @@ mrb_irep_free(mrb_state *mrb, mrb_irep *irep) mrb_free(mrb, irep); } -mrb_value -mrb_str_pool(mrb_state *mrb, mrb_value str) -{ - struct RString *s = mrb_str_ptr(str); - struct RString *ns; - char *ptr; - mrb_int len; - - ns = (struct RString *)mrb_malloc(mrb, sizeof(struct RString)); - ns->tt = MRB_TT_STRING; - ns->c = mrb->string_class; - - if (RSTR_NOFREE_P(s)) { - ns->flags = MRB_STR_NOFREE; - ns->as.heap.ptr = s->as.heap.ptr; - ns->as.heap.len = s->as.heap.len; - ns->as.heap.aux.capa = 0; - } - else { - ns->flags = 0; - if (RSTR_EMBED_P(s)) { - ptr = s->as.ary; - len = RSTR_EMBED_LEN(s); - } - else { - ptr = s->as.heap.ptr; - len = s->as.heap.len; - } - - if (RSTR_EMBEDDABLE_P(len)) { - RSTR_SET_EMBED_FLAG(ns); - RSTR_SET_EMBED_LEN(ns, len); - if (ptr) { - memcpy(ns->as.ary, ptr, len); - } - ns->as.ary[len] = '\0'; - } - else { - ns->as.heap.ptr = (char *)mrb_malloc(mrb, (size_t)len+1); - ns->as.heap.len = len; - ns->as.heap.aux.capa = len; - if (ptr) { - memcpy(ns->as.heap.ptr, ptr, len); - } - ns->as.heap.ptr[len] = '\0'; - } - } - RSTR_SET_POOL_FLAG(ns); - MRB_SET_FROZEN_FLAG(ns); - return mrb_obj_value(ns); -} - void mrb_free_backtrace(mrb_state *mrb); MRB_API void diff --git a/src/string.c b/src/string.c index 247ee78c2..72e14ede9 100644 --- a/src/string.c +++ b/src/string.c @@ -541,6 +541,29 @@ str_make_shared(mrb_state *mrb, struct RString *orig, struct RString *s) } } +mrb_value +mrb_str_pool(mrb_state *mrb, mrb_value str) +{ + struct RString *s = (struct RString *)mrb_malloc(mrb, sizeof(struct RString)); + struct RString *orig = mrb_str_ptr(str); + const char *p = RSTR_PTR(orig); + size_t len = (size_t)RSTR_LEN(orig); + + s->tt = MRB_TT_STRING; + s->c = mrb->string_class; + s->flags = 0; + + if (RSTR_NOFREE_P(orig)) { + str_init_nofree(s, p, len); + } + else { + str_init(mrb, s, p, len); + } + RSTR_SET_POOL_FLAG(s); + MRB_SET_FROZEN_FLAG(s); + return mrb_obj_value(s); +} + mrb_value mrb_str_byte_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len) { -- cgit v1.2.3 From 8157672a29e50756b9709022e8f66da73cd92c2b Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Tue, 20 Aug 2019 18:49:55 +0900 Subject: Use `RBasic` padding for embedded string on 64-bit CPU On 64-bit CPU, there is padding in `RBasic`, so reorder the fields and use it as buffer of embedded string. This change allows 4 more bytes to be embedded on 64-bit CPU. However, an incompatibility will occur if `RString::as::ary` is accessed directly because `RString` structure has changed. --- include/mruby/object.h | 6 +++--- include/mruby/string.h | 11 ++++++++--- src/gc.c | 2 +- src/string.c | 6 +++--- 4 files changed, 15 insertions(+), 10 deletions(-) (limited to 'src/string.c') diff --git a/include/mruby/object.h b/include/mruby/object.h index 48dcc4977..1cb4ca6e8 100644 --- a/include/mruby/object.h +++ b/include/mruby/object.h @@ -8,11 +8,11 @@ #define MRUBY_OBJECT_H #define MRB_OBJECT_HEADER \ + struct RClass *c; \ + struct RBasic *gcnext; \ enum mrb_vtype tt:8; \ uint32_t color:3; \ - uint32_t flags:21; \ - struct RClass *c; \ - struct RBasic *gcnext + uint32_t flags:21 #define MRB_FLAG_TEST(obj, flag) ((obj)->flags & (flag)) diff --git a/include/mruby/string.h b/include/mruby/string.h index ab29be421..84a6c4665 100644 --- a/include/mruby/string.h +++ b/include/mruby/string.h @@ -16,7 +16,8 @@ MRB_BEGIN_DECL extern const char mrb_digitmap[]; -#define RSTRING_EMBED_LEN_MAX ((mrb_int)(sizeof(void*) * 3 - 1)) +#define RSTRING_EMBED_LEN_MAX \ + ((mrb_int)(sizeof(void*) * 3 + sizeof(void*) - 32 / CHAR_BIT - 1)) struct RString { MRB_OBJECT_HEADER; @@ -30,9 +31,12 @@ struct RString { } aux; char *ptr; } heap; - char ary[RSTRING_EMBED_LEN_MAX + 1]; } as; }; +struct RStringEmbed { + MRB_OBJECT_HEADER; + char ary[]; +}; #define RSTR_SET_TYPE_FLAG(s, type) (RSTR_UNSET_TYPE_FLAG(s), (s)->flags |= MRB_STR_##type) #define RSTR_UNSET_TYPE_FLAG(s) ((s)->flags &= ~(MRB_STR_TYPE_MASK|MRB_STR_EMBED_LEN_MASK)) @@ -53,11 +57,12 @@ struct RString { (s)->as.heap.len = (mrb_int)(n);\ }\ } while (0) +#define RSTR_EMBED_PTR(s) (((struct RStringEmbed*)(s))->ary) #define RSTR_EMBED_LEN(s)\ (mrb_int)(((s)->flags & MRB_STR_EMBED_LEN_MASK) >> MRB_STR_EMBED_LEN_SHIFT) #define RSTR_EMBEDDABLE_P(len) ((len) <= RSTRING_EMBED_LEN_MAX) -#define RSTR_PTR(s) ((RSTR_EMBED_P(s)) ? (s)->as.ary : (s)->as.heap.ptr) +#define RSTR_PTR(s) ((RSTR_EMBED_P(s)) ? RSTR_EMBED_PTR(s) : (s)->as.heap.ptr) #define RSTR_LEN(s) ((RSTR_EMBED_P(s)) ? RSTR_EMBED_LEN(s) : (s)->as.heap.len) #define RSTR_CAPA(s) (RSTR_EMBED_P(s) ? RSTRING_EMBED_LEN_MAX : (s)->as.heap.aux.capa) diff --git a/src/gc.c b/src/gc.c index 211980b19..a2a904477 100644 --- a/src/gc.c +++ b/src/gc.c @@ -521,7 +521,7 @@ MRB_API struct RBasic* mrb_obj_alloc(mrb_state *mrb, enum mrb_vtype ttype, struct RClass *cls) { struct RBasic *p; - static const RVALUE RVALUE_zero = { { { MRB_TT_FALSE } } }; + static const RVALUE RVALUE_zero = { { { NULL, NULL, MRB_TT_FALSE } } }; mrb_gc *gc = &mrb->gc; if (cls) { diff --git a/src/string.c b/src/string.c index 72e14ede9..cacf48821 100644 --- a/src/string.c +++ b/src/string.c @@ -54,8 +54,8 @@ str_init_normal(mrb_state *mrb, struct RString *s, const char *p, size_t len) static void str_init_embed(struct RString *s, const char *p, size_t len) { - if (p) memcpy(s->as.ary, p, len); - s->as.ary[len] = '\0'; + if (p) memcpy(RSTR_EMBED_PTR(s), p, len); + RSTR_EMBED_PTR(s)[len] = '\0'; RSTR_SET_TYPE_FLAG(s, EMBED); RSTR_SET_EMBED_LEN(s, len); } @@ -188,7 +188,7 @@ resize_capa(mrb_state *mrb, struct RString *s, size_t capacity) #endif if (RSTR_EMBED_P(s)) { if (!RSTR_EMBEDDABLE_P(capacity)) { - str_init_normal_capa(mrb, s, s->as.ary, RSTR_EMBED_LEN(s), capacity); + str_init_normal_capa(mrb, s, RSTR_EMBED_PTR(s), RSTR_EMBED_LEN(s), capacity); } } else { -- cgit v1.2.3 From a84ab12735b91650a9db9f6bc55d16a9c7e992ce Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Wed, 21 Aug 2019 12:06:03 +0900 Subject: Prioritize embedded string over nofree (or normal) string Prioritize embedded string in the following functions: - `str_new_static` - `str_new` - `mrb_str_new_capa` - `mrb_str_pool` The reasons are as follows: - Consistency with `mrb_str_byte_subseq` and `str_replace`. - Memory locality increases and may be slightly faster. - No conversion cost to embedded string when modifying the string. --- src/string.c | 73 ++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 41 insertions(+), 32 deletions(-) (limited to 'src/string.c') diff --git a/src/string.c b/src/string.c index cacf48821..190e87123 100644 --- a/src/string.c +++ b/src/string.c @@ -32,7 +32,7 @@ const char mrb_digitmap[] = "0123456789abcdefghijklmnopqrstuvwxyz"; #define mrb_obj_alloc_string(mrb) ((struct RString*)mrb_obj_alloc((mrb), MRB_TT_STRING, (mrb)->string_class)) -static void +static struct RString* str_init_normal_capa(mrb_state *mrb, struct RString *s, const char *p, size_t len, size_t capa) { @@ -43,33 +43,36 @@ str_init_normal_capa(mrb_state *mrb, struct RString *s, s->as.heap.len = (mrb_int)len; s->as.heap.aux.capa = (mrb_int)capa; RSTR_UNSET_TYPE_FLAG(s); + return s; } -static void +static struct RString* str_init_normal(mrb_state *mrb, struct RString *s, const char *p, size_t len) { - str_init_normal_capa(mrb, s, p, len, len); + return str_init_normal_capa(mrb, s, p, len, len); } -static void +static struct RString* str_init_embed(struct RString *s, const char *p, size_t len) { if (p) memcpy(RSTR_EMBED_PTR(s), p, len); RSTR_EMBED_PTR(s)[len] = '\0'; RSTR_SET_TYPE_FLAG(s, EMBED); RSTR_SET_EMBED_LEN(s, len); + return s; } -static void +static struct RString* str_init_nofree(struct RString *s, const char *p, size_t len) { s->as.heap.ptr = (char *)p; s->as.heap.len = (mrb_int)len; s->as.heap.aux.capa = 0; /* nofree */ RSTR_SET_TYPE_FLAG(s, NOFREE); + return s; } -static void +static struct RString* str_init_shared(mrb_state *mrb, const struct RString *orig, struct RString *s, mrb_shared_string *shared) { if (shared) { @@ -85,56 +88,55 @@ str_init_shared(mrb_state *mrb, const struct RString *orig, struct RString *s, m s->as.heap.len = orig->as.heap.len; s->as.heap.aux.shared = shared; RSTR_SET_TYPE_FLAG(s, SHARED); + return s; } -static void +static struct RString* str_init_fshared(const struct RString *orig, struct RString *s, struct RString *fshared) { s->as.heap.ptr = orig->as.heap.ptr; s->as.heap.len = orig->as.heap.len; s->as.heap.aux.fshared = fshared; RSTR_SET_TYPE_FLAG(s, FSHARED); + return s; } -static void -str_init(mrb_state *mrb, struct RString *s, const char *p, size_t len) +static struct RString* +str_init_modifiable(mrb_state *mrb, struct RString *s, const char *p, size_t len) { if (RSTR_EMBEDDABLE_P(len)) { - str_init_embed(s, p, len); + return str_init_embed(s, p, len); } else { - str_init_normal(mrb, s, p, len); + return str_init_normal(mrb, s, p, len); } } static struct RString* str_new_static(mrb_state *mrb, const char *p, size_t len) { - struct RString *s; - + if (RSTR_EMBEDDABLE_P(len)) { + return str_init_embed(mrb_obj_alloc_string(mrb), p, len); + } if (len >= MRB_INT_MAX) { mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big"); } - s = mrb_obj_alloc_string(mrb); - str_init_nofree(s, p, len); - - return s; + return str_init_nofree(mrb_obj_alloc_string(mrb), p, len); } static struct RString* str_new(mrb_state *mrb, const char *p, size_t len) { - struct RString *s; - + if (RSTR_EMBEDDABLE_P(len)) { + return str_init_embed(mrb_obj_alloc_string(mrb), p, len); + } if (len >= MRB_INT_MAX) { mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big"); } if (p && mrb_ro_data_p(p)) { - return str_new_static(mrb, p, len); + return str_init_nofree(mrb_obj_alloc_string(mrb), p, len); } - s = mrb_obj_alloc_string(mrb); - str_init(mrb, s, p, len); - return s; + return str_init_normal(mrb, mrb_obj_alloc_string(mrb), p, len); } static inline void @@ -157,12 +159,15 @@ mrb_str_new_capa(mrb_state *mrb, size_t capa) { struct RString *s; - s = mrb_obj_alloc_string(mrb); - - if (capa >= MRB_INT_MAX) { + if (RSTR_EMBEDDABLE_P(capa)) { + s = str_init_embed(mrb_obj_alloc_string(mrb), NULL, 0); + } + else if (capa >= MRB_INT_MAX) { mrb_raise(mrb, E_ARGUMENT_ERROR, "string capacity size too big"); } - str_init_normal_capa(mrb, s, NULL, 0, capa); + else { + s = str_init_normal_capa(mrb, mrb_obj_alloc_string(mrb), NULL, 0, capa); + } return mrb_obj_value(s); } @@ -553,11 +558,14 @@ mrb_str_pool(mrb_state *mrb, mrb_value str) s->c = mrb->string_class; s->flags = 0; - if (RSTR_NOFREE_P(orig)) { + if (RSTR_EMBEDDABLE_P(len)) { + str_init_embed(s, p, len); + } + else if (RSTR_NOFREE_P(orig)) { str_init_nofree(s, p, len); } else { - str_init(mrb, s, p, len); + str_init_normal(mrb, s, p, len); } RSTR_SET_POOL_FLAG(s); MRB_SET_FROZEN_FLAG(s); @@ -808,12 +816,12 @@ mrb_str_modify_keep_ascii(mrb_state *mrb, struct RString *s) mrb_free(mrb, shared); } else { - str_init(mrb, s, s->as.heap.ptr, (size_t)s->as.heap.len); + str_init_modifiable(mrb, s, s->as.heap.ptr, (size_t)s->as.heap.len); str_decref(mrb, shared); } } else if (RSTR_NOFREE_P(s) || RSTR_FSHARED_P(s)) { - str_init(mrb, s, s->as.heap.ptr, (size_t)s->as.heap.len); + str_init_modifiable(mrb, s, s->as.heap.ptr, (size_t)s->as.heap.len); } } @@ -2937,7 +2945,8 @@ mrb_init_string(mrb_state *mrb) { struct RClass *s; - mrb_static_assert(RSTRING_EMBED_LEN_MAX < (1 << 5), "pointer size too big for embedded string"); + mrb_static_assert(RSTRING_EMBED_LEN_MAX < (1 << MRB_STR_EMBED_LEN_BITSIZE), + "pointer size too big for embedded string"); mrb->string_class = s = mrb_define_class(mrb, "String", mrb->object_class); /* 15.2.10 */ MRB_SET_INSTANCE_TT(s, MRB_TT_STRING); -- cgit v1.2.3 From c9c27e9d69ddd656343b8a0e876887f511fe6d03 Mon Sep 17 00:00:00 2001 From: dearblue Date: Sat, 24 Aug 2019 11:44:51 +0900 Subject: Suppress warning by gcc with `-Wmaybe-uninitialized` --- src/string.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/string.c') diff --git a/src/string.c b/src/string.c index 190e87123..8d1d53521 100644 --- a/src/string.c +++ b/src/string.c @@ -164,6 +164,8 @@ mrb_str_new_capa(mrb_state *mrb, size_t capa) } else if (capa >= MRB_INT_MAX) { mrb_raise(mrb, E_ARGUMENT_ERROR, "string capacity size too big"); + /* not reached */ + s = NULL; } else { s = str_init_normal_capa(mrb, mrb_obj_alloc_string(mrb), NULL, 0, capa); -- cgit v1.2.3 From ec3aeede20a8287e656866a2d4545bcd23baebf8 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 11 Sep 2019 12:58:55 +0900 Subject: Move `String#{getbyte,setbyte,byteslice}` to the core; #4696 Unlike CRuby, there's no way to process strings byte-wise by core methods because there's no per string encoding in mruby, so that we moved 3 byte-wise operation methods from `mruby-string-ext` gem. --- mrbgems/mruby-string-ext/src/string.c | 67 ---------------------- src/string.c | 102 ++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+), 67 deletions(-) (limited to 'src/string.c') diff --git a/mrbgems/mruby-string-ext/src/string.c b/mrbgems/mruby-string-ext/src/string.c index e3b8d9960..aa6270786 100644 --- a/mrbgems/mruby-string-ext/src/string.c +++ b/mrbgems/mruby-string-ext/src/string.c @@ -90,70 +90,6 @@ int_chr_utf8(mrb_state *mrb, mrb_value num) } #endif -static mrb_value -mrb_str_getbyte(mrb_state *mrb, mrb_value str) -{ - mrb_int pos; - mrb_get_args(mrb, "i", &pos); - - if (pos < 0) - pos += RSTRING_LEN(str); - if (pos < 0 || RSTRING_LEN(str) <= pos) - return mrb_nil_value(); - - return mrb_fixnum_value((unsigned char)RSTRING_PTR(str)[pos]); -} - -static mrb_value -mrb_str_setbyte(mrb_state *mrb, mrb_value str) -{ - mrb_int pos, byte; - mrb_int len; - - mrb_get_args(mrb, "ii", &pos, &byte); - - len = RSTRING_LEN(str); - if (pos < -len || len <= pos) - mrb_raisef(mrb, E_INDEX_ERROR, "index %i out of string", pos); - if (pos < 0) - pos += len; - - mrb_str_modify(mrb, mrb_str_ptr(str)); - byte &= 0xff; - RSTRING_PTR(str)[pos] = (unsigned char)byte; - return mrb_fixnum_value((unsigned char)byte); -} - -static mrb_value -mrb_str_byteslice(mrb_state *mrb, mrb_value str) -{ - mrb_value a1, a2; - mrb_int str_len = RSTRING_LEN(str), beg, len; - mrb_bool empty = TRUE; - - if (mrb_get_args(mrb, "o|o", &a1, &a2) == 2) { - beg = mrb_fixnum(mrb_to_int(mrb, a1)); - len = mrb_fixnum(mrb_to_int(mrb, a2)); - } - else if (mrb_type(a1) == MRB_TT_RANGE) { - if (mrb_range_beg_len(mrb, a1, &beg, &len, str_len, TRUE) != MRB_RANGE_OK) { - return mrb_nil_value(); - } - } - else { - beg = mrb_fixnum(mrb_to_int(mrb, a1)); - len = 1; - empty = FALSE; - } - - if (mrb_str_beg_len(str_len, &beg, &len) && (empty || len != 0)) { - return mrb_str_byte_subseq(mrb, str, beg, len); - } - else { - return mrb_nil_value(); - } -} - /* * call-seq: * str.swapcase! -> str or nil @@ -1266,9 +1202,6 @@ mrb_mruby_string_ext_gem_init(mrb_state* mrb) struct RClass * s = mrb->string_class; mrb_define_method(mrb, s, "dump", mrb_str_dump, MRB_ARGS_NONE()); - mrb_define_method(mrb, s, "getbyte", mrb_str_getbyte, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, s, "setbyte", mrb_str_setbyte, MRB_ARGS_REQ(2)); - mrb_define_method(mrb, s, "byteslice", mrb_str_byteslice, MRB_ARGS_REQ(1)|MRB_ARGS_OPT(1)); mrb_define_method(mrb, s, "swapcase!", mrb_str_swapcase_bang, MRB_ARGS_NONE()); mrb_define_method(mrb, s, "swapcase", mrb_str_swapcase, MRB_ARGS_NONE()); mrb_define_method(mrb, s, "concat", mrb_str_concat_m, MRB_ARGS_REQ(1)); diff --git a/src/string.c b/src/string.c index 8d1d53521..c1c28ee8b 100644 --- a/src/string.c +++ b/src/string.c @@ -2941,6 +2941,104 @@ mrb_str_bytes(mrb_state *mrb, mrb_value str) return a; } +/* + * call-seq: + * str.getbyte(index) -> 0 .. 255 + * + * returns the indexth byte as an integer. + */ +static mrb_value +mrb_str_getbyte(mrb_state *mrb, mrb_value str) +{ + mrb_int pos; + mrb_get_args(mrb, "i", &pos); + + if (pos < 0) + pos += RSTRING_LEN(str); + if (pos < 0 || RSTRING_LEN(str) <= pos) + return mrb_nil_value(); + + return mrb_fixnum_value((unsigned char)RSTRING_PTR(str)[pos]); +} + +/* + * call-seq: + * str.setbyte(index, integer) -> integer + * + * modifies the indexth byte as integer. + */ +static mrb_value +mrb_str_setbyte(mrb_state *mrb, mrb_value str) +{ + mrb_int pos, byte; + mrb_int len; + + mrb_get_args(mrb, "ii", &pos, &byte); + + len = RSTRING_LEN(str); + if (pos < -len || len <= pos) + mrb_raisef(mrb, E_INDEX_ERROR, "index %i out of string", pos); + if (pos < 0) + pos += len; + + mrb_str_modify(mrb, mrb_str_ptr(str)); + byte &= 0xff; + RSTRING_PTR(str)[pos] = (unsigned char)byte; + return mrb_fixnum_value((unsigned char)byte); +} + +/* + * call-seq: + * str.byteslice(integer) -> new_str or nil + * str.byteslice(integer, integer) -> new_str or nil + * str.byteslice(range) -> new_str or nil + * + * Byte Reference---If passed a single Integer, returns a + * substring of one byte at that position. If passed two Integer + * objects, returns a substring starting at the offset given by the first, and + * a length given by the second. If given a Range, a substring containing + * bytes at offsets given by the range is returned. In all three cases, if + * an offset is negative, it is counted from the end of str. Returns + * nil if the initial offset falls outside the string, the length + * is negative, or the beginning of the range is greater than the end. + * The encoding of the resulted string keeps original encoding. + * + * "hello".byteslice(1) #=> "e" + * "hello".byteslice(-1) #=> "o" + * "hello".byteslice(1, 2) #=> "el" + * "\x80\u3042".byteslice(1, 3) #=> "\u3042" + * "\x03\u3042\xff".byteslice(1..3) #=> "\u3042" + */ +static mrb_value +mrb_str_byteslice(mrb_state *mrb, mrb_value str) +{ + mrb_value a1, a2; + mrb_int str_len = RSTRING_LEN(str), beg, len; + mrb_bool empty = TRUE; + + if (mrb_get_args(mrb, "o|o", &a1, &a2) == 2) { + beg = mrb_fixnum(mrb_to_int(mrb, a1)); + len = mrb_fixnum(mrb_to_int(mrb, a2)); + } + else if (mrb_type(a1) == MRB_TT_RANGE) { + if (mrb_range_beg_len(mrb, a1, &beg, &len, str_len, TRUE) != MRB_RANGE_OK) { + return mrb_nil_value(); + } + } + else { + beg = mrb_fixnum(mrb_to_int(mrb, a1)); + len = 1; + empty = FALSE; + } + + if (mrb_str_beg_len(str_len, &beg, &len) && (empty || len != 0)) { + return mrb_str_byte_subseq(mrb, str, beg, len); + } + else { + return mrb_nil_value(); + } +} + /* ---------------------------*/ void mrb_init_string(mrb_state *mrb) @@ -2998,6 +3096,10 @@ mrb_init_string(mrb_state *mrb) mrb_define_method(mrb, s, "upcase!", mrb_str_upcase_bang, MRB_ARGS_NONE()); /* 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, "getbyte", mrb_str_getbyte, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, s, "setbyte", mrb_str_setbyte, MRB_ARGS_REQ(2)); + mrb_define_method(mrb, s, "byteslice", mrb_str_byteslice, MRB_ARGS_REQ(1)|MRB_ARGS_OPT(1)); } #ifndef MRB_WITHOUT_FLOAT -- cgit v1.2.3 From 231a1d68b061d80ac2ccdb7dd2e9637adb22692b Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Thu, 12 Sep 2019 21:22:59 +0900 Subject: Remove `$/` from mruby implementation. 1. `$/` and other Perl-ish global variables are not defined in ISO. 2. The current Ruby policy do not encourage those variables. 3. Those variables has global effect and can cause troubles. --- mrbgems/mruby-io/mrblib/io.rb | 6 +++--- mrbgems/mruby-io/src/io.c | 3 --- src/string.c | 5 ++--- 3 files changed, 5 insertions(+), 9 deletions(-) (limited to 'src/string.c') diff --git a/mrbgems/mruby-io/mrblib/io.rb b/mrbgems/mruby-io/mrblib/io.rb index f3c4de6fd..a6e3ef3de 100644 --- a/mrbgems/mruby-io/mrblib/io.rb +++ b/mrbgems/mruby-io/mrblib/io.rb @@ -226,12 +226,12 @@ class IO end end - def readline(arg = $/, limit = nil) + def readline(arg = "\n", limit = nil) case arg when String rs = arg when Fixnum - rs = $/ + rs = "\n" limit = arg else raise ArgumentError @@ -242,7 +242,7 @@ class IO end if rs == "" - rs = $/ + $/ + rs = "\n\n" end array = [] diff --git a/mrbgems/mruby-io/src/io.c b/mrbgems/mruby-io/src/io.c index eb9c4097b..784cdaf49 100644 --- a/mrbgems/mruby-io/src/io.c +++ b/mrbgems/mruby-io/src/io.c @@ -1328,7 +1328,4 @@ mrb_init_io(mrb_state *mrb) mrb_define_method(mrb, io, "closed?", mrb_io_closed, MRB_ARGS_NONE()); /* 15.2.20.5.2 */ mrb_define_method(mrb, io, "pid", mrb_io_pid, MRB_ARGS_NONE()); /* 15.2.20.5.2 */ mrb_define_method(mrb, io, "fileno", mrb_io_fileno, MRB_ARGS_NONE()); - - - mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$/"), mrb_str_new_cstr(mrb, "\n")); } diff --git a/src/string.c b/src/string.c index c1c28ee8b..35c7f8e7c 100644 --- a/src/string.c +++ b/src/string.c @@ -1529,9 +1529,8 @@ mrb_str_chomp_bang(mrb_state *mrb, mrb_value str) * str.chomp(separator="\n") => new_str * * Returns a new String with the given record separator removed - * from the end of str (if present). If $/ has not been - * changed from the default Ruby record separator, then chomp also - * removes carriage return characters (that is it will remove \n, + * from the end of str (if present). chomp also removes + * carriage return characters (that is it will remove \n, * \r, and \r\n). * * "hello".chomp #=> "hello" -- cgit v1.2.3 From fcd3f8450d75033af8a0c472ee9c1352e1a8186e Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sat, 14 Sep 2019 09:00:21 +0900 Subject: Raise an error from `String#<=>` with a non string operand. --- src/string.c | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) (limited to 'src/string.c') diff --git a/src/string.c b/src/string.c index 35c7f8e7c..2454eb0fb 100644 --- a/src/string.c +++ b/src/string.c @@ -1036,21 +1036,7 @@ mrb_str_cmp_m(mrb_state *mrb, mrb_value str1) mrb_get_args(mrb, "o", &str2); if (!mrb_string_p(str2)) { - if (!mrb_respond_to(mrb, str2, mrb_intern_lit(mrb, "to_s"))) { - return mrb_nil_value(); - } - else if (!mrb_respond_to(mrb, str2, mrb_intern_lit(mrb, "<=>"))) { - return mrb_nil_value(); - } - else { - mrb_value tmp = mrb_funcall(mrb, str2, "<=>", 1, str1); - - if (mrb_nil_p(tmp)) return mrb_nil_value(); - if (!mrb_fixnum_p(tmp)) { - return mrb_funcall(mrb, mrb_fixnum_value(0), "-", 1, tmp); - } - result = -mrb_fixnum(tmp); - } + return mrb_nil_value(); } else { result = mrb_str_cmp(mrb, str1, str2); -- cgit v1.2.3 From 57d7fe94a9049c7abaa5b061a0f61a5f44815733 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sat, 14 Sep 2019 19:51:52 +0900 Subject: Add a macro `mrb_frozen_p` that points to `MRB_FROZEN_P`. --- include/mruby.h | 2 +- include/mruby/object.h | 1 + mrbgems/mruby-string-ext/src/string.c | 4 ++-- src/array.c | 2 +- src/error.c | 2 +- src/hash.c | 2 +- src/kernel.c | 4 ++-- src/string.c | 4 ++-- 8 files changed, 11 insertions(+), 10 deletions(-) (limited to 'src/string.c') diff --git a/include/mruby.h b/include/mruby.h index c50054b79..aa4a987af 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -1221,7 +1221,7 @@ MRB_API void mrb_check_type(mrb_state *mrb, mrb_value x, enum mrb_vtype t); MRB_INLINE void mrb_check_frozen(mrb_state *mrb, void *o) { - if (MRB_FROZEN_P((struct RBasic*)o)) mrb_frozen_error(mrb, o); + if (mrb_frozen_p((struct RBasic*)o)) mrb_frozen_error(mrb, o); } typedef enum call_type { diff --git a/include/mruby/object.h b/include/mruby/object.h index 53511a1bb..f75e99f1b 100644 --- a/include/mruby/object.h +++ b/include/mruby/object.h @@ -25,6 +25,7 @@ struct RBasic { #define MRB_FROZEN_P(o) ((o)->flags & MRB_FL_OBJ_IS_FROZEN) #define MRB_SET_FROZEN_FLAG(o) ((o)->flags |= MRB_FL_OBJ_IS_FROZEN) #define MRB_UNSET_FROZEN_FLAG(o) ((o)->flags &= ~MRB_FL_OBJ_IS_FROZEN) +#define mrb_frozen_p(o) MRB_FROZEN_P(o) struct RObject { MRB_OBJECT_HEADER; diff --git a/mrbgems/mruby-string-ext/src/string.c b/mrbgems/mruby-string-ext/src/string.c index aa6270786..f1d31888d 100644 --- a/mrbgems/mruby-string-ext/src/string.c +++ b/mrbgems/mruby-string-ext/src/string.c @@ -1081,7 +1081,7 @@ mrb_str_del_prefix_bang(mrb_state *mrb, mrb_value self) if (plen > slen) return mrb_nil_value(); s = RSTR_PTR(str); if (memcmp(s, ptr, plen) != 0) return mrb_nil_value(); - if (!MRB_FROZEN_P(str) && (RSTR_SHARED_P(str) || RSTR_FSHARED_P(str))) { + if (!mrb_frozen_p(str) && (RSTR_SHARED_P(str) || RSTR_FSHARED_P(str))) { str->as.heap.ptr += plen; } else { @@ -1138,7 +1138,7 @@ mrb_str_del_suffix_bang(mrb_state *mrb, mrb_value self) if (plen > slen) return mrb_nil_value(); s = RSTR_PTR(str); if (memcmp(s+slen-plen, ptr, plen) != 0) return mrb_nil_value(); - if (!MRB_FROZEN_P(str) && (RSTR_SHARED_P(str) || RSTR_FSHARED_P(str))) { + if (!mrb_frozen_p(str) && (RSTR_SHARED_P(str) || RSTR_FSHARED_P(str))) { /* no need to modify string */ } else { diff --git a/src/array.c b/src/array.c index 33baceb9c..a958e12e0 100644 --- a/src/array.c +++ b/src/array.c @@ -388,7 +388,7 @@ ary_replace(mrb_state *mrb, struct RArray *a, struct RArray *b) mrb_write_barrier(mrb, (struct RBasic*)a); return; } - if (!MRB_FROZEN_P(b) && len > ARY_REPLACE_SHARED_MIN) { + if (!mrb_frozen_p(b) && len > ARY_REPLACE_SHARED_MIN) { ary_make_shared(mrb, b); goto shared_b; } diff --git a/src/error.c b/src/error.c index 2bb505d85..ad0be209d 100644 --- a/src/error.c +++ b/src/error.c @@ -233,7 +233,7 @@ mrb_exc_set(mrb_state *mrb, mrb_value exc) (struct RBasic*)mrb->exc == mrb->gc.arena[mrb->gc.arena_idx-1]) { mrb->gc.arena_idx--; } - if (!mrb->gc.out_of_memory && !MRB_FROZEN_P(mrb->exc)) { + if (!mrb->gc.out_of_memory && !mrb_frozen_p(mrb->exc)) { exc_debug_info(mrb, mrb->exc); mrb_keep_backtrace(mrb, exc); } diff --git a/src/hash.c b/src/hash.c index 2a0a19363..83c986c46 100644 --- a/src/hash.c +++ b/src/hash.c @@ -576,7 +576,7 @@ static void mrb_hash_modify(mrb_state *mrb, mrb_value hash); static inline mrb_value ht_key(mrb_state *mrb, mrb_value key) { - if (mrb_string_p(key) && !MRB_FROZEN_P(mrb_str_ptr(key))) { + if (mrb_string_p(key) && !mrb_frozen_p(mrb_str_ptr(key))) { key = mrb_str_dup(mrb, key); MRB_SET_FROZEN_FLAG(mrb_str_ptr(key)); } diff --git a/src/kernel.c b/src/kernel.c index f0935a2f8..bde0cb22a 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -436,7 +436,7 @@ mrb_obj_freeze(mrb_state *mrb, mrb_value self) { if (!mrb_immediate_p(self)) { struct RBasic *b = mrb_basic_ptr(self); - if (!MRB_FROZEN_P(b)) { + if (!mrb_frozen_p(b)) { MRB_SET_FROZEN_FLAG(b); if (b->c->tt == MRB_TT_SCLASS) MRB_SET_FROZEN_FLAG(b->c); } @@ -447,7 +447,7 @@ mrb_obj_freeze(mrb_state *mrb, mrb_value self) static mrb_value mrb_obj_frozen(mrb_state *mrb, mrb_value self) { - return mrb_bool_value(mrb_immediate_p(self) || MRB_FROZEN_P(mrb_basic_ptr(self))); + return mrb_bool_value(mrb_immediate_p(self) || mrb_frozen_p(mrb_basic_ptr(self))); } /* 15.3.1.3.15 */ diff --git a/src/string.c b/src/string.c index 2454eb0fb..7abb3148c 100644 --- a/src/string.c +++ b/src/string.c @@ -535,7 +535,7 @@ str_make_shared(mrb_state *mrb, struct RString *orig, struct RString *s) else if (RSTR_FSHARED_P(orig)) { str_init_fshared(orig, s, orig->as.heap.aux.fshared); } - else if (MRB_FROZEN_P(orig) && !RSTR_POOL_P(orig)) { + else if (mrb_frozen_p(orig) && !RSTR_POOL_P(orig)) { str_init_fshared(orig, s, orig); } else { @@ -2405,7 +2405,7 @@ mrb_string_value_cstr(mrb_state *mrb, mrb_value *ptr) if (p[len] == '\0') { return p; } - if (MRB_FROZEN_P(ps) || RSTR_CAPA(ps) == len) { + if (mrb_frozen_p(ps) || RSTR_CAPA(ps) == len) { ps = str_new(mrb, NULL, len+1); memcpy(RSTR_PTR(ps), p, len); RSTR_SET_LEN(ps, len); -- cgit v1.2.3 From e61095426bbb0de2ab0a941f9ed3a3acdb7833e8 Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Thu, 19 Sep 2019 20:19:38 +0900 Subject: Simplify arguments check in `String#index` Also fix document about type of the first argument. --- src/string.c | 54 +++++++++++++----------------------------------------- test/t/string.rb | 4 ++++ 2 files changed, 17 insertions(+), 41 deletions(-) (limited to 'src/string.c') diff --git a/src/string.c b/src/string.c index 7abb3148c..48df958ec 100644 --- a/src/string.c +++ b/src/string.c @@ -1757,22 +1757,16 @@ mrb_str_include(mrb_state *mrb, mrb_value self) /* * call-seq: * str.index(substring [, offset]) => fixnum or nil - * str.index(fixnum [, offset]) => fixnum or nil - * str.index(regexp [, offset]) => fixnum or nil * * Returns the index of the first occurrence of the given - * substring, - * character (fixnum), or pattern (regexp) in str. - * Returns - * nil if not found. + * substring. Returns nil if not found. * If the second parameter is present, it * specifies the position in the string to begin the search. * - * "hello".index('e') #=> 1 + * "hello".index('l') #=> 2 * "hello".index('lo') #=> 3 * "hello".index('a') #=> nil - * "hello".index(101) #=> 1(101=0x65='e') - * "hello".index(/[aeiou]/, -3) #=> 4 + * "hello".index('l', -2) #=> 3 */ static mrb_value mrb_str_index_m(mrb_state *mrb, mrb_value str) @@ -1780,39 +1774,17 @@ mrb_str_index_m(mrb_state *mrb, mrb_value str) mrb_value sub; mrb_int pos; - switch (mrb_get_args(mrb, "|oi", &sub, &pos)) { - case 0: - sub = mrb_nil_value(); - /* fall through */ - case 1: - pos = 0; - break; - case 2: - if (pos < 0) { - mrb_int clen = RSTRING_CHAR_LEN(str); - pos += clen; - if (pos < 0) { - return mrb_nil_value(); - } - } - break; + if (mrb_get_args(mrb, "S|i", &sub, &pos) == 1) { + pos = 0; } - - switch (mrb_type(sub)) { - default: { - mrb_value tmp; - - tmp = mrb_check_string_type(mrb, sub); - if (mrb_nil_p(tmp)) { - mrb_raisef(mrb, E_TYPE_ERROR, "type mismatch: %v given", sub); - } - sub = tmp; + else if (pos < 0) { + mrb_int clen = RSTRING_CHAR_LEN(str); + pos += clen; + if (pos < 0) { + return mrb_nil_value(); } - /* fall through */ - case MRB_TT_STRING: - pos = str_index_str_by_char(mrb, str, sub, pos); - break; } + pos = str_index_str_by_char(mrb, str, sub, pos); if (pos == -1) return mrb_nil_value(); BYTES_ALIGN_CHECK(pos); @@ -3057,7 +3029,7 @@ mrb_init_string(mrb_state *mrb) mrb_define_method(mrb, s, "hash", mrb_str_hash_m, MRB_ARGS_NONE()); /* 15.2.10.5.20 */ mrb_define_method(mrb, s, "include?", mrb_str_include, MRB_ARGS_REQ(1)); /* 15.2.10.5.21 */ - mrb_define_method(mrb, s, "index", mrb_str_index_m, MRB_ARGS_ANY()); /* 15.2.10.5.22 */ + mrb_define_method(mrb, s, "index", mrb_str_index_m, MRB_ARGS_ARG(1,1)); /* 15.2.10.5.22 */ mrb_define_method(mrb, s, "initialize", mrb_str_init, MRB_ARGS_REQ(1)); /* 15.2.10.5.23 */ mrb_define_method(mrb, s, "initialize_copy", mrb_str_replace, MRB_ARGS_REQ(1)); /* 15.2.10.5.24 */ mrb_define_method(mrb, s, "intern", mrb_str_intern, MRB_ARGS_NONE()); /* 15.2.10.5.25 */ @@ -3084,7 +3056,7 @@ mrb_init_string(mrb_state *mrb) mrb_define_method(mrb, s, "getbyte", mrb_str_getbyte, MRB_ARGS_REQ(1)); mrb_define_method(mrb, s, "setbyte", mrb_str_setbyte, MRB_ARGS_REQ(2)); - mrb_define_method(mrb, s, "byteslice", mrb_str_byteslice, MRB_ARGS_REQ(1)|MRB_ARGS_OPT(1)); + mrb_define_method(mrb, s, "byteslice", mrb_str_byteslice, MRB_ARGS_ARG(1,1)); } #ifndef MRB_WITHOUT_FLOAT diff --git a/test/t/string.rb b/test/t/string.rb index c820bfa92..01f3da327 100644 --- a/test/t/string.rb +++ b/test/t/string.rb @@ -451,12 +451,16 @@ assert('String#index', '15.2.10.5.22') do assert_equal 3, 'abcabc'.index('a', 1) assert_equal 5, "hello".index("", 5) assert_equal nil, "hello".index("", 6) + assert_equal 3, "hello".index("l", -2) + assert_raise(ArgumentError) { "hello".index } + assert_raise(TypeError) { "hello".index(101) } end assert('String#index(UTF-8)', '15.2.10.5.22') do assert_equal 0, '⓿➊➋➌➍➎'.index('⓿') assert_nil '⓿➊➋➌➍➎'.index('➓') assert_equal 6, '⓿➊➋➌➍➎⓿➊➋➌➍➎'.index('⓿', 1) + assert_equal 6, '⓿➊➋➌➍➎⓿➊➋➌➍➎'.index('⓿', -7) assert_equal 6, "⓿➊➋➌➍➎".index("", 6) assert_equal nil, "⓿➊➋➌➍➎".index("", 7) assert_equal 0, '⓿➊➋➌➍➎'.index("\xe2") -- cgit v1.2.3 From a365f9a67d4bf082ee9a414fe247bd18148d7081 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 25 Sep 2019 21:46:26 +0900 Subject: Rename symbol-to-string functions; close #4684 * mrb_sym2name -> mrb_sym_name * mrb_sym2name_len -> mrb_sym_name_len * mrb_sym2str -> mrb_sym_str --- include/mruby.h | 9 ++-- mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c | 4 +- mrbgems/mruby-compiler/core/codegen.c | 12 ++--- mrbgems/mruby-compiler/core/parse.y | 64 ++++++++++++------------ mrbgems/mruby-metaprog/src/metaprog.c | 4 +- mrbgems/mruby-proc-ext/src/proc.c | 2 +- mrbgems/mruby-struct/src/struct.c | 2 +- mrbgems/mruby-symbol-ext/src/symbol.c | 4 +- src/backtrace.c | 4 +- src/class.c | 8 +-- src/codedump.c | 52 +++++++++---------- src/debug.c | 4 +- src/dump.c | 12 ++--- src/string.c | 2 +- src/symbol.c | 16 +++--- src/variable.c | 14 +++--- src/vm.c | 2 +- 17 files changed, 109 insertions(+), 106 deletions(-) (limited to 'src/string.c') diff --git a/include/mruby.h b/include/mruby.h index e6371564e..451f39660 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -997,9 +997,12 @@ MRB_API mrb_sym mrb_intern_str(mrb_state*,mrb_value); MRB_API mrb_value mrb_check_intern_cstr(mrb_state*,const char*); MRB_API mrb_value mrb_check_intern(mrb_state*,const char*,size_t); MRB_API mrb_value mrb_check_intern_str(mrb_state*,mrb_value); -MRB_API const char *mrb_sym2name(mrb_state*,mrb_sym); -MRB_API const char *mrb_sym2name_len(mrb_state*,mrb_sym,mrb_int*); -MRB_API mrb_value mrb_sym2str(mrb_state*,mrb_sym); +MRB_API const char *mrb_sym_name(mrb_state*,mrb_sym); +MRB_API const char *mrb_sym_name_len(mrb_state*,mrb_sym,mrb_int*); +MRB_API mrb_value mrb_sym_str(mrb_state*,mrb_sym); +#define mrb_sym2name(mrb,sym) mrb_sym_name(mrb,sym) +#define mrb_sym2name_len(mrb,sym,len) mrb_sym_name_len(mrb,sym,len) +#define mrb_sym2str(mrb,sym) mrb_sym_str(mrb,sym) MRB_API void *mrb_malloc(mrb_state*, size_t); /* raise RuntimeError if no mem */ MRB_API void *mrb_calloc(mrb_state*, size_t, size_t); /* ditto */ diff --git a/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c b/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c index 530d824eb..ceeb27393 100644 --- a/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c +++ b/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c @@ -95,7 +95,7 @@ check_file_lineno(mrb_state *mrb, struct mrb_irep *irep, const char *file, uint1 for (f_idx = 0; f_idx < irep->debug_info->flen; ++f_idx) { const char *filename; info_file = irep->debug_info->files[f_idx]; - filename = mrb_sym2name_len(mrb, info_file->filename_sym, NULL); + filename = mrb_sym_name_len(mrb, info_file->filename_sym, NULL); if (!strcmp(filename, file)) { result = MRB_DEBUG_BP_FILE_OK; @@ -126,7 +126,7 @@ compare_break_method(mrb_state *mrb, mrb_debug_breakpoint *bp, struct RClass *cl mrb_debug_methodpoint *method_p; mrb_bool is_defined; - method_name = mrb_sym2name(mrb, method_sym); + method_name = mrb_sym_name(mrb, method_sym); method_p = &bp->point.methodpoint; if (strcmp(method_p->method_name, method_name) == 0) { diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index c0986893c..1989c0cf1 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -108,7 +108,7 @@ codegen_error(codegen_scope *s, const char *message) } #ifndef MRB_DISABLE_STDIO if (s->filename_sym && s->lineno) { - const char *filename = mrb_sym2name_len(s->mrb, s->filename_sym, NULL); + const char *filename = mrb_sym_name_len(s->mrb, s->filename_sym, NULL); fprintf(stderr, "codegen error:%s:%d: %s\n", filename, s->lineno, message); } else { @@ -922,7 +922,7 @@ attrsym(codegen_scope *s, mrb_sym a) mrb_int len; char *name2; - name = mrb_sym2name_len(s->mrb, a, &len); + name = mrb_sym_name_len(s->mrb, a, &len); name2 = (char *)codegen_palloc(s, (size_t)len + 1 /* '=' */ @@ -1046,7 +1046,7 @@ gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe) pop_n(n+1); { mrb_int symlen; - const char *symname = mrb_sym2name_len(s->mrb, sym, &symlen); + const char *symname = mrb_sym_name_len(s->mrb, sym, &symlen); if (!noop && symlen == 1 && symname[0] == '+' && n == 1) { gen_addsub(s, OP_ADD, cursp()); @@ -1406,7 +1406,7 @@ codegen(codegen_scope *s, node *tree, int val) } if (s->irep && s->filename_index != tree->filename_index) { mrb_sym fname = mrb_parser_get_filename(s->parser, s->filename_index); - const char *filename = mrb_sym2name_len(s->mrb, fname, NULL); + const char *filename = mrb_sym_name_len(s->mrb, fname, NULL); mrb_debug_info_append_file(s->mrb, s->irep->debug_info, filename, s->lines, s->debug_start_pos, s->pc); @@ -1987,7 +1987,7 @@ codegen(codegen_scope *s, node *tree, int val) { mrb_sym sym = nsym(tree->cdr->car); mrb_int len; - const char *name = mrb_sym2name_len(s->mrb, sym, &len); + const char *name = mrb_sym_name_len(s->mrb, sym, &len); int idx, callargs = -1, vsp = -1; if ((len == 2 && name[0] == '|' && name[1] == '|') && @@ -3065,7 +3065,7 @@ scope_finish(codegen_scope *s) irep->reps = (mrb_irep**)codegen_realloc(s, irep->reps, sizeof(mrb_irep*)*irep->rlen); if (s->filename_sym) { mrb_sym fname = mrb_parser_get_filename(s->parser, s->filename_index); - const char *filename = mrb_sym2name_len(s->mrb, fname, NULL); + const char *filename = mrb_sym_name_len(s->mrb, fname, NULL); mrb_debug_info_append_file(s->mrb, s->irep->debug_info, filename, s->lines, s->debug_start_pos, s->pc); diff --git a/mrbgems/mruby-compiler/core/parse.y b/mrbgems/mruby-compiler/core/parse.y index 6576ab702..5848e9ca3 100644 --- a/mrbgems/mruby-compiler/core/parse.y +++ b/mrbgems/mruby-compiler/core/parse.y @@ -3231,7 +3231,7 @@ var_ref : variable } | keyword__FILE__ { - const char *fn = mrb_sym2name_len(p->mrb, p->filename_sym, NULL); + const char *fn = mrb_sym_name_len(p->mrb, p->filename_sym, NULL); if (!fn) { fn = "(null)"; } @@ -3741,7 +3741,7 @@ yyerror(parser_state *p, const char *s) if (! p->capture_errors) { #ifndef MRB_DISABLE_STDIO if (p->filename_sym) { - const char *filename = mrb_sym2name_len(p->mrb, p->filename_sym, NULL); + const char *filename = mrb_sym_name_len(p->mrb, p->filename_sym, NULL); fprintf(stderr, "%s:%d:%d: %s\n", filename, p->lineno, p->column, s); } else { @@ -3780,7 +3780,7 @@ yywarn(parser_state *p, const char *s) if (! p->capture_errors) { #ifndef MRB_DISABLE_STDIO if (p->filename_sym) { - const char *filename = mrb_sym2name_len(p->mrb, p->filename_sym, NULL); + const char *filename = mrb_sym_name_len(p->mrb, p->filename_sym, NULL); fprintf(stderr, "%s:%d:%d: warning: %s\n", filename, p->lineno, p->column, s); } else { @@ -6395,7 +6395,7 @@ dump_args(mrb_state *mrb, node *n, int offset) while (n2) { dump_prefix(n2, offset+2); - printf("%s=\n", mrb_sym2name(mrb, sym(n2->car->car))); + printf("%s=\n", mrb_sym_name(mrb, sym(n2->car->car))); mrb_parser_dump(mrb, n2->car->cdr, offset+3); n2 = n2->cdr; } @@ -6404,7 +6404,7 @@ dump_args(mrb_state *mrb, node *n, int offset) n = n->cdr; if (n->car) { dump_prefix(n, offset+1); - printf("rest=*%s\n", mrb_sym2name(mrb, sym(n->car))); + printf("rest=*%s\n", mrb_sym_name(mrb, sym(n->car))); } n = n->cdr; if (n->car) { @@ -6623,7 +6623,7 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) while (n2) { if (n2->car) { if (!first_lval) printf(", "); - printf("%s", mrb_sym2name(mrb, sym(n2->car))); + printf("%s", mrb_sym_name(mrb, sym(n2->car))); first_lval = FALSE; } n2 = n2->cdr; @@ -6651,7 +6651,7 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) mrb_parser_dump(mrb, tree->car, offset+1); dump_prefix(tree, offset+1); printf("method='%s' (%d)\n", - mrb_sym2name(mrb, sym(tree->cdr->car)), + mrb_sym_name(mrb, sym(tree->cdr->car)), intn(tree->cdr->car)); tree = tree->cdr->cdr->car; if (tree) { @@ -6682,11 +6682,11 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) printf("NODE_COLON2:\n"); mrb_parser_dump(mrb, tree->car, offset+1); dump_prefix(tree, offset+1); - printf("::%s\n", mrb_sym2name(mrb, sym(tree->cdr))); + printf("::%s\n", mrb_sym_name(mrb, sym(tree->cdr))); break; case NODE_COLON3: - printf("NODE_COLON3: ::%s\n", mrb_sym2name(mrb, sym(tree))); + printf("NODE_COLON3: ::%s\n", mrb_sym_name(mrb, sym(tree))); break; case NODE_ARRAY: @@ -6782,7 +6782,7 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) mrb_parser_dump(mrb, tree->car, offset+2); tree = tree->cdr; dump_prefix(tree, offset+1); - printf("op='%s' (%d)\n", mrb_sym2name(mrb, sym(tree->car)), intn(tree->car)); + printf("op='%s' (%d)\n", mrb_sym_name(mrb, sym(tree->car)), intn(tree->car)); tree = tree->cdr; mrb_parser_dump(mrb, tree->car, offset+1); break; @@ -6834,23 +6834,23 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) break; case NODE_LVAR: - printf("NODE_LVAR %s\n", mrb_sym2name(mrb, sym(tree))); + printf("NODE_LVAR %s\n", mrb_sym_name(mrb, sym(tree))); break; case NODE_GVAR: - printf("NODE_GVAR %s\n", mrb_sym2name(mrb, sym(tree))); + printf("NODE_GVAR %s\n", mrb_sym_name(mrb, sym(tree))); break; case NODE_IVAR: - printf("NODE_IVAR %s\n", mrb_sym2name(mrb, sym(tree))); + printf("NODE_IVAR %s\n", mrb_sym_name(mrb, sym(tree))); break; case NODE_CVAR: - printf("NODE_CVAR %s\n", mrb_sym2name(mrb, sym(tree))); + printf("NODE_CVAR %s\n", mrb_sym_name(mrb, sym(tree))); break; case NODE_CONST: - printf("NODE_CONST %s\n", mrb_sym2name(mrb, sym(tree))); + printf("NODE_CONST %s\n", mrb_sym_name(mrb, sym(tree))); break; case NODE_MATCH: @@ -6872,7 +6872,7 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) break; case NODE_ARG: - printf("NODE_ARG %s\n", mrb_sym2name(mrb, sym(tree))); + printf("NODE_ARG %s\n", mrb_sym_name(mrb, sym(tree))); break; case NODE_BLOCK_ARG: @@ -6931,7 +6931,7 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) break; case NODE_SYM: - printf("NODE_SYM :%s (%d)\n", mrb_sym2name(mrb, sym(tree)), + printf("NODE_SYM :%s (%d)\n", mrb_sym_name(mrb, sym(tree)), intn(tree)); break; @@ -6953,8 +6953,8 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) case NODE_ALIAS: printf("NODE_ALIAS %s %s:\n", - mrb_sym2name(mrb, sym(tree->car)), - mrb_sym2name(mrb, sym(tree->cdr))); + mrb_sym_name(mrb, sym(tree->car)), + mrb_sym_name(mrb, sym(tree->cdr))); break; case NODE_UNDEF: @@ -6962,7 +6962,7 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) { node *t = tree; while (t) { - printf(" %s", mrb_sym2name(mrb, sym(t->car))); + printf(" %s", mrb_sym_name(mrb, sym(t->car))); t = t->cdr; } } @@ -6973,16 +6973,16 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) printf("NODE_CLASS:\n"); if (tree->car->car == (node*)0) { dump_prefix(tree, offset+1); - printf(":%s\n", mrb_sym2name(mrb, sym(tree->car->cdr))); + printf(":%s\n", mrb_sym_name(mrb, sym(tree->car->cdr))); } else if (tree->car->car == (node*)1) { dump_prefix(tree, offset+1); - printf("::%s\n", mrb_sym2name(mrb, sym(tree->car->cdr))); + printf("::%s\n", mrb_sym_name(mrb, sym(tree->car->cdr))); } else { mrb_parser_dump(mrb, tree->car->car, offset+1); dump_prefix(tree, offset+1); - printf("::%s\n", mrb_sym2name(mrb, sym(tree->car->cdr))); + printf("::%s\n", mrb_sym_name(mrb, sym(tree->car->cdr))); } if (tree->cdr->car) { dump_prefix(tree, offset+1); @@ -6998,16 +6998,16 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) printf("NODE_MODULE:\n"); if (tree->car->car == (node*)0) { dump_prefix(tree, offset+1); - printf(":%s\n", mrb_sym2name(mrb, sym(tree->car->cdr))); + printf(":%s\n", mrb_sym_name(mrb, sym(tree->car->cdr))); } else if (tree->car->car == (node*)1) { dump_prefix(tree, offset+1); - printf("::%s\n", mrb_sym2name(mrb, sym(tree->car->cdr))); + printf("::%s\n", mrb_sym_name(mrb, sym(tree->car->cdr))); } else { mrb_parser_dump(mrb, tree->car->car, offset+1); dump_prefix(tree, offset+1); - printf("::%s\n", mrb_sym2name(mrb, sym(tree->car->cdr))); + printf("::%s\n", mrb_sym_name(mrb, sym(tree->car->cdr))); } dump_prefix(tree, offset+1); printf("body:\n"); @@ -7025,7 +7025,7 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) case NODE_DEF: printf("NODE_DEF:\n"); dump_prefix(tree, offset+1); - printf("%s\n", mrb_sym2name(mrb, sym(tree->car))); + printf("%s\n", mrb_sym_name(mrb, sym(tree->car))); tree = tree->cdr; { node *n2 = tree->car; @@ -7038,7 +7038,7 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) while (n2) { if (n2->car) { if (!first_lval) printf(", "); - printf("%s", mrb_sym2name(mrb, sym(n2->car))); + printf("%s", mrb_sym_name(mrb, sym(n2->car))); first_lval = FALSE; } n2 = n2->cdr; @@ -7058,7 +7058,7 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) mrb_parser_dump(mrb, tree->car, offset+1); tree = tree->cdr; dump_prefix(tree, offset+1); - printf(":%s\n", mrb_sym2name(mrb, sym(tree->car))); + printf(":%s\n", mrb_sym_name(mrb, sym(tree->car))); tree = tree->cdr->cdr; if (tree->car) { dump_args(mrb, tree->car, offset+1); @@ -7095,17 +7095,17 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) tree = tree->cdr; if (tree->car) { dump_prefix(tree, offset+1); - printf("block='%s'\n", mrb_sym2name(mrb, sym(tree->car))); + printf("block='%s'\n", mrb_sym_name(mrb, sym(tree->car))); } break; case NODE_KW_ARG: - printf("NODE_KW_ARG %s\n", mrb_sym2name(mrb, sym(tree->car))); + printf("NODE_KW_ARG %s\n", mrb_sym_name(mrb, sym(tree->car))); mrb_parser_dump(mrb, tree->cdr->car, offset + 1); break; case NODE_KW_REST_ARGS: - printf("NODE_KW_REST_ARGS %s\n", mrb_sym2name(mrb, sym(tree))); + printf("NODE_KW_REST_ARGS %s\n", mrb_sym_name(mrb, sym(tree))); break; default: diff --git a/mrbgems/mruby-metaprog/src/metaprog.c b/mrbgems/mruby-metaprog/src/metaprog.c index 87f1d3280..3f22596eb 100644 --- a/mrbgems/mruby-metaprog/src/metaprog.c +++ b/mrbgems/mruby-metaprog/src/metaprog.c @@ -150,7 +150,7 @@ mrb_local_variables(mrb_state *mrb, mrb_value self) for (i = 0; i + 1 < irep->nlocals; ++i) { if (irep->lv[i].name) { mrb_sym sym = irep->lv[i].name; - const char *name = mrb_sym2name(mrb, sym); + const char *name = mrb_sym_name(mrb, sym); switch (name[0]) { case '*': case '&': break; @@ -409,7 +409,7 @@ static void check_cv_name_sym(mrb_state *mrb, mrb_sym id) { mrb_int len; - const char *name = mrb_sym2name_len(mrb, id, &len); + const char *name = mrb_sym_name_len(mrb, id, &len); if (!cv_name_p(mrb, name, len)) { mrb_name_error(mrb, id, "'%n' is not allowed as a class variable name", id); } diff --git a/mrbgems/mruby-proc-ext/src/proc.c b/mrbgems/mruby-proc-ext/src/proc.c index 1627ee474..a7faeebea 100644 --- a/mrbgems/mruby-proc-ext/src/proc.c +++ b/mrbgems/mruby-proc-ext/src/proc.c @@ -150,7 +150,7 @@ mrb_proc_parameters(mrb_state *mrb, mrb_value self) mrb_ary_push(mrb, a, sname); if (i < max && irep->lv[i].name) { mrb_sym sym = irep->lv[i].name; - const char *name = mrb_sym2name(mrb, sym); + const char *name = mrb_sym_name(mrb, sym); switch (name[0]) { case '*': case '&': break; diff --git a/mrbgems/mruby-struct/src/struct.c b/mrbgems/mruby-struct/src/struct.c index ebe711ed3..2d82c2466 100644 --- a/mrbgems/mruby-struct/src/struct.c +++ b/mrbgems/mruby-struct/src/struct.c @@ -132,7 +132,7 @@ mrb_id_attrset(mrb_state *mrb, mrb_sym id) mrb_sym mid; char onstack[ONSTACK_ALLOC_MAX]; - name = mrb_sym2name_len(mrb, id, &len); + name = mrb_sym_name_len(mrb, id, &len); if (len > ONSTACK_STRLEN_MAX) { buf = (char *)mrb_malloc(mrb, (size_t)len+1); } diff --git a/mrbgems/mruby-symbol-ext/src/symbol.c b/mrbgems/mruby-symbol-ext/src/symbol.c index ccb2971dc..87f8381b1 100644 --- a/mrbgems/mruby-symbol-ext/src/symbol.c +++ b/mrbgems/mruby-symbol-ext/src/symbol.c @@ -46,10 +46,10 @@ mrb_sym_length(mrb_state *mrb, mrb_value self) mrb_int len; #ifdef MRB_UTF8_STRING mrb_int byte_len; - const char *name = mrb_sym2name_len(mrb, mrb_symbol(self), &byte_len); + const char *name = mrb_sym_name_len(mrb, mrb_symbol(self), &byte_len); len = mrb_utf8_len(name, byte_len); #else - mrb_sym2name_len(mrb, mrb_symbol(self), &len); + mrb_sym_name_len(mrb, mrb_symbol(self), &len); #endif return mrb_fixnum_value(len); } diff --git a/src/backtrace.c b/src/backtrace.c index 8001849bc..803c5e285 100644 --- a/src/backtrace.c +++ b/src/backtrace.c @@ -128,7 +128,7 @@ print_packed_backtrace(mrb_state *mrb, mrb_value packed) if (entry->method_id != 0) { const char *method_name; - method_name = mrb_sym2name(mrb, entry->method_id); + method_name = mrb_sym_name(mrb, entry->method_id); fprintf(stream, ":in %s", method_name); mrb_gc_arena_restore(mrb, ai); } @@ -249,7 +249,7 @@ mrb_unpack_backtrace(mrb_state *mrb, mrb_value backtrace) btline = mrb_format(mrb, "%s:%d", entry->filename, entry->lineno); if (entry->method_id != 0) { mrb_str_cat_lit(mrb, btline, ":in "); - mrb_str_cat_cstr(mrb, btline, mrb_sym2name(mrb, entry->method_id)); + mrb_str_cat_cstr(mrb, btline, mrb_sym_name(mrb, entry->method_id)); } mrb_ary_push(mrb, backtrace, btline); mrb_gc_arena_restore(mrb, ai); diff --git a/src/class.c b/src/class.c index 1b0a37d05..adb8954cc 100644 --- a/src/class.c +++ b/src/class.c @@ -73,7 +73,7 @@ mrb_class_name_class(mrb_state *mrb, struct RClass *outer, struct RClass *c, mrb return; } mrb_str_cat_cstr(mrb, name, "::"); - mrb_str_cat_cstr(mrb, name, mrb_sym2name(mrb, id)); + mrb_str_cat_cstr(mrb, name, mrb_sym_name(mrb, id)); } mrb_obj_iv_set_force(mrb, (struct RObject*)c, nsym, name); } @@ -1333,7 +1333,7 @@ prepare_name_common(mrb_state *mrb, mrb_sym sym, const char *prefix, const char { char onstack[ONSTACK_ALLOC_MAX]; mrb_int sym_len; - const char *sym_str = mrb_sym2name_len(mrb, sym, &sym_len); + const char *sym_str = mrb_sym_name_len(mrb, sym, &sym_len); size_t prefix_len = prefix ? strlen(prefix) : 0; size_t suffix_len = suffix ? strlen(suffix) : 0; size_t name_len = sym_len + prefix_len + suffix_len; @@ -1633,7 +1633,7 @@ mrb_class_path(mrb_state *mrb, struct RClass *c) } else if (mrb_symbol_p(path)) { /* toplevel class/module */ - return mrb_sym2str(mrb, mrb_symbol(path)); + return mrb_sym_str(mrb, mrb_symbol(path)); } return mrb_str_dup(mrb, path); } @@ -1866,7 +1866,7 @@ static void check_const_name_sym(mrb_state *mrb, mrb_sym id) { mrb_int len; - const char *name = mrb_sym2name_len(mrb, id, &len); + const char *name = mrb_sym_name_len(mrb, id, &len); if (!mrb_const_name_p(mrb, name, len)) { mrb_name_error(mrb, id, "wrong constant name %n", id); } diff --git a/src/codedump.c b/src/codedump.c index b77a8adb4..2a82e5d2e 100644 --- a/src/codedump.c +++ b/src/codedump.c @@ -16,7 +16,7 @@ print_r(mrb_state *mrb, mrb_irep *irep, size_t n) for (i=0; i+1nlocals; i++) { if (irep->lv[i].r == n) { mrb_sym sym = irep->lv[i].name; - printf(" R%d:%s", (int)n, mrb_sym2name(mrb, sym)); + printf(" R%d:%s", (int)n, mrb_sym_name(mrb, sym)); break; } } @@ -82,7 +82,7 @@ codedump(mrb_state *mrb, mrb_irep *irep) printf("local variable names:\n"); for (i = 1; i < irep->nlocals; ++i) { - char const *s = mrb_sym2name(mrb, irep->lv[i - 1].name); + char const *s = mrb_sym_name(mrb, irep->lv[i - 1].name); int n = irep->lv[i - 1].r ? irep->lv[i - 1].r : i; printf(" R%d:%s\n", n, s ? s : ""); } @@ -147,7 +147,7 @@ codedump(mrb_state *mrb, mrb_irep *irep) print_lv_a(mrb, irep, a); break; CASE(OP_LOADSYM, BB): - printf("OP_LOADSYM\tR%d\t:%s\t", a, mrb_sym2name(mrb, irep->syms[b])); + printf("OP_LOADSYM\tR%d\t:%s\t", a, mrb_sym_name(mrb, irep->syms[b])); print_lv_a(mrb, irep, a); break; CASE(OP_LOADNIL, B): @@ -167,43 +167,43 @@ codedump(mrb_state *mrb, mrb_irep *irep) print_lv_a(mrb, irep, a); break; CASE(OP_GETGV, BB): - printf("OP_GETGV\tR%d\t:%s", a, mrb_sym2name(mrb, irep->syms[b])); + printf("OP_GETGV\tR%d\t:%s", a, mrb_sym_name(mrb, irep->syms[b])); print_lv_a(mrb, irep, a); break; CASE(OP_SETGV, BB): - printf("OP_SETGV\t:%s\tR%d", mrb_sym2name(mrb, irep->syms[b]), a); + printf("OP_SETGV\t:%s\tR%d", mrb_sym_name(mrb, irep->syms[b]), a); print_lv_a(mrb, irep, a); break; CASE(OP_GETSV, BB): - printf("OP_GETSV\tR%d\t:%s", a, mrb_sym2name(mrb, irep->syms[b])); + printf("OP_GETSV\tR%d\t:%s", a, mrb_sym_name(mrb, irep->syms[b])); print_lv_a(mrb, irep, a); break; CASE(OP_SETSV, BB): - printf("OP_SETSV\t:%s\tR%d", mrb_sym2name(mrb, irep->syms[b]), a); + printf("OP_SETSV\t:%s\tR%d", mrb_sym_name(mrb, irep->syms[b]), a); print_lv_a(mrb, irep, a); break; CASE(OP_GETCONST, BB): - printf("OP_GETCONST\tR%d\t:%s", a, mrb_sym2name(mrb, irep->syms[b])); + printf("OP_GETCONST\tR%d\t:%s", a, mrb_sym_name(mrb, irep->syms[b])); print_lv_a(mrb, irep, a); break; CASE(OP_SETCONST, BB): - printf("OP_SETCONST\t:%s\tR%d", mrb_sym2name(mrb, irep->syms[b]), a); + printf("OP_SETCONST\t:%s\tR%d", mrb_sym_name(mrb, irep->syms[b]), a); print_lv_a(mrb, irep, a); break; CASE(OP_GETMCNST, BB): - printf("OP_GETMCNST\tR%d\tR%d::%s", a, a, mrb_sym2name(mrb, irep->syms[b])); + printf("OP_GETMCNST\tR%d\tR%d::%s", a, a, mrb_sym_name(mrb, irep->syms[b])); print_lv_a(mrb, irep, a); break; CASE(OP_SETMCNST, BB): - printf("OP_SETMCNST\tR%d::%s\tR%d", a+1, mrb_sym2name(mrb, irep->syms[b]), a); + printf("OP_SETMCNST\tR%d::%s\tR%d", a+1, mrb_sym_name(mrb, irep->syms[b]), a); print_lv_a(mrb, irep, a); break; CASE(OP_GETIV, BB): - printf("OP_GETIV\tR%d\t%s", a, mrb_sym2name(mrb, irep->syms[b])); + printf("OP_GETIV\tR%d\t%s", a, mrb_sym_name(mrb, irep->syms[b])); print_lv_a(mrb, irep, a); break; CASE(OP_SETIV, BB): - printf("OP_SETIV\t%s\tR%d", mrb_sym2name(mrb, irep->syms[b]), a); + printf("OP_SETIV\t%s\tR%d", mrb_sym_name(mrb, irep->syms[b]), a); print_lv_a(mrb, irep, a); break; CASE(OP_GETUPVAR, BBB): @@ -215,11 +215,11 @@ codedump(mrb_state *mrb, mrb_irep *irep) print_lv_a(mrb, irep, a); break; CASE(OP_GETCV, BB): - printf("OP_GETCV\tR%d\t%s", a, mrb_sym2name(mrb, irep->syms[b])); + printf("OP_GETCV\tR%d\t%s", a, mrb_sym_name(mrb, irep->syms[b])); print_lv_a(mrb, irep, a); break; CASE(OP_SETCV, BB): - printf("OP_SETCV\t%s\tR%d", mrb_sym2name(mrb, irep->syms[b]), a); + printf("OP_SETCV\t%s\tR%d", mrb_sym_name(mrb, irep->syms[b]), a); print_lv_a(mrb, irep, a); break; CASE(OP_JMP, S): @@ -238,16 +238,16 @@ codedump(mrb_state *mrb, mrb_irep *irep) print_lv_a(mrb, irep, a); break; CASE(OP_SENDV, BB): - printf("OP_SENDV\tR%d\t:%s\n", a, mrb_sym2name(mrb, irep->syms[b])); + printf("OP_SENDV\tR%d\t:%s\n", a, mrb_sym_name(mrb, irep->syms[b])); break; CASE(OP_SENDVB, BB): - printf("OP_SENDVB\tR%d\t:%s\n", a, mrb_sym2name(mrb, irep->syms[b])); + printf("OP_SENDVB\tR%d\t:%s\n", a, mrb_sym_name(mrb, irep->syms[b])); break; CASE(OP_SEND, BBB): - printf("OP_SEND\tR%d\t:%s\t%d\n", a, mrb_sym2name(mrb, irep->syms[b]), c); + printf("OP_SEND\tR%d\t:%s\t%d\n", a, mrb_sym_name(mrb, irep->syms[b]), c); break; CASE(OP_SENDB, BBB): - printf("OP_SENDB\tR%d\t:%s\t%d\n", a, mrb_sym2name(mrb, irep->syms[b]), c); + printf("OP_SENDB\tR%d\t:%s\t%d\n", a, mrb_sym_name(mrb, irep->syms[b]), c); break; CASE(OP_CALL, Z): printf("OP_CALL\n"); @@ -275,14 +275,14 @@ codedump(mrb_state *mrb, mrb_irep *irep) MRB_ASPEC_BLOCK(a)); break; CASE(OP_KEY_P, BB): - printf("OP_KEY_P\tR%d\t:%s\t", a, mrb_sym2name(mrb, irep->syms[b])); + printf("OP_KEY_P\tR%d\t:%s\t", a, mrb_sym_name(mrb, irep->syms[b])); print_lv_a(mrb, irep, a); break; CASE(OP_KEYEND, Z): printf("OP_KEYEND\n"); break; CASE(OP_KARG, BB): - printf("OP_KARG\tR%d\t:%s\t", a, mrb_sym2name(mrb, irep->syms[b])); + printf("OP_KARG\tR%d\t:%s\t", a, mrb_sym_name(mrb, irep->syms[b])); print_lv_a(mrb, irep, a); break; CASE(OP_RETURN, B): @@ -322,13 +322,13 @@ codedump(mrb_state *mrb, mrb_irep *irep) printf("OP_RANGE_EXC\tR%d\n", a); break; CASE(OP_DEF, BB): - printf("OP_DEF\tR%d\t:%s\n", a, mrb_sym2name(mrb, irep->syms[b])); + printf("OP_DEF\tR%d\t:%s\n", a, mrb_sym_name(mrb, irep->syms[b])); break; CASE(OP_UNDEF, B): - printf("OP_UNDEF\t:%s\n", mrb_sym2name(mrb, irep->syms[a])); + printf("OP_UNDEF\t:%s\n", mrb_sym_name(mrb, irep->syms[a])); break; CASE(OP_ALIAS, BB): - printf("OP_ALIAS\t:%s\t%s\n", mrb_sym2name(mrb, irep->syms[a]), mrb_sym2name(mrb, irep->syms[b])); + printf("OP_ALIAS\t:%s\t%s\n", mrb_sym_name(mrb, irep->syms[a]), mrb_sym_name(mrb, irep->syms[b])); break; CASE(OP_ADD, B): printf("OP_ADD\tR%d\t\n", a); @@ -429,11 +429,11 @@ codedump(mrb_state *mrb, mrb_irep *irep) print_lv_a(mrb, irep, a); break; CASE(OP_CLASS, BB): - printf("OP_CLASS\tR%d\t:%s", a, mrb_sym2name(mrb, irep->syms[b])); + printf("OP_CLASS\tR%d\t:%s", a, mrb_sym_name(mrb, irep->syms[b])); print_lv_a(mrb, irep, a); break; CASE(OP_MODULE, BB): - printf("OP_MODULE\tR%d\t:%s", a, mrb_sym2name(mrb, irep->syms[b])); + printf("OP_MODULE\tR%d\t:%s", a, mrb_sym_name(mrb, irep->syms[b])); print_lv_a(mrb, irep, a); break; CASE(OP_EXEC, BB): diff --git a/src/debug.c b/src/debug.c index 0dc02a1e3..b44c7d10e 100644 --- a/src/debug.c +++ b/src/debug.c @@ -57,7 +57,7 @@ mrb_debug_get_filename(mrb_state *mrb, mrb_irep *irep, ptrdiff_t pc) mrb_irep_debug_info_file* f = NULL; if (!irep->debug_info) return NULL; else if ((f = get_file(irep->debug_info, (uint32_t)pc))) { - return mrb_sym2name_len(mrb, f->filename_sym, NULL); + return mrb_sym_name_len(mrb, f->filename_sym, NULL); } } return NULL; @@ -138,7 +138,7 @@ mrb_debug_info_append_file(mrb_state *mrb, mrb_irep_debug_info *d, mrb_assert(lines); if (d->flen > 0) { - const char *fn = mrb_sym2name_len(mrb, d->files[d->flen - 1]->filename_sym, NULL); + const char *fn = mrb_sym_name_len(mrb, d->files[d->flen - 1]->filename_sym, NULL); if (strcmp(filename, fn) == 0) return NULL; } diff --git a/src/dump.c b/src/dump.c index f1e167e35..5972c166d 100644 --- a/src/dump.c +++ b/src/dump.c @@ -220,7 +220,7 @@ get_syms_block_size(mrb_state *mrb, mrb_irep *irep) for (sym_no = 0; sym_no < irep->slen; sym_no++) { size += sizeof(uint16_t); /* snl(n) */ if (irep->syms[sym_no] != 0) { - mrb_sym2name_len(mrb, irep->syms[sym_no], &len); + mrb_sym_name_len(mrb, irep->syms[sym_no], &len); size += len + 1; /* sn(n) + null char */ } } @@ -241,7 +241,7 @@ write_syms_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf) if (irep->syms[sym_no] != 0) { mrb_int len; - name = mrb_sym2name_len(mrb, irep->syms[sym_no], &len); + name = mrb_sym_name_len(mrb, irep->syms[sym_no], &len); mrb_assert_int_fit(mrb_int, len, uint16_t, UINT16_MAX); cur += uint16_to_bin((uint16_t)len, cur); /* length of symbol name */ @@ -436,7 +436,7 @@ get_filename_table_size(mrb_state *mrb, mrb_irep *irep, mrb_sym **fp, uint16_t * filenames[*lp - 1] = file->filename_sym; /* filename */ - mrb_sym2name_len(mrb, file->filename_sym, &filename_len); + mrb_sym_name_len(mrb, file->filename_sym, &filename_len); size += sizeof(uint16_t) + (size_t)filename_len; } } @@ -540,7 +540,7 @@ write_section_debug(mrb_state *mrb, mrb_irep *irep, uint8_t *cur, mrb_sym const cur += uint16_to_bin(filenames_len, cur); section_size += sizeof(uint16_t); for (i = 0; i < filenames_len; ++i) { - sym = mrb_sym2name_len(mrb, filenames[i], &sym_len); + sym = mrb_sym_name_len(mrb, filenames[i], &sym_len); mrb_assert(sym); cur += uint16_to_bin((uint16_t)sym_len, cur); memcpy(cur, sym, sym_len); @@ -594,7 +594,7 @@ write_lv_sym_table(mrb_state *mrb, uint8_t **start, mrb_sym const *syms, uint32_ cur += uint32_to_bin(syms_len, cur); for (i = 0; i < syms_len; ++i) { - str = mrb_sym2name_len(mrb, syms[i], &str_len); + str = mrb_sym_name_len(mrb, syms[i], &str_len); cur += uint16_to_bin((uint16_t)str_len, cur); memcpy(cur, str, str_len); cur += str_len; @@ -658,7 +658,7 @@ get_lv_section_size(mrb_state *mrb, mrb_irep *irep, mrb_sym const *syms, uint32_ ret += sizeof(uint16_t) * syms_len; /* symbol name lengths */ for (i = 0; i < syms_len; ++i) { mrb_int str_len; - mrb_sym2name_len(mrb, syms[i], &str_len); + mrb_sym_name_len(mrb, syms[i], &str_len); ret += str_len; } diff --git a/src/string.c b/src/string.c index 48df958ec..f53985ab9 100644 --- a/src/string.c +++ b/src/string.c @@ -1092,7 +1092,7 @@ mrb_str_to_str(mrb_state *mrb, mrb_value str) case MRB_TT_STRING: return str; case MRB_TT_SYMBOL: - return mrb_sym2str(mrb, mrb_symbol(str)); + return mrb_sym_str(mrb, mrb_symbol(str)); case MRB_TT_FIXNUM: return mrb_fixnum_to_str(mrb, str, 10); case MRB_TT_CLASS: diff --git a/src/symbol.c b/src/symbol.c index aad250f09..6ff1e54da 100644 --- a/src/symbol.c +++ b/src/symbol.c @@ -266,7 +266,7 @@ sym2name_len(mrb_state *mrb, mrb_sym sym, char *buf, mrb_int *lenp) } MRB_API const char* -mrb_sym2name_len(mrb_state *mrb, mrb_sym sym, mrb_int *lenp) +mrb_sym_name_len(mrb_state *mrb, mrb_sym sym, mrb_int *lenp) { return sym2name_len(mrb, sym, mrb->symbuf, lenp); } @@ -336,7 +336,7 @@ mrb_init_symtbl(mrb_state *mrb) static mrb_value sym_to_s(mrb_state *mrb, mrb_value sym) { - return mrb_sym2str(mrb, mrb_symbol(sym)); + return mrb_sym_str(mrb, mrb_symbol(sym)); } /* 15.2.11.3.4 */ @@ -491,7 +491,7 @@ sym_inspect(mrb_state *mrb, mrb_value sym) mrb_sym id = mrb_symbol(sym); char *sp; - name = mrb_sym2name_len(mrb, id, &len); + name = mrb_sym_name_len(mrb, id, &len); str = mrb_str_new(mrb, 0, len+1); sp = RSTRING_PTR(str); sp[0] = ':'; @@ -510,10 +510,10 @@ sym_inspect(mrb_state *mrb, mrb_value sym) } MRB_API mrb_value -mrb_sym2str(mrb_state *mrb, mrb_sym sym) +mrb_sym_str(mrb_state *mrb, mrb_sym sym) { mrb_int len; - const char *name = mrb_sym2name_len(mrb, sym, &len); + const char *name = mrb_sym_name_len(mrb, sym, &len); if (!name) return mrb_undef_value(); /* can't happen */ if (SYMBOL_INLINE_P(sym)) { @@ -525,13 +525,13 @@ mrb_sym2str(mrb_state *mrb, mrb_sym sym) } MRB_API const char* -mrb_sym2name(mrb_state *mrb, mrb_sym sym) +mrb_sym_name(mrb_state *mrb, mrb_sym sym) { mrb_int len; - const char *name = mrb_sym2name_len(mrb, sym, &len); + const char *name = mrb_sym_name_len(mrb, sym, &len); if (!name) return NULL; - if (symname_p(name) && strlen(name) == (size_t)len) { + if (strlen(name) == (size_t)len) { return name; } else { diff --git a/src/variable.c b/src/variable.c index 62d6f35a5..d7a07d5be 100644 --- a/src/variable.c +++ b/src/variable.c @@ -378,7 +378,7 @@ assign_class_name(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v) { if (namespace_p(obj->tt) && namespace_p(mrb_type(v))) { struct RObject *c = mrb_obj_ptr(v); - if (obj != c && ISUPPER(mrb_sym2name(mrb, sym)[0])) { + if (obj != c && ISUPPER(mrb_sym_name(mrb, sym)[0])) { mrb_sym id_classname = mrb_intern_lit(mrb, "__classname__"); mrb_value o = mrb_obj_iv_get(mrb, c, id_classname); @@ -435,7 +435,7 @@ mrb_iv_name_sym_p(mrb_state *mrb, mrb_sym iv_name) const char *s; mrb_int len; - s = mrb_sym2name_len(mrb, iv_name, &len); + s = mrb_sym_name_len(mrb, iv_name, &len); if (len < 2) return FALSE; if (s[0] != '@') return FALSE; if (ISDIGIT(s[1])) return FALSE; @@ -483,7 +483,7 @@ inspect_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p) else { mrb_str_cat_lit(mrb, str, ", "); } - s = mrb_sym2name_len(mrb, sym, &len); + s = mrb_sym_name_len(mrb, sym, &len); mrb_str_cat(mrb, str, s, len); mrb_str_cat_lit(mrb, str, "="); if (mrb_type(v) == MRB_TT_OBJECT) { @@ -541,7 +541,7 @@ iv_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p) mrb_int len; ary = *(mrb_value*)p; - s = mrb_sym2name_len(mrb, sym, &len); + s = mrb_sym_name_len(mrb, sym, &len); if (len > 1 && s[0] == '@' && s[1] != '@') { mrb_ary_push(mrb, ary, mrb_symbol_value(sym)); } @@ -585,7 +585,7 @@ cv_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p) mrb_int len; ary = *(mrb_value*)p; - s = mrb_sym2name_len(mrb, sym, &len); + s = mrb_sym_name_len(mrb, sym, &len); if (len > 2 && s[0] == '@' && s[1] == '@') { mrb_ary_push(mrb, ary, mrb_symbol_value(sym)); } @@ -894,7 +894,7 @@ const_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p) mrb_int len; ary = *(mrb_value*)p; - s = mrb_sym2name_len(mrb, sym, &len); + s = mrb_sym_name_len(mrb, sym, &len); if (len >= 1 && ISUPPER(s[0])) { mrb_int i, alen = RARRAY_LEN(ary); @@ -1117,7 +1117,7 @@ mrb_class_find_path(mrb_state *mrb, struct RClass *c) mrb_str_cat_cstr(mrb, path, str); mrb_str_cat_cstr(mrb, path, "::"); - str = mrb_sym2name_len(mrb, name, &len); + str = mrb_sym_name_len(mrb, name, &len); mrb_str_cat(mrb, path, str, len); if (RSTRING_PTR(path)[0] != '#') { iv_del(mrb, c->iv, mrb_intern_lit(mrb, "__outer__"), NULL); diff --git a/src/vm.c b/src/vm.c index ec19d3eec..6d342a381 100644 --- a/src/vm.c +++ b/src/vm.c @@ -2156,7 +2156,7 @@ RETRY_TRY_BLOCK: } pc = ci->pc; ci = mrb->c->ci; - DEBUG(fprintf(stderr, "from :%s\n", mrb_sym2name(mrb, ci->mid))); + DEBUG(fprintf(stderr, "from :%s\n", mrb_sym_name(mrb, ci->mid))); proc = mrb->c->ci->proc; irep = proc->body.irep; pool = irep->pool; -- cgit v1.2.3 From feaf80d8996340bd0316fda72418b1abd774bd59 Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Thu, 26 Sep 2019 22:23:27 +0900 Subject: Use type predicate macros instead of `mrb_type` if possible For efficiency with `MRB_WORD_BOXING` (implement type predicate macros for all `enum mrb_vtype`). --- include/mruby/boxing_word.h | 14 +++++++++ include/mruby/data.h | 2 +- include/mruby/value.h | 57 ++++++++++++++++++++++++++++++----- mrbgems/mruby-array-ext/src/array.c | 2 +- mrbgems/mruby-class-ext/src/class.c | 2 +- mrbgems/mruby-compiler/core/codegen.c | 4 +-- mrbgems/mruby-fiber/src/fiber.c | 2 +- mrbgems/mruby-io/src/io.c | 4 +-- mrbgems/mruby-io/test/mruby_io_test.c | 8 ++--- mrbgems/mruby-kernel-ext/src/kernel.c | 2 +- mrbgems/mruby-method/src/method.c | 4 +-- mrbgems/mruby-random/src/random.c | 2 +- mrbgems/mruby-socket/src/socket.c | 2 +- src/class.c | 12 ++++---- src/etc.c | 4 +-- src/gc.c | 4 +-- src/hash.c | 2 +- src/kernel.c | 6 ++-- src/numeric.c | 2 +- src/object.c | 2 +- src/proc.c | 4 +-- src/range.c | 4 +-- src/state.c | 4 +-- src/string.c | 4 +-- src/symbol.c | 2 +- src/variable.c | 2 +- src/vm.c | 10 +++--- 27 files changed, 112 insertions(+), 55 deletions(-) (limited to 'src/string.c') diff --git a/include/mruby/boxing_word.h b/include/mruby/boxing_word.h index 22d549687..d763ffaf8 100644 --- a/include/mruby/boxing_word.h +++ b/include/mruby/boxing_word.h @@ -133,6 +133,20 @@ MRB_API mrb_value mrb_word_boxing_float_pool(struct mrb_state*, mrb_float); #define mrb_hash_p(o) BOXWORD_OBJ_TYPE_P(o, HASH) #define mrb_cptr_p(o) BOXWORD_OBJ_TYPE_P(o, CPTR) #define mrb_exception_p(o) BOXWORD_OBJ_TYPE_P(o, EXCEPTION) +#define mrb_free_p(o) BOXWORD_OBJ_TYPE_P(o, FREE) +#define mrb_object_p(o) BOXWORD_OBJ_TYPE_P(o, OBJECT) +#define mrb_class_p(o) BOXWORD_OBJ_TYPE_P(o, CLASS) +#define mrb_module_p(o) BOXWORD_OBJ_TYPE_P(o, MODULE) +#define mrb_iclass_p(o) BOXWORD_OBJ_TYPE_P(o, ICLASS) +#define mrb_sclass_p(o) BOXWORD_OBJ_TYPE_P(o, SCLASS) +#define mrb_proc_p(o) BOXWORD_OBJ_TYPE_P(o, PROC) +#define mrb_range_p(o) BOXWORD_OBJ_TYPE_P(o, RANGE) +#define mrb_file_p(o) BOXWORD_OBJ_TYPE_P(o, FILE) +#define mrb_env_p(o) BOXWORD_OBJ_TYPE_P(o, ENV) +#define mrb_data_p(o) BOXWORD_OBJ_TYPE_P(o, DATA) +#define mrb_fiber_p(o) BOXWORD_OBJ_TYPE_P(o, FIBER) +#define mrb_istruct_p(o) BOXWORD_OBJ_TYPE_P(o, ISTRUCT) +#define mrb_break_p(o) BOXWORD_OBJ_TYPE_P(o, BREAK) #ifndef MRB_WITHOUT_FLOAT #define SET_FLOAT_VALUE(mrb,r,v) ((r) = mrb_word_boxing_float_value(mrb, v)) diff --git a/include/mruby/data.h b/include/mruby/data.h index 35ec2c25b..7bdf1c34e 100644 --- a/include/mruby/data.h +++ b/include/mruby/data.h @@ -66,7 +66,7 @@ MRB_API void *mrb_data_check_get_ptr(mrb_state *mrb, mrb_value, const mrb_data_t MRB_INLINE void mrb_data_init(mrb_value v, void *ptr, const mrb_data_type *type) { - mrb_assert(mrb_type(v) == MRB_TT_DATA); + mrb_assert(mrb_data_p(v)); DATA_PTR(v) = ptr; DATA_TYPE(v) = type; } diff --git a/include/mruby/value.h b/include/mruby/value.h index b318e9042..84ea7fb0a 100644 --- a/include/mruby/value.h +++ b/include/mruby/value.h @@ -169,6 +169,11 @@ typedef void mrb_value; #include "boxing_no.h" #endif +#if !defined(MRB_SYMBOL_BITSIZE) +#define MRB_SYMBOL_BITSIZE (sizeof(mrb_sym) * CHAR_BIT) +#define MRB_SYMBOL_MAX UINT32_MAX +#endif + #ifndef mrb_immediate_p #define mrb_immediate_p(o) (mrb_type(o) < MRB_TT_FREE) #endif @@ -190,13 +195,6 @@ typedef void mrb_value; #ifndef mrb_true_p #define mrb_true_p(o) (mrb_type(o) == MRB_TT_TRUE) #endif -#ifndef mrb_bool -#define mrb_bool(o) (mrb_type(o) != MRB_TT_FALSE) -#endif -#if !defined(MRB_SYMBOL_BITSIZE) -#define MRB_SYMBOL_BITSIZE (sizeof(mrb_sym) * CHAR_BIT) -#define MRB_SYMBOL_MAX UINT32_MAX -#endif #ifndef MRB_WITHOUT_FLOAT #ifndef mrb_float_p #define mrb_float_p(o) (mrb_type(o) == MRB_TT_FLOAT) @@ -217,6 +215,51 @@ typedef void mrb_value; #ifndef mrb_exception_p #define mrb_exception_p(o) (mrb_type(o) == MRB_TT_EXCEPTION) #endif +#ifndef mrb_free_p +#define mrb_free_p(o) (mrb_type(o) == MRB_TT_FREE) +#endif +#ifndef mrb_object_p +#define mrb_object_p(o) (mrb_type(o) == MRB_TT_OBJECT) +#endif +#ifndef mrb_class_p +#define mrb_class_p(o) (mrb_type(o) == MRB_TT_CLASS) +#endif +#ifndef mrb_module_p +#define mrb_module_p(o) (mrb_type(o) == MRB_TT_MODULE) +#endif +#ifndef mrb_iclass_p +#define mrb_iclass_p(o) (mrb_type(o) == MRB_TT_ICLASS) +#endif +#ifndef mrb_sclass_p +#define mrb_sclass_p(o) (mrb_type(o) == MRB_TT_SCLASS) +#endif +#ifndef mrb_proc_p +#define mrb_proc_p(o) (mrb_type(o) == MRB_TT_PROC) +#endif +#ifndef mrb_range_p +#define mrb_range_p(o) (mrb_type(o) == MRB_TT_RANGE) +#endif +#ifndef mrb_file_p +#define mrb_file_p(o) (mrb_type(o) == MRB_TT_FILE) +#endif +#ifndef mrb_env_p +#define mrb_env_p(o) (mrb_type(o) == MRB_TT_ENV) +#endif +#ifndef mrb_data_p +#define mrb_data_p(o) (mrb_type(o) == MRB_TT_DATA) +#endif +#ifndef mrb_fiber_p +#define mrb_fiber_p(o) (mrb_type(o) == MRB_TT_FIBER) +#endif +#ifndef mrb_istruct_p +#define mrb_istruct_p(o) (mrb_type(o) == MRB_TT_ISTRUCT) +#endif +#ifndef mrb_break_p +#define mrb_break_p(o) (mrb_type(o) == MRB_TT_BREAK) +#endif +#ifndef mrb_bool +#define mrb_bool(o) (mrb_type(o) != MRB_TT_FALSE) +#endif #define mrb_test(o) mrb_bool(o) /** diff --git a/mrbgems/mruby-array-ext/src/array.c b/mrbgems/mruby-array-ext/src/array.c index cb4798d49..ab6d99133 100644 --- a/mrbgems/mruby-array-ext/src/array.c +++ b/mrbgems/mruby-array-ext/src/array.c @@ -65,7 +65,7 @@ mrb_ary_rassoc(mrb_state *mrb, mrb_value ary) for (i = 0; i < RARRAY_LEN(ary); ++i) { v = RARRAY_PTR(ary)[i]; - if (mrb_type(v) == MRB_TT_ARRAY && + if (mrb_array_p(v) && RARRAY_LEN(v) > 1 && mrb_equal(mrb, RARRAY_PTR(v)[1], value)) return v; diff --git a/mrbgems/mruby-class-ext/src/class.c b/mrbgems/mruby-class-ext/src/class.c index 255e62f6b..0d27c30ed 100644 --- a/mrbgems/mruby-class-ext/src/class.c +++ b/mrbgems/mruby-class-ext/src/class.c @@ -11,7 +11,7 @@ mrb_mod_name(mrb_state *mrb, mrb_value self) static mrb_value mrb_mod_singleton_class_p(mrb_state *mrb, mrb_value self) { - return mrb_bool_value(mrb_type(self) == MRB_TT_SCLASS); + return mrb_bool_value(mrb_sclass_p(self)); } /* diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index 1989c0cf1..0af76bd17 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -559,7 +559,7 @@ new_lit(codegen_scope *s, mrb_value val) mrb_int len; pv = &s->irep->pool[i]; - if (mrb_type(*pv) != MRB_TT_STRING) continue; + if (!mrb_string_p(*pv)) continue; if ((len = RSTRING_LEN(*pv)) != RSTRING_LEN(val)) continue; if (memcmp(RSTRING_PTR(*pv), RSTRING_PTR(val), len) == 0) return i; @@ -570,7 +570,7 @@ new_lit(codegen_scope *s, mrb_value val) for (i=0; iirep->plen; i++) { mrb_float f1, f2; pv = &s->irep->pool[i]; - if (mrb_type(*pv) != MRB_TT_FLOAT) continue; + if (!mrb_float_p(*pv)) continue; f1 = mrb_float(*pv); f2 = mrb_float(val); if (f1 == f2 && !signbit(f1) == !signbit(f2)) return i; diff --git a/mrbgems/mruby-fiber/src/fiber.c b/mrbgems/mruby-fiber/src/fiber.c index e47849dda..e22985bd3 100644 --- a/mrbgems/mruby-fiber/src/fiber.c +++ b/mrbgems/mruby-fiber/src/fiber.c @@ -294,7 +294,7 @@ fiber_eq(mrb_state *mrb, mrb_value self) mrb_value other; mrb_get_args(mrb, "o", &other); - if (mrb_type(other) != MRB_TT_FIBER) { + if (!mrb_fiber_p(other)) { return mrb_false_value(); } return mrb_bool_value(fiber_ptr(self) == fiber_ptr(other)); diff --git a/mrbgems/mruby-io/src/io.c b/mrbgems/mruby-io/src/io.c index 8228097cb..624c27f47 100644 --- a/mrbgems/mruby-io/src/io.c +++ b/mrbgems/mruby-io/src/io.c @@ -907,7 +907,7 @@ mrb_io_syswrite(mrb_state *mrb, mrb_value io) } mrb_get_args(mrb, "S", &str); - if (mrb_type(str) != MRB_TT_STRING) { + if (!mrb_string_p(str)) { buf = mrb_funcall(mrb, str, "to_s", 0); } else { buf = str; @@ -1000,7 +1000,7 @@ static int mrb_io_read_data_pending(mrb_state *mrb, mrb_value io) { mrb_value buf = mrb_iv_get(mrb, io, mrb_intern_cstr(mrb, "@buf")); - if (mrb_type(buf) == MRB_TT_STRING && RSTRING_LEN(buf) > 0) { + if (mrb_string_p(buf) && RSTRING_LEN(buf) > 0) { return 1; } return 0; diff --git a/mrbgems/mruby-io/test/mruby_io_test.c b/mrbgems/mruby-io/test/mruby_io_test.c index 2c8a75fc9..eb552c41a 100644 --- a/mrbgems/mruby-io/test/mruby_io_test.c +++ b/mrbgems/mruby-io/test/mruby_io_test.c @@ -154,16 +154,16 @@ mrb_io_test_io_cleanup(mrb_state *mrb, mrb_value self) mrb_value symlinkname = mrb_gv_get(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_symlinkname")); mrb_value socketname = mrb_gv_get(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_socketname")); - if (mrb_type(rfname) == MRB_TT_STRING) { + if (mrb_string_p(rfname)) { remove(RSTRING_PTR(rfname)); } - if (mrb_type(wfname) == MRB_TT_STRING) { + if (mrb_string_p(wfname)) { remove(RSTRING_PTR(wfname)); } - if (mrb_type(symlinkname) == MRB_TT_STRING) { + if (mrb_string_p(symlinkname)) { remove(RSTRING_PTR(symlinkname)); } - if (mrb_type(socketname) == MRB_TT_STRING) { + if (mrb_string_p(socketname)) { remove(RSTRING_PTR(socketname)); } diff --git a/mrbgems/mruby-kernel-ext/src/kernel.c b/mrbgems/mruby-kernel-ext/src/kernel.c index 376751e10..a2af6b46f 100644 --- a/mrbgems/mruby-kernel-ext/src/kernel.c +++ b/mrbgems/mruby-kernel-ext/src/kernel.c @@ -20,7 +20,7 @@ mrb_f_caller(mrb_state *mrb, mrb_value self) n = bt_len - lev; break; case 1: - if (mrb_type(v) == MRB_TT_RANGE) { + if (mrb_range_p(v)) { mrb_int beg, len; if (mrb_range_beg_len(mrb, v, &beg, &len, bt_len, TRUE) == MRB_RANGE_OK) { lev = beg; diff --git a/mrbgems/mruby-method/src/method.c b/mrbgems/mruby-method/src/method.c index d95ca1664..1557e60ca 100644 --- a/mrbgems/mruby-method/src/method.c +++ b/mrbgems/mruby-method/src/method.c @@ -14,10 +14,10 @@ method_object_alloc(mrb_state *mrb, struct RClass *mclass) static void bind_check(mrb_state *mrb, mrb_value recv, mrb_value owner) { - if (mrb_type(owner) != MRB_TT_MODULE && + if (!mrb_module_p(owner) && mrb_class_ptr(owner) != mrb_obj_class(mrb, recv) && !mrb_obj_is_kind_of(mrb, recv, mrb_class_ptr(owner))) { - if (mrb_type(owner) == MRB_TT_SCLASS) { + if (mrb_sclass_p(owner)) { mrb_raise(mrb, E_TYPE_ERROR, "singleton method called for a different object"); } else { mrb_raisef(mrb, E_TYPE_ERROR, "bind argument must be an instance of %v", owner); diff --git a/mrbgems/mruby-random/src/random.c b/mrbgems/mruby-random/src/random.c index af9876ce7..515c0707a 100644 --- a/mrbgems/mruby-random/src/random.c +++ b/mrbgems/mruby-random/src/random.c @@ -136,7 +136,7 @@ get_opt(mrb_state* mrb) static void random_check(mrb_state *mrb, mrb_value random) { struct RClass *c = mrb_class_get(mrb, "Random"); - if (!mrb_obj_is_kind_of(mrb, random, c) || mrb_type(random) != MRB_TT_ISTRUCT) { + if (!mrb_obj_is_kind_of(mrb, random, c) || !mrb_istruct_p(random)) { mrb_raise(mrb, E_TYPE_ERROR, "Random instance required"); } } diff --git a/mrbgems/mruby-socket/src/socket.c b/mrbgems/mruby-socket/src/socket.c index 53f761617..53cd9f4aa 100644 --- a/mrbgems/mruby-socket/src/socket.c +++ b/mrbgems/mruby-socket/src/socket.c @@ -455,7 +455,7 @@ mrb_basicsocket_setsockopt(mrb_state *mrb, mrb_value self) level = mrb_fixnum(so); if (mrb_string_p(optval)) { /* that's good */ - } else if (mrb_type(optval) == MRB_TT_TRUE || mrb_type(optval) == MRB_TT_FALSE) { + } else if (mrb_true_p(optval) || mrb_false_p(optval)) { mrb_int i = mrb_test(optval) ? 1 : 0; optval = mrb_str_new(mrb, (char*)&i, sizeof(i)); } else if (mrb_fixnum_p(optval)) { diff --git a/src/class.c b/src/class.c index adb8954cc..745e0a72c 100644 --- a/src/class.c +++ b/src/class.c @@ -215,7 +215,7 @@ mrb_vm_define_module(mrb_state *mrb, mrb_value outer, mrb_sym id) if (mrb_const_defined_at(mrb, outer, id)) { mrb_value old = mrb_const_get(mrb, outer, id); - if (mrb_type(old) != MRB_TT_MODULE) { + if (!mrb_module_p(old)) { mrb_raisef(mrb, E_TYPE_ERROR, "%!v is not a module", old); } return mrb_class_ptr(old); @@ -312,7 +312,7 @@ mrb_vm_define_class(mrb_state *mrb, mrb_value outer, mrb_value super, mrb_sym id struct RClass *c; if (!mrb_nil_p(super)) { - if (mrb_type(super) != MRB_TT_CLASS) { + if (!mrb_class_p(super)) { mrb_raisef(mrb, E_TYPE_ERROR, "superclass must be a Class (%!v given)", super); } s = mrb_class_ptr(super); @@ -324,7 +324,7 @@ mrb_vm_define_class(mrb_state *mrb, mrb_value outer, mrb_value super, mrb_sym id if (mrb_const_defined_at(mrb, outer, id)) { mrb_value old = mrb_const_get(mrb, outer, id); - if (mrb_type(old) != MRB_TT_CLASS) { + if (!mrb_class_p(old)) { mrb_raisef(mrb, E_TYPE_ERROR, "%!v is not a class", old); } c = mrb_class_ptr(old); @@ -381,7 +381,7 @@ mrb_exc_get(mrb_state *mrb, const char *name) mrb_value c = mrb_const_get(mrb, mrb_obj_value(mrb->object_class), mrb_intern_cstr(mrb, name)); - if (mrb_type(c) != MRB_TT_CLASS) { + if (!mrb_class_p(c)) { mrb_raise(mrb, mrb->eException_class, "exception corrupted"); } exc = e = mrb_class_ptr(c); @@ -791,7 +791,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) p = va_arg(ap, void**); if (i < argc) { ss = argv[arg_i]; - if (mrb_type(ss) != MRB_TT_ISTRUCT) + if (!mrb_istruct_p(ss)) { mrb_raisef(mrb, E_TYPE_ERROR, "%v is not inline struct", ss); } @@ -1789,7 +1789,7 @@ mrb_value mrb_mod_to_s(mrb_state *mrb, mrb_value klass) { - if (mrb_type(klass) == MRB_TT_SCLASS) { + if (mrb_sclass_p(klass)) { mrb_value v = mrb_iv_get(mrb, klass, mrb_intern_lit(mrb, "__attached__")); mrb_value str = mrb_str_new_lit(mrb, "#range_class)) return mrb_false_value(); - if (mrb_type(obj) != MRB_TT_RANGE) return mrb_false_value(); + if (!mrb_range_p(obj)) return mrb_false_value(); r = mrb_range_ptr(mrb, range); o = mrb_range_ptr(mrb, obj); @@ -391,7 +391,7 @@ mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int beg, end; struct RRange *r; - if (mrb_type(range) != MRB_TT_RANGE) return MRB_RANGE_TYPE_MISMATCH; + if (!mrb_range_p(range)) return MRB_RANGE_TYPE_MISMATCH; r = mrb_range_ptr(mrb, range); beg = mrb_int(mrb, RANGE_BEG(r)); diff --git a/src/state.c b/src/state.c index 99b523dd5..3e5ebb483 100644 --- a/src/state.c +++ b/src/state.c @@ -119,12 +119,12 @@ mrb_irep_free(mrb_state *mrb, mrb_irep *irep) if (!(irep->flags & MRB_ISEQ_NO_FREE)) mrb_free(mrb, (void*)irep->iseq); if (irep->pool) for (i=0; iplen; i++) { - if (mrb_type(irep->pool[i]) == MRB_TT_STRING) { + if (mrb_string_p(irep->pool[i])) { mrb_gc_free_str(mrb, RSTRING(irep->pool[i])); mrb_free(mrb, mrb_obj_ptr(irep->pool[i])); } #if defined(MRB_WORD_BOXING) && !defined(MRB_WITHOUT_FLOAT) - else if (mrb_type(irep->pool[i]) == MRB_TT_FLOAT) { + else if (mrb_float_p(irep->pool[i])) { mrb_free(mrb, mrb_obj_ptr(irep->pool[i])); } #endif diff --git a/src/string.c b/src/string.c index f53985ab9..b49fdfc2e 100644 --- a/src/string.c +++ b/src/string.c @@ -1688,7 +1688,7 @@ mrb_str_eql(mrb_state *mrb, mrb_value self) mrb_bool eql_p; mrb_get_args(mrb, "o", &str2); - eql_p = (mrb_type(str2) == MRB_TT_STRING) && str_eql(mrb, self, str2); + eql_p = (mrb_string_p(str2)) && str_eql(mrb, self, str2); return mrb_bool_value(eql_p); } @@ -2977,7 +2977,7 @@ mrb_str_byteslice(mrb_state *mrb, mrb_value str) beg = mrb_fixnum(mrb_to_int(mrb, a1)); len = mrb_fixnum(mrb_to_int(mrb, a2)); } - else if (mrb_type(a1) == MRB_TT_RANGE) { + else if (mrb_range_p(a1)) { if (mrb_range_beg_len(mrb, a1, &beg, &len, str_len, TRUE) != MRB_RANGE_OK) { return mrb_nil_value(); } diff --git a/src/symbol.c b/src/symbol.c index 6ff1e54da..90cb49fd8 100644 --- a/src/symbol.c +++ b/src/symbol.c @@ -551,7 +551,7 @@ sym_cmp(mrb_state *mrb, mrb_value s1) mrb_sym sym1, sym2; mrb_get_args(mrb, "o", &s2); - if (mrb_type(s2) != MRB_TT_SYMBOL) return mrb_nil_value(); + if (!mrb_symbol_p(s2)) return mrb_nil_value(); sym1 = mrb_symbol(s1); sym2 = mrb_symbol(s2); if (sym1 == sym2) return mrb_fixnum_value(0); diff --git a/src/variable.c b/src/variable.c index d7a07d5be..7d4470186 100644 --- a/src/variable.c +++ b/src/variable.c @@ -486,7 +486,7 @@ inspect_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p) s = mrb_sym_name_len(mrb, sym, &len); mrb_str_cat(mrb, str, s, len); mrb_str_cat_lit(mrb, str, "="); - if (mrb_type(v) == MRB_TT_OBJECT) { + if (mrb_object_p(v)) { ins = mrb_any_to_s(mrb, v); } else { diff --git a/src/vm.c b/src/vm.c index 6d342a381..54f74907e 100644 --- a/src/vm.c +++ b/src/vm.c @@ -816,7 +816,7 @@ mrb_yield_cont(mrb_state *mrb, mrb_value b, mrb_value self, mrb_int argc, const if (mrb_nil_p(b)) { mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given"); } - if (mrb_type(b) != MRB_TT_PROC) { + if (!mrb_proc_p(b)) { mrb_raise(mrb, E_TYPE_ERROR, "not a block"); } @@ -1387,7 +1387,7 @@ RETRY_TRY_BLOCK: recv = regs[a]; blk = regs[bidx]; - if (!mrb_nil_p(blk) && mrb_type(blk) != MRB_TT_PROC) { + if (!mrb_nil_p(blk) && !mrb_proc_p(blk)) { blk = mrb_convert_type(mrb, blk, MRB_TT_PROC, "Proc", "to_proc"); /* The stack might have been reallocated during mrb_convert_type(), see #3622 */ @@ -1447,7 +1447,7 @@ RETRY_TRY_BLOCK: mrb_gc_arena_shrink(mrb, ai); if (mrb->exc) goto L_RAISE; ci = mrb->c->ci; - if (mrb_type(blk) == MRB_TT_PROC) { + if (mrb_proc_p(blk)) { struct RProc *p = mrb_proc_ptr(blk); if (p && !MRB_PROC_STRICT_P(p) && MRB_PROC_ENV(p) == ci[-1].env) { p->flags |= MRB_PROC_ORPHAN; @@ -1588,7 +1588,7 @@ RETRY_TRY_BLOCK: goto L_RAISE; } blk = regs[bidx]; - if (!mrb_nil_p(blk) && mrb_type(blk) != MRB_TT_PROC) { + if (!mrb_nil_p(blk) && !mrb_proc_p(blk)) { blk = mrb_convert_type(mrb, blk, MRB_TT_PROC, "Proc", "to_proc"); /* The stack or ci stack might have been reallocated during mrb_convert_type(), see #3622 and #3784 */ @@ -1939,7 +1939,7 @@ RETRY_TRY_BLOCK: else { blk = regs[ci->argc+1]; } - if (mrb_type(blk) == MRB_TT_PROC) { + if (mrb_proc_p(blk)) { struct RProc *p = mrb_proc_ptr(blk); if (!MRB_PROC_STRICT_P(p) && -- cgit v1.2.3 From 198683e914ebaceba7b989c6592f871ac8fe5aa0 Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Fri, 27 Sep 2019 17:13:57 +0900 Subject: Simplify arguments check in `String#rindex` Also fix document about type of the first argument. --- src/string.c | 67 ++++++++++++++++++-------------------------------------- test/t/string.rb | 8 +++++++ 2 files changed, 29 insertions(+), 46 deletions(-) (limited to 'src/string.c') diff --git a/src/string.c b/src/string.c index b49fdfc2e..1428ea780 100644 --- a/src/string.c +++ b/src/string.c @@ -1977,21 +1977,17 @@ mrb_str_reverse(mrb_state *mrb, mrb_value str) /* 15.2.10.5.31 */ /* * call-seq: - * str.rindex(substring [, fixnum]) => fixnum or nil - * str.rindex(fixnum [, fixnum]) => fixnum or nil - * str.rindex(regexp [, fixnum]) => fixnum or nil + * str.rindex(substring [, offset]) => fixnum or nil * - * Returns the index of the last occurrence of the given substring, - * character (fixnum), or pattern (regexp) in str. Returns - * nil if not found. If the second parameter is present, it - * specifies the position in the string to end the search---characters beyond - * this point will not be considered. + * Returns the index of the last occurrence of the given substring. + * Returns nil if not found. If the second parameter is + * present, it specifies the position in the string to end the + * search---characters beyond this point will not be considered. * * "hello".rindex('e') #=> 1 * "hello".rindex('l') #=> 3 * "hello".rindex('a') #=> nil - * "hello".rindex(101) #=> 1 - * "hello".rindex(/[aeiou]/, -2) #=> 1 + * "hello".rindex('l', 2) #=> 2 */ static mrb_value mrb_str_rindex(mrb_state *mrb, mrb_value str) @@ -1999,46 +1995,25 @@ mrb_str_rindex(mrb_state *mrb, mrb_value str) mrb_value sub; mrb_int pos, len = RSTRING_CHAR_LEN(str); - switch (mrb_get_args(mrb, "|oi", &sub, &pos)) { - case 0: - sub = mrb_nil_value(); - /* fall through */ - case 1: - pos = len; - break; - case 2: + if (mrb_get_args(mrb, "S|i", &sub, &pos) == 1) { + pos = len; + } + else { + if (pos < 0) { + pos += len; if (pos < 0) { - pos += len; - if (pos < 0) { - return mrb_nil_value(); - } + return mrb_nil_value(); } - if (pos > len) pos = len; - break; + } + if (pos > len) pos = len; } pos = chars2bytes(str, 0, pos); - - switch (mrb_type(sub)) { - default: { - mrb_value tmp; - - tmp = mrb_check_string_type(mrb, sub); - if (mrb_nil_p(tmp)) { - mrb_raisef(mrb, E_TYPE_ERROR, "type mismatch: %v given", sub); - } - sub = tmp; - } - /* fall through */ - case MRB_TT_STRING: - pos = str_rindex(mrb, str, sub, pos); - if (pos >= 0) { - pos = bytes2chars(RSTRING_PTR(str), RSTRING_LEN(str), pos); - BYTES_ALIGN_CHECK(pos); - return mrb_fixnum_value(pos); - } - break; - - } /* end of switch (TYPE(sub)) */ + pos = str_rindex(mrb, str, sub, pos); + if (pos >= 0) { + pos = bytes2chars(RSTRING_PTR(str), RSTRING_LEN(str), pos); + BYTES_ALIGN_CHECK(pos); + return mrb_fixnum_value(pos); + } return mrb_nil_value(); } diff --git a/test/t/string.rb b/test/t/string.rb index 01f3da327..e1ff48312 100644 --- a/test/t/string.rb +++ b/test/t/string.rb @@ -554,9 +554,16 @@ end if UTF8STRING assert('String#rindex', '15.2.10.5.31') do assert_equal 0, 'abc'.rindex('a') + assert_equal 0, 'abc'.rindex('a', 3) + assert_nil 'abc'.rindex('a', -4) assert_nil 'abc'.rindex('d') + assert_equal 6, 'abcabc'.rindex('') + assert_equal 3, 'abcabc'.rindex('a') assert_equal 0, 'abcabc'.rindex('a', 1) assert_equal 3, 'abcabc'.rindex('a', 4) + assert_equal 0, 'abcabc'.rindex('a', -4) + assert_raise(ArgumentError) { "hello".rindex } + assert_raise(TypeError) { "hello".rindex(101) } end assert('String#rindex(UTF-8)', '15.2.10.5.31') do @@ -564,6 +571,7 @@ assert('String#rindex(UTF-8)', '15.2.10.5.31') do assert_nil str.rindex('さ') assert_equal 12, str.rindex('ち') assert_equal 3, str.rindex('ち', 10) + assert_equal 3, str.rindex('ち', -6) broken = "\xf0☀\xf1☁\xf2☂\xf3☃\xf0☀\xf1☁\xf2☂\xf3☃" assert_nil broken.rindex("\x81") # "\x81" is a part of "☁" ("\xe2\x98\x81") -- cgit v1.2.3 From 1f5a7f2f4970144164232a2bc45f561de5d65c33 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Fri, 4 Oct 2019 16:02:50 +0900 Subject: Freeze strings from `nil.to_s`, `true.to_s`, `false.to_s`. This is an experimental changes in Ruby 2.7. --- include/mruby.h | 6 ++++++ src/kernel.c | 2 +- src/object.c | 8 ++++---- src/string.c | 7 +++++++ 4 files changed, 18 insertions(+), 5 deletions(-) (limited to 'src/string.c') diff --git a/include/mruby.h b/include/mruby.h index 04b21bc35..5d12cf84e 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -1022,6 +1022,12 @@ MRB_API mrb_value mrb_str_new_cstr(mrb_state*, const char*); MRB_API mrb_value mrb_str_new_static(mrb_state *mrb, const char *p, size_t len); #define mrb_str_new_lit(mrb, lit) mrb_str_new_static(mrb, (lit), mrb_strlen_lit(lit)) +MRB_API mrb_value mrb_obj_freeze(mrb_state*, mrb_value); +#define mrb_str_new_frozen(mrb,p,len) mrb_obj_freeze(mrb,mrb_str_new(mrb,p,len)) +#define mrb_str_new_cstr_frozen(mrb,p) mrb_obj_freeze(mrb,mrb_str_new_cstr(mrb,p)) +#define mrb_str_new_static_frozen(mrb,p,len) mrb_obj_freeze(mrb,mrb_str_new_static(mrb,p,len)) +#define mrb_str_new_lit_frozen(mrb,lit) mrb_obj_freeze(mrb,mrb_str_new_lit(mrb,lit)) + #ifdef _WIN32 MRB_API char* mrb_utf8_from_locale(const char *p, int len); MRB_API char* mrb_locale_from_utf8(const char *p, int len); diff --git a/src/kernel.c b/src/kernel.c index 4287b6cf2..c88a457f0 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -431,7 +431,7 @@ mrb_obj_extend_m(mrb_state *mrb, mrb_value self) return mrb_obj_extend(mrb, argc, argv, self); } -static mrb_value +MRB_API mrb_value mrb_obj_freeze(mrb_state *mrb, mrb_value self) { if (!mrb_immediate_p(self)) { diff --git a/src/object.c b/src/object.c index 0b83c97a3..4e2ba7154 100644 --- a/src/object.c +++ b/src/object.c @@ -83,13 +83,13 @@ mrb_true(mrb_state *mrb, mrb_value obj) static mrb_value nil_to_s(mrb_state *mrb, mrb_value obj) { - return mrb_str_new(mrb, 0, 0); + return mrb_str_new_frozen(mrb, 0, 0); } static mrb_value nil_inspect(mrb_state *mrb, mrb_value obj) { - return mrb_str_new_lit(mrb, "nil"); + return mrb_str_new_lit_frozen(mrb, "nil"); } /*********************************************************************** @@ -150,7 +150,7 @@ true_xor(mrb_state *mrb, mrb_value obj) static mrb_value true_to_s(mrb_state *mrb, mrb_value obj) { - return mrb_str_new_lit(mrb, "true"); + return mrb_str_new_lit_frozen(mrb, "true"); } /* 15.2.5.3.4 */ @@ -257,7 +257,7 @@ false_or(mrb_state *mrb, mrb_value obj) static mrb_value false_to_s(mrb_state *mrb, mrb_value obj) { - return mrb_str_new_lit(mrb, "false"); + return mrb_str_new_lit_frozen(mrb, "false"); } void diff --git a/src/string.c b/src/string.c index 1428ea780..328366e10 100644 --- a/src/string.c +++ b/src/string.c @@ -235,6 +235,13 @@ mrb_str_new_static(mrb_state *mrb, const char *p, size_t len) return mrb_obj_value(s); } +MRB_API mrb_value +mrb_str_freeze(mrb_state *mrb, const char *p, size_t len) +{ + struct RString *s = str_new_static(mrb, p, len); + return mrb_obj_value(s); +} + static void str_decref(mrb_state *mrb, mrb_shared_string *shared) { -- cgit v1.2.3 From b7a8d538c1f079c51ede221d60179877bed18642 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sat, 5 Oct 2019 20:56:05 +0900 Subject: Remove unnecessary function: `mrb_str_freeze`. --- src/string.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'src/string.c') diff --git a/src/string.c b/src/string.c index 328366e10..1428ea780 100644 --- a/src/string.c +++ b/src/string.c @@ -235,13 +235,6 @@ mrb_str_new_static(mrb_state *mrb, const char *p, size_t len) return mrb_obj_value(s); } -MRB_API mrb_value -mrb_str_freeze(mrb_state *mrb, const char *p, size_t len) -{ - struct RString *s = str_new_static(mrb, p, len); - return mrb_obj_value(s); -} - static void str_decref(mrb_state *mrb, mrb_shared_string *shared) { -- cgit v1.2.3 From 7ce5d3394706723a82d337641f960c58649e0134 Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Thu, 10 Oct 2019 19:50:48 +0900 Subject: Integrate `mrb_str_inspect` and `mrb_str_dump` --- mrbgems/mruby-string-ext/test/string.rb | 1 + src/string.c | 261 ++++++++++---------------------- test/t/string.rb | 12 +- 3 files changed, 90 insertions(+), 184 deletions(-) (limited to 'src/string.c') diff --git a/mrbgems/mruby-string-ext/test/string.rb b/mrbgems/mruby-string-ext/test/string.rb index 6914fe31d..3f11c00a0 100644 --- a/mrbgems/mruby-string-ext/test/string.rb +++ b/mrbgems/mruby-string-ext/test/string.rb @@ -13,6 +13,7 @@ end assert('String#dump') do assert_equal("\"\\x00\"", "\0".dump) assert_equal("\"foo\"", "foo".dump) + assert_equal('"\xe3\x82\x8b"', "る".dump) assert_nothing_raised { ("\1" * 100).dump } # regress #1210 end diff --git a/src/string.c b/src/string.c index 1428ea780..a45dee11e 100644 --- a/src/string.c +++ b/src/string.c @@ -1318,6 +1318,84 @@ str_replace_partial(mrb_state *mrb, mrb_value src, mrb_int pos, mrb_int end, mrb return src; } +#define CHAR_ESC_LEN 13 /* sizeof(\x{ hex of 32bit unsigned int } \0) */ +#define IS_EVSTR(p,e) ((p) < (e) && (*(p) == '$' || *(p) == '@' || *(p) == '{')) + +static mrb_value +str_escape(mrb_state *mrb, mrb_value str, mrb_bool inspect) +{ + const char *p, *pend; + char buf[CHAR_ESC_LEN + 1]; + mrb_value result = mrb_str_new_lit(mrb, "\""); +#ifdef MRB_UTF8_STRING + uint32_t ascii_flag = MRB_STR_ASCII; +#endif + + p = RSTRING_PTR(str); pend = RSTRING_END(str); + for (;p < pend; p++) { + unsigned char c, cc; +#ifdef MRB_UTF8_STRING + if (inspect) { + mrb_int clen = utf8len(p, pend); + if (clen > 1) { + mrb_int i; + + for (i=0; iflags |= ascii_flag; + mrb_str_ptr(result)->flags |= ascii_flag; +#endif + + return result; +} + static void mrb_str_aset(mrb_state *mrb, mrb_value str, mrb_value indx, mrb_value alen, mrb_value replace) { @@ -2574,8 +2652,6 @@ mrb_str_upcase(mrb_state *mrb, mrb_value self) return str; } -#define IS_EVSTR(p,e) ((p) < (e) && (*(p) == '$' || *(p) == '@' || *(p) == '{')) - /* * call-seq: * str.dump -> new_str @@ -2586,113 +2662,7 @@ mrb_str_upcase(mrb_state *mrb, mrb_value self) mrb_value mrb_str_dump(mrb_state *mrb, mrb_value str) { - mrb_int len; - const char *p, *pend; - char *q; - struct RString *result; - - len = 2; /* "" */ - p = RSTRING_PTR(str); pend = p + RSTRING_LEN(str); - while (p < pend) { - unsigned char c = *p++; - switch (c) { - case '"': case '\\': - case '\n': case '\r': - case '\t': case '\f': - case '\013': case '\010': case '\007': case '\033': - len += 2; - break; - - case '#': - len += IS_EVSTR(p, pend) ? 2 : 1; - break; - - default: - if (ISPRINT(c)) { - len++; - } - else { - len += 4; /* \NNN */ - } - break; - } - } - - result = str_new(mrb, 0, len); - str_with_class(result, str); - p = RSTRING_PTR(str); pend = p + RSTRING_LEN(str); - q = RSTR_PTR(result); - *q++ = '"'; - while (p < pend) { - unsigned char c = *p++; - - switch (c) { - case '"': - case '\\': - *q++ = '\\'; - *q++ = c; - break; - - case '\n': - *q++ = '\\'; - *q++ = 'n'; - break; - - case '\r': - *q++ = '\\'; - *q++ = 'r'; - break; - - case '\t': - *q++ = '\\'; - *q++ = 't'; - break; - - case '\f': - *q++ = '\\'; - *q++ = 'f'; - break; - - case '\013': - *q++ = '\\'; - *q++ = 'v'; - break; - - case '\010': - *q++ = '\\'; - *q++ = 'b'; - break; - - case '\007': - *q++ = '\\'; - *q++ = 'a'; - break; - - case '\033': - *q++ = '\\'; - *q++ = 'e'; - break; - - case '#': - if (IS_EVSTR(p, pend)) *q++ = '\\'; - *q++ = '#'; - break; - - default: - if (ISPRINT(c)) { - *q++ = c; - } - else { - *q++ = '\\'; - *q++ = 'x'; - q[1] = mrb_digitmap[c % 16]; c /= 16; - q[0] = mrb_digitmap[c % 16]; - q += 2; - } - } - } - *q = '"'; - return mrb_obj_value(result); + return str_escape(mrb, str, FALSE); } MRB_API mrb_value @@ -2762,8 +2732,6 @@ mrb_str_append(mrb_state *mrb, mrb_value str1, mrb_value str2) return mrb_str_cat_str(mrb, str1, str2); } -#define CHAR_ESC_LEN 13 /* sizeof(\x{ hex of 32bit unsigned int } \0) */ - /* * call-seq: * str.inspect -> string @@ -2778,76 +2746,7 @@ mrb_str_append(mrb_state *mrb, mrb_value str1, mrb_value str2) mrb_value mrb_str_inspect(mrb_state *mrb, mrb_value str) { - const char *p, *pend; - char buf[CHAR_ESC_LEN + 1]; - mrb_value result = mrb_str_new_lit(mrb, "\""); -#ifdef MRB_UTF8_STRING - uint32_t ascii_flag = MRB_STR_ASCII; -#endif - - p = RSTRING_PTR(str); pend = RSTRING_END(str); - for (;p < pend; p++) { - unsigned char c, cc; -#ifdef MRB_UTF8_STRING - mrb_int clen; - - clen = utf8len(p, pend); - if (clen > 1) { - mrb_int i; - - for (i=0; iflags |= ascii_flag; - mrb_str_ptr(result)->flags |= ascii_flag; -#endif - - return result; + return str_escape(mrb, str, TRUE); } /* diff --git a/test/t/string.rb b/test/t/string.rb index e1ff48312..65ad13103 100644 --- a/test/t/string.rb +++ b/test/t/string.rb @@ -748,12 +748,18 @@ assert('String#upcase!', '15.2.10.5.43') do end assert('String#inspect', '15.2.10.5.46') do + assert_equal "\"\\x00\"", "\0".inspect + assert_equal "\"foo\"", "foo".inspect + if UTF8STRING + assert_equal '"る"', "る".inspect + else + assert_equal '"\xe3\x82\x8b"', "る".inspect + end + # should not raise an exception - regress #1210 assert_nothing_raised do - ("\1" * 100).inspect + ("\1" * 100).inspect end - - assert_equal "\"\\x00\"", "\0".inspect end # Not ISO specified -- cgit v1.2.3 From cdd36c979d961c5e7249cd9ae668d80832e5e528 Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Sat, 12 Oct 2019 12:49:51 +0900 Subject: Rename `str_make_shared()` to `str_share()` in `src/string.c` Because it may not create `struct mrb_shared_string`. --- src/string.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/string.c') diff --git a/src/string.c b/src/string.c index a45dee11e..d1b177485 100644 --- a/src/string.c +++ b/src/string.c @@ -521,7 +521,7 @@ mrb_memsearch(const void *x0, mrb_int m, const void *y0, mrb_int n) } static void -str_make_shared(mrb_state *mrb, struct RString *orig, struct RString *s) +str_share(mrb_state *mrb, struct RString *orig, struct RString *s) { size_t len = (size_t)orig->as.heap.len; @@ -585,7 +585,7 @@ mrb_str_byte_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len) str_init_embed(s, RSTR_PTR(orig)+beg, len); } else { - str_make_shared(mrb, orig, s); + str_share(mrb, orig, s); s->as.heap.ptr += beg; s->as.heap.len = len; } @@ -691,7 +691,7 @@ str_replace(mrb_state *mrb, struct RString *s1, struct RString *s2) str_init_embed(s1, RSTR_PTR(s2), len); } else { - str_make_shared(mrb, s2, s1); + str_share(mrb, s2, s1); } return mrb_obj_value(s1); -- cgit v1.2.3 From 7594983671da2871036af5e6437e106b159d04de Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Sat, 12 Oct 2019 21:32:56 +0900 Subject: SHARED string is not required when sharing POOL string The heap string buffer of POOL string always exists, does not need to be released, and read only, so it can be shared as NOFREE string. --- src/string.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/string.c') diff --git a/src/string.c b/src/string.c index a45dee11e..41aa4b779 100644 --- a/src/string.c +++ b/src/string.c @@ -526,7 +526,7 @@ str_make_shared(mrb_state *mrb, struct RString *orig, struct RString *s) size_t len = (size_t)orig->as.heap.len; mrb_assert(!RSTR_EMBED_P(orig)); - if (RSTR_NOFREE_P(orig)) { + if (RSTR_NOFREE_P(orig) || RSTR_POOL_P(orig)) { str_init_nofree(s, orig->as.heap.ptr, len); } else if (RSTR_SHARED_P(orig)) { @@ -535,7 +535,7 @@ str_make_shared(mrb_state *mrb, struct RString *orig, struct RString *s) else if (RSTR_FSHARED_P(orig)) { str_init_fshared(orig, s, orig->as.heap.aux.fshared); } - else if (mrb_frozen_p(orig) && !RSTR_POOL_P(orig)) { + else if (mrb_frozen_p(orig)) { str_init_fshared(orig, s, orig); } else { -- cgit v1.2.3 From b0507e7678ba1277a32c80c29cd868216673a9fa Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Tue, 15 Oct 2019 19:23:30 +0900 Subject: Adjust `buf` size in `str_escape` --- src/string.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/string.c') diff --git a/src/string.c b/src/string.c index e4b63a36d..d3774f8c4 100644 --- a/src/string.c +++ b/src/string.c @@ -1318,14 +1318,13 @@ str_replace_partial(mrb_state *mrb, mrb_value src, mrb_int pos, mrb_int end, mrb return src; } -#define CHAR_ESC_LEN 13 /* sizeof(\x{ hex of 32bit unsigned int } \0) */ #define IS_EVSTR(p,e) ((p) < (e) && (*(p) == '$' || *(p) == '@' || *(p) == '{')) static mrb_value str_escape(mrb_state *mrb, mrb_value str, mrb_bool inspect) { const char *p, *pend; - char buf[CHAR_ESC_LEN + 1]; + char buf[4]; /* `\x??` or UTF-8 character */ mrb_value result = mrb_str_new_lit(mrb, "\""); #ifdef MRB_UTF8_STRING uint32_t ascii_flag = MRB_STR_ASCII; -- cgit v1.2.3