* string.c (rb_str_change_terminator_length): New function to change
termlen and resize heap for the terminator. This is split from rb_str_fill_terminator (str_fill_term) because filling terminator and changing terminator length are different things. [Bug #12536] * internal.h: declaration for rb_str_change_terminator_length. * string.c (str_fill_term): Simplify only to zero-fill the terminator. For non-shared strings, it assumes that (capa + termlen) bytes of heap is allocated. This partially reverts r55557. * encoding.c (rb_enc_associate_index): rb_str_change_terminator_length is used, and it should be called whenever the termlen is changed. * string.c (str_capacity): New static function to return capacity of a string with the given termlen, because the termlen may sometimes be different from TERM_LEN(str) especially during changing termlen or filling terminator with specific termlen. * string.c (rb_str_capacity): Use str_capacity. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55575 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
a3ca2c7cd5
commit
5eff15d1bd
23
ChangeLog
23
ChangeLog
@ -1,3 +1,26 @@
|
|||||||
|
Tue Jul 5 19:39:49 2016 Naohisa Goto <ngotogenome@gmail.com>
|
||||||
|
|
||||||
|
* string.c (rb_str_change_terminator_length): New function to change
|
||||||
|
termlen and resize heap for the terminator. This is split from
|
||||||
|
rb_str_fill_terminator (str_fill_term) because filling terminator
|
||||||
|
and changing terminator length are different things. [Bug #12536]
|
||||||
|
|
||||||
|
* internal.h: declaration for rb_str_change_terminator_length.
|
||||||
|
|
||||||
|
* string.c (str_fill_term): Simplify only to zero-fill the terminator.
|
||||||
|
For non-shared strings, it assumes that (capa + termlen) bytes of
|
||||||
|
heap is allocated. This partially reverts r55557.
|
||||||
|
|
||||||
|
* encoding.c (rb_enc_associate_index): rb_str_change_terminator_length
|
||||||
|
is used, and it should be called whenever the termlen is changed.
|
||||||
|
|
||||||
|
* string.c (str_capacity): New static function to return capacity
|
||||||
|
of a string with the given termlen, because the termlen may
|
||||||
|
sometimes be different from TERM_LEN(str) especially during
|
||||||
|
changing termlen or filling terminator with specific termlen.
|
||||||
|
|
||||||
|
* string.c (rb_str_capacity): Use str_capacity.
|
||||||
|
|
||||||
Tue Jul 5 11:07:14 2016 NARUSE, Yui <naruse@ruby-lang.org>
|
Tue Jul 5 11:07:14 2016 NARUSE, Yui <naruse@ruby-lang.org>
|
||||||
|
|
||||||
* pack.c (pack_pack): use union instead of bare variable to ease
|
* pack.c (pack_pack): use union instead of bare variable to ease
|
||||||
|
@ -843,8 +843,8 @@ rb_enc_associate_index(VALUE obj, int idx)
|
|||||||
}
|
}
|
||||||
termlen = rb_enc_mbminlen(enc);
|
termlen = rb_enc_mbminlen(enc);
|
||||||
oldtermlen = rb_enc_mbminlen(rb_enc_from_index(oldidx));
|
oldtermlen = rb_enc_mbminlen(rb_enc_from_index(oldidx));
|
||||||
if (oldtermlen < termlen && RB_TYPE_P(obj, T_STRING)) {
|
if (oldtermlen != termlen && RB_TYPE_P(obj, T_STRING)) {
|
||||||
rb_str_fill_terminator(obj, termlen);
|
rb_str_change_terminator_length(obj, oldtermlen, termlen);
|
||||||
}
|
}
|
||||||
enc_set_index(obj, idx);
|
enc_set_index(obj, idx);
|
||||||
return obj;
|
return obj;
|
||||||
|
@ -1356,6 +1356,7 @@ VALUE rb_id_quote_unprintable(ID);
|
|||||||
#define QUOTE(str) rb_str_quote_unprintable(str)
|
#define QUOTE(str) rb_str_quote_unprintable(str)
|
||||||
#define QUOTE_ID(id) rb_id_quote_unprintable(id)
|
#define QUOTE_ID(id) rb_id_quote_unprintable(id)
|
||||||
char *rb_str_fill_terminator(VALUE str, const int termlen);
|
char *rb_str_fill_terminator(VALUE str, const int termlen);
|
||||||
|
void rb_str_change_terminator_length(VALUE str, const int oldtermlen, const int termlen);
|
||||||
VALUE rb_str_locktmp_ensure(VALUE str, VALUE (*func)(VALUE), VALUE arg);
|
VALUE rb_str_locktmp_ensure(VALUE str, VALUE (*func)(VALUE), VALUE arg);
|
||||||
#ifdef RUBY_ENCODING_H
|
#ifdef RUBY_ENCODING_H
|
||||||
VALUE rb_external_str_with_enc(VALUE str, rb_encoding *eenc);
|
VALUE rb_external_str_with_enc(VALUE str, rb_encoding *eenc);
|
||||||
|
69
string.c
69
string.c
@ -646,11 +646,11 @@ str_mod_check(VALUE s, const char *p, long len)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
static size_t
|
||||||
rb_str_capacity(VALUE str)
|
str_capacity(VALUE str, const int termlen)
|
||||||
{
|
{
|
||||||
if (STR_EMBED_P(str)) {
|
if (STR_EMBED_P(str)) {
|
||||||
return (RSTRING_EMBED_LEN_MAX + 1 - TERM_LEN(str));
|
return (RSTRING_EMBED_LEN_MAX + 1 - termlen);
|
||||||
}
|
}
|
||||||
else if (FL_TEST(str, STR_SHARED|STR_NOFREE)) {
|
else if (FL_TEST(str, STR_SHARED|STR_NOFREE)) {
|
||||||
return RSTRING(str)->as.heap.len;
|
return RSTRING(str)->as.heap.len;
|
||||||
@ -660,6 +660,12 @@ rb_str_capacity(VALUE str)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
rb_str_capacity(VALUE str)
|
||||||
|
{
|
||||||
|
return str_capacity(str, TERM_LEN(str));
|
||||||
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
must_not_null(const char *ptr)
|
must_not_null(const char *ptr)
|
||||||
{
|
{
|
||||||
@ -2021,42 +2027,55 @@ str_null_char(const char *s, long len, const int minlen, rb_encoding *enc)
|
|||||||
static char *
|
static char *
|
||||||
str_fill_term(VALUE str, char *s, long len, int termlen)
|
str_fill_term(VALUE str, char *s, long len, int termlen)
|
||||||
{
|
{
|
||||||
long capa = rb_str_capacity(str);
|
long capa = str_capacity(str, termlen);
|
||||||
/* This function could be called during the encoding changing procedure.
|
|
||||||
* If so, the termlen may be different from current TERM_LEN(str).
|
|
||||||
*/
|
|
||||||
const int oldtermlen = TERM_LEN(str);
|
|
||||||
|
|
||||||
if (capa < len + termlen - 1) { /* assumes oldtermlen is 1 here */
|
/* This function assumes that (capa + termlen) bytes of memory
|
||||||
|
* is allocated, like many other functions in this file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (capa < len) {
|
||||||
rb_check_lockedtmp(str);
|
rb_check_lockedtmp(str);
|
||||||
str_make_independent_expand(str, len, 0L, termlen);
|
str_make_independent_expand(str, len, 0L, termlen);
|
||||||
}
|
}
|
||||||
else if (str_dependent_p(str)) {
|
else if (str_dependent_p(str)) {
|
||||||
if ((termlen > oldtermlen) || !zero_filled(s + len, termlen))
|
if (!zero_filled(s + len, termlen))
|
||||||
str_make_independent_expand(str, len, 0L, termlen);
|
str_make_independent_expand(str, len, 0L, termlen);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (termlen > oldtermlen) {
|
|
||||||
if (!STR_EMBED_P(str)) {
|
|
||||||
const int d = termlen - oldtermlen;
|
|
||||||
if (capa > len + d) {
|
|
||||||
/* decrease capa for the new termlen */
|
|
||||||
capa -= d;
|
|
||||||
assert(capa >= 1);
|
|
||||||
assert(!FL_TEST((str), STR_SHARED));
|
|
||||||
RSTRING(str)->as.heap.aux.capa = capa;
|
|
||||||
} else {
|
|
||||||
assert(capa >= len);
|
|
||||||
RESIZE_CAPA_TERM(str, capa, termlen);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TERM_FILL(s + len, termlen);
|
TERM_FILL(s + len, termlen);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
return RSTRING_PTR(str);
|
return RSTRING_PTR(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_str_change_terminator_length(VALUE str, const int oldtermlen, const int termlen)
|
||||||
|
{
|
||||||
|
long capa = str_capacity(str, oldtermlen);
|
||||||
|
long len = RSTRING_LEN(str);
|
||||||
|
|
||||||
|
if (capa < len + termlen - oldtermlen) {
|
||||||
|
rb_check_lockedtmp(str);
|
||||||
|
str_make_independent_expand(str, len, 0L, termlen);
|
||||||
|
}
|
||||||
|
else if (str_dependent_p(str)) {
|
||||||
|
if (termlen > oldtermlen)
|
||||||
|
str_make_independent_expand(str, len, 0L, termlen);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!STR_EMBED_P(str)) {
|
||||||
|
/* modify capa instead of realloc */
|
||||||
|
assert(!FL_TEST((str), STR_SHARED));
|
||||||
|
RSTRING(str)->as.heap.aux.capa = capa - (termlen - oldtermlen);
|
||||||
|
}
|
||||||
|
if (termlen > oldtermlen) {
|
||||||
|
TERM_FILL(RSTRING_PTR(str) + len, termlen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
rb_string_value_cstr(volatile VALUE *ptr)
|
rb_string_value_cstr(volatile VALUE *ptr)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user