summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--bignum.c12
-rw-r--r--dir.c44
-rw-r--r--error.c12
-rw-r--r--eval.c63
-rw-r--r--file.c55
-rw-r--r--gc.c10
-rw-r--r--hash.c30
-rw-r--r--io.c158
-rw-r--r--marshal.c43
-rw-r--r--numeric.c2
-rw-r--r--object.c30
-rw-r--r--pack.c88
-rw-r--r--parse.y43
-rw-r--r--process.c18
-rw-r--r--re.c60
-rw-r--r--ruby.c28
-rw-r--r--ruby.h38
-rw-r--r--signal.c18
-rw-r--r--sprintf.c32
-rw-r--r--string.c868
-rw-r--r--time.c16
-rw-r--r--variable.c12
23 files changed, 900 insertions, 788 deletions
diff --git a/ChangeLog b/ChangeLog
index b51fed5bdd..d52b3d1a0e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Thu Aug 31 18:23:00 2006 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * ruby.h (struct RString): embed small strings.
+ (RSTRING_LEN): defined for accessing string members.
+ (RSTRING_PTR): ditto.
+
+ * string.c: use RSTRING_LEN and RSTRING_PTR.
+
Thu Aug 31 17:16:19 2006 Yukihiro Matsumoto <matz@ruby-lang.org>
* array.c (rb_ary_shuffle_bang): new method.
diff --git a/bignum.c b/bignum.c
index 8a5dd41782..dd29124995 100644
--- a/bignum.c
+++ b/bignum.c
@@ -494,10 +494,10 @@ rb_str_to_inum(VALUE str, int base, int badcheck)
s = StringValueCStr(str);
}
else {
- s = RSTRING(str)->ptr;
+ s = RSTRING_PTR(str);
}
if (s) {
- len = RSTRING(str)->len;
+ len = RSTRING_LEN(str);
if (s[len]) { /* no sentinel somehow */
char *p = ALLOCA_N(char, len+1);
@@ -631,7 +631,7 @@ rb_big2str(VALUE x, int base)
t = rb_big_clone(x);
ds = BDIGITS(t);
ss = rb_str_new(0, j);
- s = RSTRING(ss)->ptr;
+ s = RSTRING_PTR(ss);
s[0] = RBIGNUM(x)->sign ? '+' : '-';
while (i && j) {
@@ -653,9 +653,9 @@ rb_big2str(VALUE x, int base)
}
}
while (s[j] == '0') j++;
- RSTRING(ss)->len -= RBIGNUM(x)->sign?j:j-1;
- memmove(RBIGNUM(x)->sign?s:s+1, s+j, RSTRING(ss)->len);
- s[RSTRING(ss)->len] = '\0';
+ i = RSTRING_LEN(ss)-(RBIGNUM(x)->sign?j:j-1);
+ memmove(RBIGNUM(x)->sign?s:s+1, s+j, i);
+ rb_str_set_len(ss, i);
return ss;
}
diff --git a/dir.c b/dir.c
index 3a8eb61b1c..90b23c67cd 100644
--- a/dir.c
+++ b/dir.c
@@ -394,17 +394,17 @@ dir_initialize(VALUE dir, VALUE dirname)
if (dp->path) free(dp->path);
dp->dir = NULL;
dp->path = NULL;
- dp->dir = opendir(RSTRING(dirname)->ptr);
+ dp->dir = opendir(RSTRING_PTR(dirname));
if (dp->dir == NULL) {
if (errno == EMFILE || errno == ENFILE) {
rb_gc();
- dp->dir = opendir(RSTRING(dirname)->ptr);
+ dp->dir = opendir(RSTRING_PTR(dirname));
}
if (dp->dir == NULL) {
- rb_sys_fail(RSTRING(dirname)->ptr);
+ rb_sys_fail(RSTRING_PTR(dirname));
}
}
- dp->path = strdup(RSTRING(dirname)->ptr);
+ dp->path = strdup(RSTRING_PTR(dirname));
return dir;
}
@@ -470,7 +470,7 @@ dir_inspect(VALUE dir)
char *c = rb_obj_classname(dir);
int len = strlen(c) + strlen(dirp->path) + 4;
VALUE s = rb_str_new(0, len);
- snprintf(RSTRING(s)->ptr, len+1, "#<%s:%s>", c, dirp->path);
+ snprintf(RSTRING_PTR(s), len+1, "#<%s:%s>", c, dirp->path);
return s;
}
return rb_funcall(dir, rb_intern("to_s"), 0, 0);
@@ -688,8 +688,8 @@ dir_close(VALUE dir)
static void
dir_chdir(VALUE path)
{
- if (chdir(RSTRING(path)->ptr) < 0)
- rb_sys_fail(RSTRING(path)->ptr);
+ if (chdir(RSTRING_PTR(path)) < 0)
+ rb_sys_fail(RSTRING_PTR(path));
}
static int chdir_blocking = 0;
@@ -831,7 +831,7 @@ check_dirname(volatile VALUE *dir)
rb_secure(2);
FilePathValue(*dir);
- path = RSTRING(*dir)->ptr;
+ path = RSTRING_PTR(*dir);
if (path && *(pend = rb_path_end(rb_path_skip_prefix(path)))) {
*dir = rb_str_new(path, pend - path);
}
@@ -852,8 +852,8 @@ dir_s_chroot(VALUE dir, VALUE path)
#if defined(HAVE_CHROOT) && !defined(__CHECKER__)
check_dirname(&path);
- if (chroot(RSTRING(path)->ptr) == -1)
- rb_sys_fail(RSTRING(path)->ptr);
+ if (chroot(RSTRING_PTR(path)) == -1)
+ rb_sys_fail(RSTRING_PTR(path));
return INT2FIX(0);
#else
@@ -889,8 +889,8 @@ dir_s_mkdir(int argc, VALUE *argv, VALUE obj)
}
check_dirname(&path);
- if (mkdir(RSTRING(path)->ptr, mode) == -1)
- rb_sys_fail(RSTRING(path)->ptr);
+ if (mkdir(RSTRING_PTR(path), mode) == -1)
+ rb_sys_fail(RSTRING_PTR(path));
return INT2FIX(0);
}
@@ -908,8 +908,8 @@ static VALUE
dir_s_rmdir(VALUE obj, VALUE dir)
{
check_dirname(&dir);
- if (rmdir(RSTRING(dir)->ptr) < 0)
- rb_sys_fail(RSTRING(dir)->ptr);
+ if (rmdir(RSTRING_PTR(dir)) < 0)
+ rb_sys_fail(RSTRING_PTR(dir));
return INT2FIX(0);
}
@@ -1501,17 +1501,17 @@ rb_push_glob(VALUE str, int flags) /* '\0' is delimiter */
ary = rb_ary_new();
- while (offset < RSTRING(str)->len) {
- int status = push_glob(ary, RSTRING(str)->ptr + offset, flags);
+ while (offset < RSTRING_LEN(str)) {
+ int status = push_glob(ary, RSTRING_PTR(str) + offset, flags);
char *p, *pend;
if (status) rb_jump_tag(status);
- if (offset >= RSTRING(str)->len) break;
- p = RSTRING(str)->ptr + offset;
+ if (offset >= RSTRING_LEN(str)) break;
+ p = RSTRING_PTR(str) + offset;
p += strlen(p) + 1;
- pend = RSTRING(str)->ptr + RSTRING(str)->len;
+ pend = RSTRING_PTR(str) + RSTRING_LEN(str);
while (p < pend && !*p)
p++;
- offset = p - RSTRING(str)->ptr;
+ offset = p - RSTRING_PTR(str);
}
return ary;
@@ -1527,7 +1527,7 @@ dir_globs(long argc, VALUE *argv, int flags)
int status;
VALUE str = argv[i];
FilePathValue(str);
- status = push_glob(ary, RSTRING(str)->ptr, flags);
+ status = push_glob(ary, RSTRING_PTR(str), flags);
if (status) rb_jump_tag(status);
}
@@ -1797,7 +1797,7 @@ file_s_fnmatch(int argc, VALUE *argv, VALUE obj)
StringValue(pattern);
StringValue(path);
- if (fnmatch(RSTRING(pattern)->ptr, RSTRING(path)->ptr, flags) == 0)
+ if (fnmatch(RSTRING_PTR(pattern), RSTRING_PTR(path), flags) == 0)
return Qtrue;
return Qfalse;
diff --git a/error.c b/error.c
index cdb1b327a7..38d96ba4e7 100644
--- a/error.c
+++ b/error.c
@@ -221,7 +221,7 @@ rb_check_type(VALUE x, int t)
etype = "Symbol";
}
else if (rb_special_const_p(x)) {
- etype = RSTRING(rb_obj_as_string(x))->ptr;
+ etype = RSTRING_PTR(rb_obj_as_string(x));
}
else {
etype = rb_obj_classname(x);
@@ -378,7 +378,7 @@ exc_inspect(VALUE exc)
klass = CLASS_OF(exc);
exc = rb_obj_as_string(exc);
- if (RSTRING(exc)->len == 0) {
+ if (RSTRING_LEN(exc) == 0) {
return rb_str_dup(rb_class_name(klass));
}
@@ -699,10 +699,10 @@ name_err_mesg_to_str(VALUE obj)
break;
default:
d = rb_protect(rb_inspect, obj, 0);
- if (NIL_P(d) || RSTRING(d)->len > 65) {
+ if (NIL_P(d) || RSTRING_LEN(d) > 65) {
d = rb_any_to_s(obj);
}
- desc = RSTRING(d)->ptr;
+ desc = RSTRING_PTR(d);
break;
}
if (desc && desc[0] != '#') {
@@ -745,7 +745,7 @@ rb_invalid_str(const char *str, const char *type)
{
VALUE s = rb_str_inspect(rb_str_new2(str));
- rb_raise(rb_eArgError, "invalid value for %s: %s", type, RSTRING(s)->ptr);
+ rb_raise(rb_eArgError, "invalid value for %s: %s", type, RSTRING_PTR(s));
}
/*
@@ -856,7 +856,7 @@ syserr_initialize(int argc, VALUE *argv, VALUE self)
StringValue(str);
mesg = rb_sprintf("%s - %.*s", err,
- (int)RSTRING(str)->len, RSTRING(str)->ptr);
+ (int)RSTRING_LEN(str), RSTRING_PTR(str));
}
else {
mesg = rb_str_new2(err);
diff --git a/eval.c b/eval.c
index 7729337eb4..63e3c36250 100644
--- a/eval.c
+++ b/eval.c
@@ -1246,7 +1246,7 @@ error_print(void)
if (NIL_P(mesg)) error_pos();
else {
- warn_print2(RSTRING(mesg)->ptr, RSTRING(mesg)->len);
+ warn_print2(RSTRING_PTR(mesg), RSTRING_LEN(mesg));
}
}
@@ -1254,8 +1254,8 @@ error_print(void)
if (EXEC_TAG() == 0) {
e = rb_funcall(ruby_errinfo, rb_intern("message"), 0, 0);
StringValue(e);
- einfo = RSTRING(e)->ptr;
- elen = RSTRING(e)->len;
+ einfo = RSTRING_PTR(e);
+ elen = RSTRING_LEN(e);
}
else {
einfo = "";
@@ -1271,14 +1271,14 @@ error_print(void)
epath = rb_class_name(eclass);
if (elen == 0) {
warn_print(": ");
- warn_print2(RSTRING(epath)->ptr, RSTRING(epath)->len);
+ warn_print2(RSTRING_PTR(epath), RSTRING_LEN(epath));
warn_print("\n");
}
else {
char *tail = 0;
long len = elen;
- if (RSTRING(epath)->ptr[0] == '#') epath = 0;
+ if (RSTRING_PTR(epath)[0] == '#') epath = 0;
if (tail = memchr(einfo, '\n', elen)) {
len = tail - einfo;
tail++; /* skip newline */
@@ -1287,7 +1287,7 @@ error_print(void)
warn_print2(einfo, len);
if (epath) {
warn_print(" (");
- warn_print2(RSTRING(epath)->ptr, RSTRING(epath)->len);
+ warn_print2(RSTRING_PTR(epath), RSTRING_LEN(epath));
warn_print(")\n");
}
if (tail) {
@@ -1307,7 +1307,7 @@ error_print(void)
ep = RARRAY(errat);
for (i=1; i<ep->len; i++) {
if (TYPE(ep->ptr[i]) == T_STRING) {
- warn_printf("\tfrom %s\n", RSTRING(ep->ptr[i])->ptr);
+ warn_printf("\tfrom %s\n", RSTRING_PTR(ep->ptr[i]));
}
if (i == TRACE_HEAD && ep->len > TRACE_MAX) {
warn_printf("\t ... %ld levels...\n",
@@ -2642,7 +2642,7 @@ class_prefix(VALUE self, NODE *cpath)
break;
default:
rb_raise(rb_eTypeError, "%s is not a class/module",
- RSTRING(rb_obj_as_string(c))->ptr);
+ RSTRING_PTR(rb_obj_as_string(c)));
}
return c;
}
@@ -3568,7 +3568,7 @@ rb_eval(VALUE self, NODE *n)
break;
default:
rb_raise(rb_eTypeError, "%s is not a class/module",
- RSTRING(rb_obj_as_string(klass))->ptr);
+ RSTRING_PTR(rb_obj_as_string(klass)));
break;
}
}
@@ -3666,7 +3666,10 @@ rb_eval(VALUE self, NODE *n)
break;
case NODE_EVSTR:
- result = rb_obj_as_string(rb_eval(self, node->nd_body));
+ if (!node->nd_body) result = rb_str_new(0,0);
+ else {
+ result = rb_obj_as_string(rb_eval(self, node->nd_body));
+ }
break;
case NODE_DSTR:
@@ -3696,11 +3699,11 @@ rb_eval(VALUE self, NODE *n)
}
switch (nd_type(node)) {
case NODE_DREGX:
- result = rb_reg_new(RSTRING(str)->ptr, RSTRING(str)->len,
+ result = rb_reg_new(RSTRING_PTR(str), RSTRING_LEN(str),
node->nd_cflag);
break;
case NODE_DREGX_ONCE: /* regexp expand once */
- result = rb_reg_new(RSTRING(str)->ptr, RSTRING(str)->len,
+ result = rb_reg_new(RSTRING_PTR(str), RSTRING_LEN(str),
node->nd_cflag);
nd_set_type(node, NODE_LIT);
node->nd_lit = result;
@@ -4404,7 +4407,7 @@ rb_longjmp(int tag, VALUE mesg)
warn_printf("Exception `%s' at %s:%d - %s\n",
rb_obj_classname(ruby_errinfo),
ruby_sourcefile, ruby_sourceline,
- RSTRING(e)->ptr);
+ RSTRING_PTR(e));
}
POP_TAG();
if (status == TAG_FATAL && ruby_errinfo == exception_error) {
@@ -6228,7 +6231,7 @@ rb_backtrace(void)
ary = backtrace(-1);
for (i=0; i<RARRAY(ary)->len; i++) {
- printf("\tfrom %s\n", RSTRING(RARRAY(ary)->ptr[i])->ptr);
+ printf("\tfrom %s\n", RSTRING_PTR(RARRAY(ary)->ptr[i]));
}
}
@@ -6421,7 +6424,7 @@ rb_f_eval(int argc, VALUE *argv, VALUE self)
line = NUM2INT(vline);
}
- if (!NIL_P(vfile)) file = RSTRING(vfile)->ptr;
+ if (!NIL_P(vfile)) file = RSTRING_PTR(vfile);
if (NIL_P(scope) && ruby_frame->prev) {
struct FRAME *prev;
VALUE val;
@@ -6750,7 +6753,7 @@ rb_load(VALUE fname, int wrap)
ruby_in_eval++;
critical = rb_thread_critical;
rb_thread_critical = Qtrue;
- rb_load_file(RSTRING(fname)->ptr);
+ rb_load_file(RSTRING_PTR(fname));
ruby_in_eval--;
node = ruby_eval_tree;
rb_thread_critical = critical;
@@ -6899,7 +6902,7 @@ rb_provided(const char *feature)
}
}
if (search_required(rb_str_new2(feature), &fname)) {
- feature = RSTRING(fname)->ptr;
+ feature = RSTRING_PTR(fname);
if (rb_feature_p(feature, 0, Qfalse))
return Qtrue;
if (loading_tbl && st_lookup(loading_tbl, (st_data_t)feature, 0))
@@ -6970,13 +6973,13 @@ search_required(VALUE fname, VALUE *path)
int type, ft = 0;
*path = 0;
- ext = strrchr(ftptr = RSTRING(fname)->ptr, '.');
+ ext = strrchr(ftptr = RSTRING_PTR(fname), '.');
if (ext && !strchr(ext, '/')) {
if (strcmp(".rb", ext) == 0) {
if (rb_feature_p(ftptr, ext, Qtrue)) return 'r';
if (tmp = rb_find_file(fname)) {
tmp = rb_file_expand_path(tmp, Qnil);
- ext = strrchr(ftptr = RSTRING(tmp)->ptr, '.');
+ ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
if (!rb_feature_p(ftptr, ext, Qtrue))
*path = tmp;
return 'r';
@@ -6985,7 +6988,7 @@ search_required(VALUE fname, VALUE *path)
}
else if (IS_SOEXT(ext)) {
if (rb_feature_p(ftptr, ext, Qfalse)) return 's';
- tmp = rb_str_new(RSTRING(fname)->ptr, ext-RSTRING(fname)->ptr);
+ tmp = rb_str_new(RSTRING_PTR(fname), ext-RSTRING_PTR(fname));
#ifdef DLEXT2
OBJ_FREEZE(tmp);
if (rb_find_file_ext(&tmp, loadable_ext+1)) {
@@ -7000,7 +7003,7 @@ search_required(VALUE fname, VALUE *path)
OBJ_FREEZE(tmp);
if (tmp = rb_find_file(tmp)) {
tmp = rb_file_expand_path(tmp, Qnil);
- ext = strrchr(ftptr = RSTRING(tmp)->ptr, '.');
+ ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
if (!rb_feature_p(ftptr, ext, Qfalse))
*path = tmp;
return 's';
@@ -7011,7 +7014,7 @@ search_required(VALUE fname, VALUE *path)
if (rb_feature_p(ftptr, ext, Qfalse)) return 's';
if (tmp = rb_find_file(fname)) {
tmp = rb_file_expand_path(tmp, Qnil);
- ext = strrchr(ftptr = RSTRING(tmp)->ptr, '.');
+ ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
if (!rb_feature_p(ftptr, ext, Qfalse))
*path = tmp;
return 's';
@@ -7026,14 +7029,14 @@ search_required(VALUE fname, VALUE *path)
tmp = rb_file_expand_path(tmp, Qnil);
switch (type) {
case 0:
- ftptr = RSTRING(tmp)->ptr;
+ ftptr = RSTRING_PTR(tmp);
if (ft) break;
return rb_feature_p(ftptr, 0, Qfalse);
default:
if (ft) break;
case 1:
- ext = strrchr(ftptr = RSTRING(tmp)->ptr, '.');
+ ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
if (rb_feature_p(ftptr, ext, !--type)) break;
*path = tmp;
}
@@ -7043,7 +7046,7 @@ search_required(VALUE fname, VALUE *path)
static void
load_failed(VALUE fname)
{
- rb_raise(rb_eLoadError, "no such file to load -- %s", RSTRING(fname)->ptr);
+ rb_raise(rb_eLoadError, "no such file to load -- %s", RSTRING_PTR(fname));
}
VALUE
@@ -7078,7 +7081,7 @@ rb_require_safe(VALUE fname, int safe)
*(volatile VALUE *)&fname = rb_str_new4(fname);
found = search_required(fname, &path);
if (found) {
- if (!path || load_wait(RSTRING(path)->ptr)) {
+ if (!path || load_wait(RSTRING_PTR(path))) {
result = Qfalse;
}
else {
@@ -7090,19 +7093,19 @@ rb_require_safe(VALUE fname, int safe)
loading_tbl = st_init_strtable();
}
/* partial state */
- ftptr = ruby_strdup(RSTRING(path)->ptr);
+ ftptr = ruby_strdup(RSTRING_PTR(path));
st_insert(loading_tbl, (st_data_t)ftptr, (st_data_t)curr_thread);
rb_load(path, 0);
break;
case 's':
ruby_current_node = 0;
- ruby_sourcefile = rb_source_filename(RSTRING(path)->ptr);
+ ruby_sourcefile = rb_source_filename(RSTRING_PTR(path));
ruby_sourceline = 0;
ruby_frame->callee = 0;
ruby_frame->this_func = 0;
VIS_SET(VIS_PUBLIC);
- handle = (long)dln_load(RSTRING(path)->ptr);
+ handle = (long)dln_load(RSTRING_PTR(path));
rb_ary_push(ruby_dln_librefs, LONG2NUM(handle));
break;
}
@@ -7975,7 +7978,7 @@ rb_mod_autoload(VALUE mod, VALUE sym, VALUE file)
ID id = rb_to_id(sym);
Check_SafeStr(file);
- rb_autoload(mod, id, RSTRING(file)->ptr);
+ rb_autoload(mod, id, RSTRING_PTR(file));
return Qnil;
}
diff --git a/file.c b/file.c
index 195c9fdc32..9482613b69 100644
--- a/file.c
+++ b/file.c
@@ -743,7 +743,7 @@ rb_file_s_lstat(VALUE klass, VALUE fname)
rb_secure(2);
FilePathValue(fname);
if (lstat(StringValueCStr(fname), &st) == -1) {
- rb_sys_fail(RSTRING(fname)->ptr);
+ rb_sys_fail(RSTRING_PTR(fname));
}
return stat_new(&st);
#else
@@ -1545,7 +1545,7 @@ rb_file_s_ftype(VALUE klass, VALUE fname)
rb_secure(2);
FilePathValue(fname);
if (lstat(StringValueCStr(fname), &st) == -1) {
- rb_sys_fail(RSTRING(fname)->ptr);
+ rb_sys_fail(RSTRING_PTR(fname));
}
return rb_file_ftype(&st);
@@ -1611,7 +1611,7 @@ rb_file_s_mtime(VALUE klass, VALUE fname)
struct stat st;
if (rb_stat(fname, &st) < 0)
- rb_sys_fail(RSTRING(fname)->ptr);
+ rb_sys_fail(RSTRING_PTR(fname));
return rb_time_new(st.st_mtime, 0);
}
@@ -1656,7 +1656,7 @@ rb_file_s_ctime(VALUE klass, VALUE fname)
struct stat st;
if (rb_stat(fname, &st) < 0)
- rb_sys_fail(RSTRING(fname)->ptr);
+ rb_sys_fail(RSTRING_PTR(fname));
return rb_time_new(st.st_ctime, 0);
}
@@ -2022,9 +2022,9 @@ sys_fail2(VALUE s1, VALUE s2)
char *buf;
int len;
- len = RSTRING(s1)->len + RSTRING(s2)->len + 5;
+ len = RSTRING_LEN(s1) + RSTRING_LEN(s2) + 5;
buf = ALLOCA_N(char, len);
- snprintf(buf, len, "(%s, %s)", RSTRING(s1)->ptr, RSTRING(s2)->ptr);
+ snprintf(buf, len, "(%s, %s)", RSTRING_PTR(s1), RSTRING_PTR(s2));
rb_sys_fail(buf);
}
@@ -2111,7 +2111,7 @@ rb_file_s_readlink(VALUE klass, VALUE path)
rb_secure(2);
FilePathValue(path);
buf = xmalloc(size);
- while ((rv = readlink(RSTRING(path)->ptr, buf, size)) == size
+ while ((rv = readlink(RSTRING_PTR(path), buf, size)) == size
#ifdef _AIX
|| (rv < 0 && errno == ERANGE) /* quirky behavior of GPFS */
#endif
@@ -2121,7 +2121,7 @@ rb_file_s_readlink(VALUE klass, VALUE path)
}
if (rv < 0) {
free(buf);
- rb_sys_fail(RSTRING(path)->ptr);
+ rb_sys_fail(RSTRING_PTR(path));
}
v = rb_tainted_str_new(buf, rv);
free(buf);
@@ -2390,14 +2390,14 @@ rb_path_end(const char *path)
buflen *= 2;\
}\
rb_str_resize(result, buflen);\
- buf = RSTRING(result)->ptr;\
+ buf = RSTRING_PTR(result);\
p = buf + bdiff;\
pend = buf + buflen;\
} while (0)
#define BUFINIT() (\
- p = buf = RSTRING(result)->ptr,\
- buflen = RSTRING(result)->len,\
+ p = buf = RSTRING_PTR(result),\
+ buflen = RSTRING_LEN(result),\
pend = p + buflen)
#if !defined(TOLOWER)
@@ -2601,8 +2601,7 @@ file_expand_path(VALUE fname, VALUE dname, VALUE result)
if (p == skiproot(buf) - 1) p++;
if (tainted) OBJ_TAINT(result);
- RSTRING(result)->len = p - buf;
- *p = '\0';
+ rb_str_set_len(result, p - buf);
return result;
}
@@ -2692,7 +2691,7 @@ rb_file_s_basename(int argc, VALUE *argv)
StringValue(fext);
}
StringValue(fname);
- if (RSTRING(fname)->len == 0 || !*(name = RSTRING(fname)->ptr))
+ if (RSTRING_LEN(fname) == 0 || !*(name = RSTRING_PTR(fname)))
return fname;
name = skipprefix(name);
#if defined DOSISH_DRIVE_LETTER || defined DOSISH_UNC
@@ -2723,7 +2722,7 @@ rb_file_s_basename(int argc, VALUE *argv)
else if (!(p = strrdirsep(name))) {
if (NIL_P(fext) || !(f = rmext(name, StringValueCStr(fext)))) {
f = chompdirsep(name) - name;
- if (f == RSTRING(fname)->len) return fname;
+ if (f == RSTRING_LEN(fname)) return fname;
}
p = name;
}
@@ -2881,7 +2880,7 @@ rb_file_join(VALUE ary, VALUE sep)
len = 1;
for (i=0; i<RARRAY(ary)->len; i++) {
if (TYPE(RARRAY(ary)->ptr[i]) == T_STRING) {
- len += RSTRING(RARRAY(ary)->ptr[i])->len;
+ len += RSTRING_LEN(RARRAY(ary)->ptr[i]);
}
else {
len += 10;
@@ -2889,7 +2888,7 @@ rb_file_join(VALUE ary, VALUE sep)
}
if (!NIL_P(sep)) {
StringValue(sep);
- len += RSTRING(sep)->len * RARRAY(ary)->len - 1;
+ len += RSTRING_LEN(sep) * RARRAY(ary)->len - 1;
}
result = rb_str_buf_new(len);
OBJ_INFECT(result, ary);
@@ -2913,8 +2912,8 @@ rb_file_join(VALUE ary, VALUE sep)
name = StringValueCStr(result);
if (i > 0 && !NIL_P(sep)) {
tail = chompdirsep(name);
- if (RSTRING(tmp)->ptr && isdirsep(RSTRING(tmp)->ptr[0])) {
- RSTRING(result)->len = tail - name;
+ if (RSTRING_PTR(tmp) && isdirsep(RSTRING_PTR(tmp)[0])) {
+ rb_str_set_len(result, tail - name);
}
else if (!*tail) {
rb_str_buf_append(result, sep);
@@ -2968,7 +2967,7 @@ rb_file_s_truncate(VALUE klass, VALUE path, VALUE len)
FilePathValue(path);
#ifdef HAVE_TRUNCATE
if (truncate(StringValueCStr(path), pos) < 0)
- rb_sys_fail(RSTRING(path)->ptr);
+ rb_sys_fail(RSTRING_PTR(path));
#else
# ifdef HAVE_CHSIZE
{
@@ -3334,7 +3333,7 @@ rb_f_test(int argc, VALUE *argv)
CHECK(1);
if (rb_stat(argv[1], &st) == -1) {
- rb_sys_fail(RSTRING(argv[1])->ptr);
+ rb_sys_fail(RSTRING_PTR(argv[1]));
}
switch (cmd) {
@@ -3417,7 +3416,7 @@ rb_stat_init(VALUE obj, VALUE fname)
rb_secure(2);
FilePathValue(fname);
if (stat(StringValueCStr(fname), &st) == -1) {
- rb_sys_fail(RSTRING(fname)->ptr);
+ rb_sys_fail(RSTRING_PTR(fname));
}
if (DATA_PTR(obj)) {
free(DATA_PTR(obj));
@@ -4145,7 +4144,7 @@ int
rb_find_file_ext(VALUE *filep, const char *const *ext)
{
char *path, *found;
- char *f = RSTRING(*filep)->ptr;
+ char *f = RSTRING_PTR(*filep);
VALUE fname;
long i, j;
@@ -4179,8 +4178,8 @@ rb_find_file_ext(VALUE *filep, const char *const *ext)
VALUE str = RARRAY(rb_load_path)->ptr[i];
FilePathValue(str);
- if (RSTRING(str)->len == 0) continue;
- path = RSTRING(str)->ptr;
+ if (RSTRING_LEN(str) == 0) continue;
+ path = RSTRING_PTR(str);
for (j=0; ext[j]; j++) {
fname = rb_str_dup(*filep);
rb_str_cat2(fname, ext[j]);
@@ -4239,16 +4238,16 @@ rb_find_file(VALUE path)
for (i=0;i<RARRAY(rb_load_path)->len;i++) {
VALUE str = RARRAY(rb_load_path)->ptr[i];
FilePathValue(str);
- if (RSTRING(str)->len > 0) {
+ if (RSTRING_LEN(str) > 0) {
rb_ary_push(tmp, str);
}
}
tmp = rb_ary_join(tmp, rb_str_new2(PATH_SEP));
- if (RSTRING(tmp)->len == 0) {
+ if (RSTRING_LEN(tmp) == 0) {
lpath = 0;
}
else {
- lpath = RSTRING(tmp)->ptr;
+ lpath = RSTRING_PTR(tmp);
if (rb_safe_level() >= 1 && !rb_path_check(lpath)) {
rb_raise(rb_eSecurityError, "loading from unsafe path %s", lpath);
}
diff --git a/gc.c b/gc.c
index db16d6c841..9bd44f30cb 100644
--- a/gc.c
+++ b/gc.c
@@ -945,9 +945,10 @@ gc_mark_children(VALUE ptr, int lev)
goto again;
case T_STRING:
+#define STR_NOEMBED FL_USER1 /* copied from string.c */
#define STR_ASSOC FL_USER3 /* copied from string.c */
- if (FL_TEST(obj, ELTS_SHARED|STR_ASSOC)) {
- ptr = obj->as.string.aux.shared;
+ if (FL_TEST(obj, STR_NOEMBED) && FL_ANY(obj, ELTS_SHARED|STR_ASSOC)) {
+ ptr = obj->as.string.as.heap.aux.shared;
goto again;
}
break;
@@ -1174,8 +1175,9 @@ obj_free(VALUE obj)
}
break;
case T_STRING:
- if (RANY(obj)->as.string.ptr && !FL_TEST(obj, ELTS_SHARED)) {
- RUBY_CRITICAL(free(RANY(obj)->as.string.ptr));
+ if (FL_TEST(obj, STR_NOEMBED) &&
+ RANY(obj)->as.string.as.heap.ptr && !FL_TEST(obj, ELTS_SHARED)) {
+ RUBY_CRITICAL(free(RANY(obj)->as.string.as.heap.ptr));
}
break;
case T_ARRAY:
diff --git a/hash.c b/hash.c
index 7a3035f6df..6a9ad90eab 100644
--- a/hash.c
+++ b/hash.c
@@ -1117,7 +1117,7 @@ inspect_i(VALUE key, VALUE value, VALUE str)
VALUE str2;
if (key == Qundef) return ST_CONTINUE;
- if (RSTRING(str)->len > 1) {
+ if (RSTRING_LEN(str) > 1) {
rb_str_cat2(str, ", ");
}
str2 = rb_inspect(key);
@@ -1540,8 +1540,8 @@ env_delete(VALUE obj, VALUE name)
rb_secure(4);
SafeStringValue(name);
- nam = RSTRING(name)->ptr;
- if (strlen(nam) != RSTRING(name)->len) {
+ nam = RSTRING_PTR(name);
+ if (strlen(nam) != RSTRING_LEN(name)) {
rb_raise(rb_eArgError, "bad environment variable name");
}
val = getenv(nam);
@@ -1579,8 +1579,8 @@ rb_f_getenv(VALUE obj, VALUE name)
rb_secure(4);
SafeStringValue(name);
- nam = RSTRING(name)->ptr;
- if (strlen(nam) != RSTRING(name)->len) {
+ nam = RSTRING_PTR(name);
+ if (strlen(nam) != RSTRING_LEN(name)) {
rb_raise(rb_eArgError, "bad environment variable name");
}
env = getenv(nam);
@@ -1615,8 +1615,8 @@ env_fetch(int argc, VALUE *argv)
rb_warn("block supersedes default value argument");
}
SafeStringValue(key);
- nam = RSTRING(key)->ptr;
- if (strlen(nam) != RSTRING(key)->len) {
+ nam = RSTRING_PTR(key);
+ if (strlen(nam) != RSTRING_LEN(key)) {
rb_raise(rb_eArgError, "bad environment variable name");
}
env = getenv(nam);
@@ -1774,11 +1774,11 @@ env_aset(VALUE obj, VALUE nm, VALUE val)
}
StringValue(nm);
StringValue(val);
- name = RSTRING(nm)->ptr;
- value = RSTRING(val)->ptr;
- if (strlen(name) != RSTRING(nm)->len)
+ name = RSTRING_PTR(nm);
+ value = RSTRING_PTR(val);
+ if (strlen(name) != RSTRING_LEN(nm))
rb_raise(rb_eArgError, "bad environment variable name");
- if (strlen(value) != RSTRING(val)->len)
+ if (strlen(value) != RSTRING_LEN(val))
rb_raise(rb_eArgError, "bad environment variable value");
ruby_setenv(name, value);
@@ -2101,7 +2101,7 @@ env_has_key(VALUE env, VALUE key)
rb_secure(4);
s = StringValuePtr(key);
- if (strlen(s) != RSTRING(key)->len)
+ if (strlen(s) != RSTRING_LEN(key))
rb_raise(rb_eArgError, "bad environment variable name");
if (getenv(s)) return Qtrue;
return Qfalse;
@@ -2119,7 +2119,7 @@ env_has_value(VALUE dmy, VALUE value)
char *s = strchr(*env, '=');
if (s++) {
long len = strlen(s);
- if (RSTRING(value)->len == len && strncmp(s, RSTRING(value)->ptr, len) == 0) {
+ if (RSTRING_LEN(value) == len && strncmp(s, RSTRING_PTR(value), len) == 0) {
FREE_ENVIRON(environ);
return Qtrue;
}
@@ -2143,7 +2143,7 @@ env_key(VALUE dmy, VALUE value)
char *s = strchr(*env, '=');
if (s++) {
long len = strlen(s);
- if (RSTRING(value)->len == len && strncmp(s, RSTRING(value)->ptr, len) == 0) {
+ if (RSTRING_LEN(value) == len && strncmp(s, RSTRING_PTR(value), len) == 0) {
str = env_str_new(*env, s-*env-1);
FREE_ENVIRON(environ);
return str;
@@ -2200,7 +2200,7 @@ env_shift(void)
char *s = strchr(*env, '=');
if (s) {
VALUE key = env_str_new(*env, s-*env);
- VALUE val = env_str_new2(getenv(RSTRING(key)->ptr));
+ VALUE val = env_str_new2(getenv(RSTRING_PTR(key)));
env_delete(Qnil, key);
return rb_assoc_new(key, val);
}
diff --git a/io.c b/io.c
index b265444135..9f90104f80 100644
--- a/io.c
+++ b/io.c
@@ -543,7 +543,7 @@ io_fwrite(VALUE str, OpenFile *fptr)
{
long len, n, r, l, offset = 0;
- len = RSTRING(str)->len;
+ len = RSTRING_LEN(str);
if ((n = len) <= 0) return n;
if (fptr->wbuf == NULL && !(fptr->mode & FMODE_SYNC)) {
fptr->wbuf_off = 0;
@@ -553,14 +553,14 @@ io_fwrite(VALUE str, OpenFile *fptr)
}
if ((fptr->mode & FMODE_SYNC) ||
(fptr->wbuf && fptr->wbuf_capa <= fptr->wbuf_len + len) ||
- ((fptr->mode & FMODE_TTY) && memchr(RSTRING(str)->ptr+offset, '\n', len))) {
+ ((fptr->mode & FMODE_TTY) && memchr(RSTRING_PTR(str)+offset, '\n', len))) {
/* xxx: use writev to avoid double write if available */
if (fptr->wbuf_len && fptr->wbuf_len+len <= fptr->wbuf_capa) {
if (fptr->wbuf_capa < fptr->wbuf_off+fptr->wbuf_len+len) {
MEMMOVE(fptr->wbuf, fptr->wbuf+fptr->wbuf_off, char, fptr->wbuf_len);
fptr->wbuf_off = 0;
}
- MEMMOVE(fptr->wbuf+fptr->wbuf_off+fptr->wbuf_len, RSTRING(str)->ptr+offset, char, len);
+ MEMMOVE(fptr->wbuf+fptr->wbuf_off+fptr->wbuf_len, RSTRING_PTR(str)+offset, char, len);
fptr->wbuf_len += len;
n = 0;
}
@@ -582,7 +582,7 @@ io_fwrite(VALUE str, OpenFile *fptr)
l = PIPE_BUF;
}
TRAP_BEG;
- r = write(fptr->fd, RSTRING(str)->ptr+offset, l);
+ r = write(fptr->fd, RSTRING_PTR(str)+offset, l);
TRAP_END; /* xxx: signal handler may modify given string. */
if (r == n) return len;
if (0 <= r) {
@@ -592,7 +592,7 @@ io_fwrite(VALUE str, OpenFile *fptr)
}
if (rb_io_wait_writable(fptr->fd)) {
rb_io_check_closed(fptr);
- if (offset < RSTRING(str)->len)
+ if (offset < RSTRING_LEN(str))
goto retry;
}
return -1L;
@@ -603,7 +603,7 @@ io_fwrite(VALUE str, OpenFile *fptr)
MEMMOVE(fptr->wbuf, fptr->wbuf+fptr->wbuf_off, char, fptr->wbuf_len);
fptr->wbuf_off = 0;
}
- MEMMOVE(fptr->wbuf+fptr->wbuf_off+fptr->wbuf_len, RSTRING(str)->ptr+offset, char, len);
+ MEMMOVE(fptr->wbuf+fptr->wbuf_off+fptr->wbuf_len, RSTRING_PTR(str)+offset, char, len);
fptr->wbuf_len += len;
return len;
}
@@ -653,7 +653,7 @@ io_write(VALUE io, VALUE str)
return rb_funcall(io, id_write, 1, str);
}
io = tmp;
- if (RSTRING(str)->len == 0) return INT2FIX(0);
+ if (RSTRING_LEN(str) == 0) return INT2FIX(0);
GetOpenFile(io, fptr);
rb_io_check_writable(fptr);
@@ -1138,12 +1138,12 @@ read_buffered_data(char *ptr, long len, OpenFile *fptr)
static long
io_fread(VALUE str, long offset, OpenFile *fptr)
{
- long len = RSTRING(str)->len - offset;
+ long len = RSTRING_LEN(str) - offset;
long n = len;
int c;
while (n > 0) {
- c = read_buffered_data(RSTRING(str)->ptr+offset, n, fptr);
+ c = read_buffered_data(RSTRING_PTR(str)+offset, n, fptr);
if (c > 0) {
offset += c;
if ((n -= c) <= 0) break;
@@ -1154,8 +1154,8 @@ io_fread(VALUE str, long offset, OpenFile *fptr)
if (c < 0) {
break;
}
- RSTRING(str)->ptr[offset++] = c;
- if (offset > RSTRING(str)->len) break;
+ RSTRING_PTR(str)[offset++] = c;
+ if (offset > RSTRING_LEN(str)) break;
n--;
}
return len - n;
@@ -1173,7 +1173,7 @@ rb_io_fread(char *ptr, long len, FILE *f)
of.mode = FMODE_READABLE;
str = rb_str_new(ptr, len);
n = io_fread(str, 0, &of);
- MEMCPY(ptr, RSTRING(str)->ptr, char, n);
+ MEMCPY(ptr, RSTRING_PTR(str), char, n);
return n;
}
@@ -1287,21 +1287,21 @@ io_getpartial(int argc, VALUE *argv, VALUE io, int nonblock)
if (!nonblock)
READ_CHECK(fptr);
- if (RSTRING(str)->len != len) {
+ if (RSTRING_LEN(str) != len) {
modified:
rb_raise(rb_eRuntimeError, "buffer string modified");
}
- n = read_buffered_data(RSTRING(str)->ptr, len, fptr);
+ n = read_buffered_data(RSTRING_PTR(str), len, fptr);
if (n <= 0) {
again:
- if (RSTRING(str)->len != len) goto modified;
+ if (RSTRING_LEN(str) != len) goto modified;
if (nonblock) {
rb_io_set_nonblock(fptr);
- n = read(fptr->fd, RSTRING(str)->ptr, len);
+ n = read(fptr->fd, RSTRING_PTR(str), len);
}
else {
TRAP_BEG;
- n = read(fptr->fd, RSTRING(str)->ptr, len);
+ n = read(fptr->fd, RSTRING_PTR(str), len);
TRAP_END;
}
if (n < 0) {
@@ -1456,7 +1456,7 @@ rb_io_write_nonblock(VALUE io, VALUE str)
io_fflush(fptr);
rb_io_set_nonblock(fptr);
- n = write(fptr->fd, RSTRING(str)->ptr, RSTRING(str)->len);
+ n = write(fptr->fd, RSTRING_PTR(str), RSTRING_LEN(str));
if (n == -1) rb_sys_fail(fptr->path);
@@ -1519,7 +1519,7 @@ io_read(int argc, VALUE *argv, VALUE io)
if (len == 0) return str;
READ_CHECK(fptr);
- if (RSTRING(str)->len != len) {
+ if (RSTRING_LEN(str) != len) {
rb_raise(rb_eRuntimeError, "buffer string modified");
}
n = io_fread(str, 0, fptr);
@@ -1529,8 +1529,6 @@ io_read(int argc, VALUE *argv, VALUE io)
return Qnil;
}
rb_str_resize(str, n);
- RSTRING(str)->len = n;
- RSTRING(str)->ptr[n] = '\0';
OBJ_TAINT(str);
return str;
@@ -1551,18 +1549,17 @@ appendline(OpenFile *fptr, int delim, VALUE *strp)
if (e) pending = e - p + 1;
len += pending;
if (!NIL_P(str)) {
- last = RSTRING(str)->len;
+ last = RSTRING_LEN(str);
rb_str_resize(str, last + len);
}
else {
*strp = str = rb_str_buf_new(len);
- RSTRING(str)->len = len;
- RSTRING(str)->ptr[len] = '\0';
+ rb_str_set_len(str, len);
}
if (c != EOF) {
- RSTRING(str)->ptr[last++] = c;
+ RSTRING_PTR(str)[last++] = c;
}
- read_buffered_data(RSTRING(str)->ptr + last, pending, fptr); /* must not fail */
+ read_buffered_data(RSTRING_PTR(str) + last, pending, fptr); /* must not fail */
if (e) return delim;
}
else if (c != EOF) {
@@ -1572,7 +1569,8 @@ appendline(OpenFile *fptr, int delim, VALUE *strp)
}
else {
*strp = str = rb_str_buf_new(1);
- RSTRING(str)->ptr[RSTRING(str)->len++] = c;
+ rb_str_resize(str, 1);
+ RSTRING_PTR(str)[0] = c;
}
}
rb_thread_wait_fd(fptr->fd);
@@ -1645,7 +1643,7 @@ rb_io_getline_fast(OpenFile *fptr, unsigned char delim)
static int
rscheck(const char *rsptr, long rslen, VALUE rs)
{
- if (RSTRING(rs)->ptr != rsptr && RSTRING(rs)->len != rslen)
+ if (RSTRING_PTR(rs) != rsptr && RSTRING_LEN(rs) != rslen)
rb_raise(rb_eRuntimeError, "rs modified");
return 0;
}
@@ -1660,7 +1658,7 @@ rb_io_getline(VALUE rs, VALUE io)
rb_io_check_readable(fptr);
if (NIL_P(rs)) {
str = read_all(fptr, 0, Qnil);
- if (RSTRING(str)->len == 0) return Qnil;
+ if (RSTRING_LEN(str) == 0) return Qnil;
}
else if (rs == rb_default_rs) {
return rb_io_getline_fast(fptr, '\n');
@@ -1671,7 +1669,7 @@ rb_io_getline(VALUE rs, VALUE io)
long rslen;
int rspara = 0;
- rslen = RSTRING(rs)->len;
+ rslen = RSTRING_LEN(rs);
if (rslen == 0) {
rsptr = "\n\n";
rslen = 2;
@@ -1679,18 +1677,18 @@ rb_io_getline(VALUE rs, VALUE io)
swallow(fptr, '\n');
}
else if (rslen == 1) {
- return rb_io_getline_fast(fptr, (unsigned char)RSTRING(rs)->ptr[0]);
+ return rb_io_getline_fast(fptr, (unsigned char)RSTRING_PTR(rs)[0]);
}
else {
- rsptr = RSTRING(rs)->ptr;
+ rsptr = RSTRING_PTR(rs);
}
newline = rsptr[rslen - 1];
while ((c = appendline(fptr, newline, &str)) != EOF) {
if (c == newline) {
- if (RSTRING(str)->len < rslen) continue;
+ if (RSTRING_LEN(str) < rslen) continue;
if (!rspara) rscheck(rsptr, rslen, rs);
- if (memcmp(RSTRING(str)->ptr + RSTRING(str)->len - rslen,
+ if (memcmp(RSTRING_PTR(str) + RSTRING_LEN(str) - rslen,
rsptr, rslen) == 0) break;
}
}
@@ -2077,10 +2075,10 @@ rb_io_ungetc(VALUE io, VALUE c)
}
else {
SafeStringValue(c);
- if (RSTRING(c)->len > 1) {
+ if (RSTRING_LEN(c) > 1) {
rb_warn("IO#ungetc pushes back only one byte");
}
- cc = (unsigned char)RSTRING(c)->ptr[0];
+ cc = (unsigned char)RSTRING_PTR(c)[0];
}
if (io_ungetc(cc, fptr) == EOF && cc != EOF) {
rb_raise(rb_eIOError, "ungetc failed");
@@ -2427,7 +2425,7 @@ rb_io_syswrite(VALUE io, VALUE str)
rb_io_check_closed(fptr);
}
TRAP_BEG;
- n = write(fptr->fd, RSTRING(str)->ptr, RSTRING(str)->len);
+ n = write(fptr->fd, RSTRING_PTR(str), RSTRING_LEN(str));
TRAP_END;
if (n == -1) rb_sys_fail(fptr->path);
@@ -2481,22 +2479,21 @@ rb_io_sysread(int argc, VALUE *argv, VALUE io)
n = fptr->fd;
rb_thread_wait_fd(fptr->fd);
rb_io_check_closed(fptr);
- if (RSTRING(str)->len != ilen) {
+ if (RSTRING_LEN(str) != ilen) {
rb_raise(rb_eRuntimeError, "buffer string modified");
}
TRAP_BEG;
- n = read(fptr->fd, RSTRING(str)->ptr, ilen);
+ n = read(fptr->fd, RSTRING_PTR(str), ilen);
TRAP_END;
if (n == -1) {
rb_sys_fail(fptr->path);
}
- rb_str_resize(str, n);
+ rb_str_set_len(str, n);
if (n == 0 && ilen > 0) {
rb_eof_error();
}
- RSTRING(str)->len = n;
- RSTRING(str)->ptr[n] = '\0';
+ rb_str_resize(str, n);
OBJ_TAINT(str);
return str;
@@ -3209,15 +3206,15 @@ rb_open_file(int argc, VALUE *argv, VALUE io)
}
else {
SafeStringValue(vmode);
- flags = rb_io_mode_modenum(RSTRING(vmode)->ptr);
+ flags = rb_io_mode_modenum(RSTRING_PTR(vmode));
}
fmode = NIL_P(perm) ? 0666 : NUM2INT(perm);
- rb_file_sysopen_internal(io, RSTRING(fname)->ptr, flags, fmode);
+ rb_file_sysopen_internal(io, RSTRING_PTR(fname), flags, fmode);
}
else {
mode = NIL_P(vmode) ? "r" : StringValuePtr(vmode);
- rb_file_open_internal(io, RSTRING(fname)->ptr, mode);
+ rb_file_open_internal(io, RSTRING_PTR(fname), mode);
}
return io;
}
@@ -3272,13 +3269,13 @@ rb_io_s_sysopen(int argc, VALUE *argv)
else if (FIXNUM_P(vmode)) flags = FIX2INT(vmode);
else {
SafeStringValue(vmode);
- flags = rb_io_mode_modenum(RSTRING(vmode)->ptr);
+ flags = rb_io_mode_modenum(RSTRING_PTR(vmode));
}
if (NIL_P(perm)) fmode = 0666;
else fmode = NUM2INT(perm);
- path = ALLOCA_N(char, strlen(RSTRING(fname)->ptr)+1);
- strcpy(path, RSTRING(fname)->ptr);
+ path = ALLOCA_N(char, strlen(RSTRING_PTR(fname))+1);
+ strcpy(path, RSTRING_PTR(fname));
fd = rb_sysopen(path, flags, fmode);
return INT2NUM(fd);
}
@@ -3384,7 +3381,7 @@ rb_f_open(int argc, VALUE *argv)
if (!NIL_P(tmp)) {
char *str = StringValuePtr(tmp);
if (str && str[0] == '|') {
- argv[0] = rb_str_new(str+1, RSTRING(tmp)->len-1);
+ argv[0] = rb_str_new(str+1, RSTRING_LEN(tmp)-1);
OBJ_INFECT(argv[0], tmp);
return rb_io_s_popen(argc, argv, rb_cIO);
}
@@ -3550,7 +3547,7 @@ rb_io_reopen(int argc, VALUE *argv, VALUE file)
fptr->path = 0;
}
- fptr->path = strdup(RSTRING(fname)->ptr);
+ fptr->path = strdup(RSTRING_PTR(fname));
mode = rb_io_flags_mode(fptr->mode);
if (fptr->fd < 0) {
fptr->fd = rb_sysopen(fptr->path, rb_io_mode_modenum(mode), 0666);
@@ -3563,7 +3560,7 @@ rb_io_reopen(int argc, VALUE *argv, VALUE file)
}
if (fptr->stdio_file) {
- if (freopen(RSTRING(fname)->ptr, mode, fptr->stdio_file) == 0) {
+ if (freopen(RSTRING_PTR(fname), mode, fptr->stdio_file) == 0) {
rb_sys_fail(fptr->path);
}
fptr->fd = fileno(fptr->stdio_file);
@@ -3829,20 +3826,15 @@ rb_io_puts(int argc, VALUE *argv, VALUE out)
return Qnil;
}
for (i=0; i<argc; i++) {
- if (NIL_P(argv[i])) {
- line = rb_str_new2("nil");
- }
- else {
- line = rb_check_array_type(argv[i]);
- if (!NIL_P(line)) {
- rb_exec_recursive(io_puts_ary, line, out);
- continue;
- }
- line = rb_obj_as_string(argv[i]);
+ line = rb_check_array_type(argv[i]);
+ if (!NIL_P(line)) {
+ rb_exec_recursive(io_puts_ary, line, out);
+ continue;
}
+ line = rb_obj_as_string(argv[i]);
rb_io_write(out, line);
- if (RSTRING(line)->len == 0 ||
- RSTRING(line)->ptr[RSTRING(line)->len-1] != '\n') {
+ if (RSTRING_LEN(line) == 0 ||
+ RSTRING_PTR(line)[RSTRING_LEN(line)-1] != '\n') {
rb_io_write(out, rb_default_rs);
}
}
@@ -4066,7 +4058,7 @@ rb_io_initialize(int argc, VALUE *argv, VALUE io)
}
else {
SafeStringValue(mode);
- flags = rb_io_mode_modenum(RSTRING(mode)->ptr);
+ flags = rb_io_mode_modenum(RSTRING_PTR(mode));
}
}
orig = rb_io_check_io(fnum);
@@ -4101,7 +4093,7 @@ rb_io_initialize(int argc, VALUE *argv, VALUE io)
rb_raise(rb_eArgError, "incompatible mode 0%o", flags);
}
else {
- rb_raise(rb_eArgError, "incompatible mode \"%s\"", RSTRING(mode)->ptr);
+ rb_raise(rb_eArgError, "incompatible mode \"%s\"", RSTRING_PTR(mode));
}
}
}
@@ -4285,13 +4277,13 @@ next_argv(void)
#endif
#ifdef NO_SAFE_RENAME
(void)close(fr);
- (void)unlink(RSTRING(str)->ptr);
- (void)rename(fn, RSTRING(str)->ptr);
- fr = rb_sysopen(RSTRING(str)->ptr, O_RDONLY, 0);
+ (void)unlink(RSTRING_PTR(str));
+ (void)rename(fn, RSTRING_PTR(str));
+ fr = rb_sysopen(RSTRING_PTR(str), O_RDONLY, 0);
#else
- if (rename(fn, RSTRING(str)->ptr) < 0) {
+ if (rename(fn, RSTRING_PTR(str)) < 0) {
rb_warn("Can't rename %s to %s: %s, skipping file",
- fn, RSTRING(str)->ptr, strerror(errno));
+ fn, RSTRING_PTR(str), strerror(errno));
close(fr);
goto retry;
}
@@ -4782,20 +4774,20 @@ rb_io_ctl(VALUE io, VALUE req, VALUE arg, int io_p)
#endif
rb_str_modify(arg);
- if (len <= RSTRING(arg)->len) {
- len = RSTRING(arg)->len;
+ if (len <= RSTRING_LEN(arg)) {
+ len = RSTRING_LEN(arg);
}
- if (RSTRING(arg)->len < len) {
+ if (RSTRING_LEN(arg) < len) {
rb_str_resize(arg, len+1);
}
- RSTRING(arg)->ptr[len] = 17; /* a little sanity check here */
- narg = (long)RSTRING(arg)->ptr;
+ RSTRING_PTR(arg)[len] = 17; /* a little sanity check here */
+ narg = (long)RSTRING_PTR(arg);
}
}
GetOpenFile(io, fptr);
retval = io_cntl(fptr->fd, cmd, narg, io_p);
if (retval < 0) rb_sys_fail(fptr->path);
- if (TYPE(arg) == T_STRING && RSTRING(arg)->ptr[len] != 17) {
+ if (TYPE(arg) == T_STRING && RSTRING_PTR(arg)[len] != 17) {
rb_raise(rb_eArgError, "return value overflowed string");
}
@@ -4912,7 +4904,7 @@ rb_f_syscall(int argc, VALUE *argv)
if (!NIL_P(v)) {
StringValue(v);
rb_str_modify(v);
- arg[i] = (unsigned long)RSTRING(v)->ptr;
+ arg[i] = (unsigned long)RSTRING_PTR(v);
}
else {
arg[i] = (unsigned long)NUM2LONG(*argv);
@@ -5110,7 +5102,7 @@ rb_io_s_foreach(int argc, VALUE *argv, VALUE self)
else if (!NIL_P(arg.sep)) {
StringValue(arg.sep);
}
- arg.io = rb_io_open(RSTRING(fname)->ptr, "r");
+ arg.io = rb_io_open(RSTRING_PTR(fname), "r");
if (NIL_P(arg.io)) return Qnil;
return rb_ensure(io_s_foreach, (VALUE)&arg, rb_io_close, arg.io);
@@ -5144,7 +5136,7 @@ rb_io_s_readlines(int argc, VALUE *argv, VALUE io)
rb_scan_args(argc, argv, "11", &fname, &arg.sep);
FilePathValue(fname);
arg.argc = argc - 1;
- arg.io = rb_io_open(RSTRING(fname)->ptr, "r");
+ arg.io = rb_io_open(RSTRING_PTR(fname), "r");
if (NIL_P(arg.io)) return Qnil;
return rb_ensure(io_s_readlines, (VALUE)&arg, rb_io_close, arg.io);
}
@@ -5177,7 +5169,7 @@ rb_io_s_read(int argc, VALUE *argv, VALUE io)
rb_scan_args(argc, argv, "12", &fname, &arg.sep, &offset);
FilePathValue(fname);
arg.argc = argc ? 1 : 0;
- arg.io = rb_io_open(RSTRING(fname)->ptr, "r");
+ arg.io = rb_io_open(RSTRING_PTR(fname), "r");
if (NIL_P(arg.io)) return Qnil;
if (!NIL_P(offset)) {
rb_io_seek(arg.io, offset, SEEK_SET);
@@ -5292,8 +5284,8 @@ argf_read(int argc, VALUE *argv)
}
}
else if (argc >= 1) {
- if (RSTRING(str)->len < len) {
- len -= RSTRING(str)->len;
+ if (RSTRING_LEN(str) < len) {
+ len -= RSTRING_LEN(str);
argv[0] = INT2NUM(len);
goto retry;
}
@@ -5490,7 +5482,7 @@ opt_i_set(VALUE val)
StringValue(val);
if (ruby_inplace_mode) free(ruby_inplace_mode);
ruby_inplace_mode = 0;
- ruby_inplace_mode = strdup(RSTRING(val)->ptr);
+ ruby_inplace_mode = strdup(RSTRING_PTR(val));
}
/*
diff --git a/marshal.c b/marshal.c
index aa6a5943d8..2e69af00ed 100644
--- a/marshal.c
+++ b/marshal.c
@@ -100,7 +100,7 @@ static VALUE
class2path(VALUE klass)
{
VALUE path = rb_class_path(klass);
- char *n = RSTRING(path)->ptr;
+ char *n = RSTRING_PTR(path);
if (n[0] == '#') {
rb_raise(rb_eTypeError, "can't dump anonymous %s %s",
@@ -120,7 +120,7 @@ w_nbyte(const char *s, int n, struct dump_arg *arg)
{
VALUE buf = arg->str;
rb_str_buf_cat(buf, s, n);
- if (arg->dest && RSTRING(buf)->len >= BUFSIZ) {
+ if (arg->dest && RSTRING_LEN(buf) >= BUFSIZ) {
if (arg->taint) OBJ_TAINT(buf);
rb_io_write(arg->dest, buf);
rb_str_resize(buf, 0);
@@ -365,7 +365,7 @@ w_class(char type, VALUE obj, struct dump_arg *arg, int check)
VALUE klass = CLASS_OF(obj);
w_extended(klass, arg, check);
w_byte(type, arg);
- path = RSTRING(class2path(rb_class_real(klass)))->ptr;
+ path = RSTRING_PTR(class2path(rb_class_real(klass)));
w_unique(path, arg);
}
@@ -378,7 +378,7 @@ w_uclass(VALUE obj, VALUE base_klass, struct dump_arg *arg)
klass = rb_class_real(klass);
if (klass != base_klass) {
w_byte(TYPE_UCLASS, arg);
- w_unique(RSTRING(class2path(klass))->ptr, arg);
+ w_unique(RSTRING_PTR(class2path(klass)), arg);
}
}
@@ -476,7 +476,7 @@ w_object(VALUE obj, struct dump_arg *arg, int limit)
w_byte(TYPE_IVAR, arg);
}
w_class(TYPE_USERDEF, obj, arg, Qfalse);
- w_bytes(RSTRING(v)->ptr, RSTRING(v)->len, arg);
+ w_bytes(RSTRING_PTR(v), RSTRING_LEN(v), arg);
if (ivtbl) {
w_ivar(ivtbl, &c_arg);
}
@@ -491,7 +491,7 @@ w_object(VALUE obj, struct dump_arg *arg, int limit)
w_byte(TYPE_CLASS, arg);
{
VALUE path = class2path(obj);
- w_bytes(RSTRING(path)->ptr, RSTRING(path)->len, arg);
+ w_bytes(RSTRING_PTR(path), RSTRING_LEN(path), arg);
}
break;
@@ -499,7 +499,7 @@ w_object(VALUE obj, struct dump_arg *arg, int limit)
w_byte(TYPE_MODULE, arg);
{
VALUE path = class2path(obj);
- w_bytes(RSTRING(path)->ptr, RSTRING(path)->len, arg);
+ w_bytes(RSTRING_PTR(path), RSTRING_LEN(path), arg);
}
break;
@@ -538,7 +538,7 @@ w_object(VALUE obj, struct dump_arg *arg, int limit)
case T_STRING:
w_uclass(obj, rb_cString, arg);
w_byte(TYPE_STRING, arg);
- w_bytes(RSTRING(obj)->ptr, RSTRING(obj)->len, arg);
+ w_bytes(RSTRING_PTR(obj), RSTRING_LEN(obj), arg);
break;
case T_REGEXP:
@@ -746,8 +746,8 @@ r_byte(struct load_arg *arg)
int c;
if (TYPE(arg->src) == T_STRING) {
- if (RSTRING(arg->src)->len > arg->offset) {
- c = (unsigned char)RSTRING(arg->src)->ptr[arg->offset++];
+ if (RSTRING_LEN(arg->src) > arg->offset) {
+ c = (unsigned char)RSTRING_PTR(arg->src)[arg->offset++];
}
else {
rb_raise(rb_eArgError, "marshal data too short");
@@ -819,8 +819,8 @@ r_bytes0(long len, struct load_arg *arg)
if (len == 0) return rb_str_new(0, 0);
if (TYPE(arg->src) == T_STRING) {
- if (RSTRING(arg->src)->len > arg->offset) {
- str = rb_str_new(RSTRING(arg->src)->ptr+arg->offset, len);
+ if (RSTRING_LEN(arg->src) > arg->offset) {
+ str = rb_str_new(RSTRING_PTR(arg->src)+arg->offset, len);
arg->offset += len;
}
else {
@@ -834,7 +834,7 @@ r_bytes0(long len, struct load_arg *arg)
str = rb_funcall2(src, s_read, 1, &n);
if (NIL_P(str)) goto too_short;
StringValue(str);
- if (RSTRING(str)->len != len) goto too_short;
+ if (RSTRING_LEN(str) != len) goto too_short;
if (OBJ_TAINTED(str)) arg->taint = Qtrue;
}
return str;
@@ -856,8 +856,9 @@ static ID
r_symreal(struct load_arg *arg)
{
ID id;
+ volatile VALUE s = r_bytes(arg);
- id = rb_intern(RSTRING(r_bytes(arg))->ptr);
+ id = rb_intern(RSTRING_PTR(s));
st_insert(arg->symbols, arg->symbols->num_entries, id);
return id;
@@ -1013,7 +1014,7 @@ r_object0(struct load_arg *arg, VALUE proc, int *ivp, VALUE extmod)
{
double d, t = 0.0;
VALUE str = r_bytes(arg);
- const char *ptr = RSTRING(str)->ptr;
+ const char *ptr = RSTRING_PTR(str);
if (strcmp(ptr, "nan") == 0) {
d = t / t;
@@ -1027,7 +1028,7 @@ r_object0(struct load_arg *arg, VALUE proc, int *ivp, VALUE extmod)
else {
char *e;
d = strtod(ptr, &e);
- d = load_mantissa(d, e, RSTRING(str)->len - (e - ptr));
+ d = load_mantissa(d, e, RSTRING_LEN(str) - (e - ptr));
}
v = rb_float_new(d);
r_entry(v, arg);
@@ -1051,7 +1052,7 @@ r_object0(struct load_arg *arg, VALUE proc, int *ivp, VALUE extmod)
big->len = (len + 1) * 2 / sizeof(BDIGIT);
#endif
big->digits = digits = ALLOC_N(BDIGIT, big->len);
- MEMCPY(digits, RSTRING(data)->ptr, char, len * 2);
+ MEMCPY(digits, RSTRING_PTR(data), char, len * 2);
#if SIZEOF_BDIGITS > SIZEOF_SHORT
MEMZERO((char *)digits + len * 2, char,
big->len * sizeof(BDIGIT) - len * 2);
@@ -1087,7 +1088,7 @@ r_object0(struct load_arg *arg, VALUE proc, int *ivp, VALUE extmod)
{
volatile VALUE str = r_bytes(arg);
int options = r_byte(arg);
- v = r_entry(rb_reg_new(RSTRING(str)->ptr, RSTRING(str)->len, options), arg);
+ v = r_entry(rb_reg_new(RSTRING_PTR(str), RSTRING_LEN(str), options), arg);
}
break;
@@ -1240,7 +1241,7 @@ r_object0(struct load_arg *arg, VALUE proc, int *ivp, VALUE extmod)
{
volatile VALUE str = r_bytes(arg);
- v = rb_path2class(RSTRING(str)->ptr);
+ v = rb_path2class(RSTRING_PTR(str));
r_entry(v, arg);
}
break;
@@ -1249,7 +1250,7 @@ r_object0(struct load_arg *arg, VALUE proc, int *ivp, VALUE extmod)
{
volatile VALUE str = r_bytes(arg);
- v = path2class(RSTRING(str)->ptr);
+ v = path2class(RSTRING_PTR(str));
r_entry(v, arg);
}
break;
@@ -1258,7 +1259,7 @@ r_object0(struct load_arg *arg, VALUE proc, int *ivp, VALUE extmod)
{
volatile VALUE str = r_bytes(arg);
- v = path2module(RSTRING(str)->ptr);
+ v = path2module(RSTRING_PTR(str));
r_entry(v, arg);
}
break;
diff --git a/numeric.c b/numeric.c
index 255b6b52b4..a330cf0905 100644
--- a/numeric.c
+++ b/numeric.c
@@ -117,7 +117,7 @@ coerce_rescue(VALUE *x)
rb_raise(rb_eTypeError, "%s can't be coerced into %s",
rb_special_const_p(x[1])?
- RSTRING(v)->ptr:
+ RSTRING_PTR(v):
rb_obj_classname(x[1]),
rb_obj_classname(x[0]));
return Qnil; /* dummy */
diff --git a/object.c b/object.c
index a396da0913..d04cf0b4d8 100644
--- a/object.c
+++ b/object.c
@@ -272,8 +272,8 @@ inspect_i(ID id, VALUE value, VALUE str)
/* need not to show internal data */
if (CLASS_OF(value) == 0) return ST_CONTINUE;
if (!rb_is_instance_id(id)) return ST_CONTINUE;
- if (RSTRING(str)->ptr[0] == '-') { /* first element */
- RSTRING(str)->ptr[0] = '#';
+ if (RSTRING_PTR(str)[0] == '-') { /* first element */
+ RSTRING_PTR(str)[0] = '#';
rb_str_cat2(str, " ");
}
else {
@@ -299,7 +299,7 @@ inspect_obj(VALUE obj, VALUE str, int recur)
st_foreach_safe(ROBJECT(obj)->iv_tbl, inspect_i, str);
}
rb_str_cat2(str, ">");
- RSTRING(str)->ptr[0] = '#';
+ RSTRING_PTR(str)[0] = '#';
OBJ_INFECT(str, obj);
return str;
@@ -1009,11 +1009,11 @@ sym_inspect(VALUE sym)
name = rb_id2name(id);
str = rb_str_new(0, strlen(name)+1);
- RSTRING(str)->ptr[0] = ':';
- strcpy(RSTRING(str)->ptr+1, name);
+ RSTRING_PTR(str)[0] = ':';
+ strcpy(RSTRING_PTR(str)+1, name);
if (!rb_symname_p(name)) {
str = rb_str_dump(str);
- strncpy(RSTRING(str)->ptr, ":\"", 2);
+ strncpy(RSTRING_PTR(str), ":\"", 2);
}
return str;
}
@@ -1476,13 +1476,13 @@ rb_class_superclass(VALUE klass)
static ID
str_to_id(VALUE str)
{
- if (!RSTRING(str)->ptr || RSTRING(str)->len == 0) {
+ if (!RSTRING_PTR(str) || RSTRING_LEN(str) == 0) {
rb_raise(rb_eArgError, "empty symbol string");
}
- if (RSTRING(str)->len != strlen(RSTRING(str)->ptr)) {
+ if (RSTRING_LEN(str) != strlen(RSTRING_PTR(str))) {
rb_raise(rb_eArgError, "Symbols should not contain NUL (\\0)");
}
- return rb_intern(RSTRING(str)->ptr);
+ return rb_intern(RSTRING_PTR(str));
}
ID
@@ -1509,7 +1509,7 @@ rb_to_id(VALUE name)
if (!NIL_P(tmp)) {
return str_to_id(tmp);
}
- rb_raise(rb_eTypeError, "%s is not a symbol", RSTRING(rb_inspect(name))->ptr);
+ rb_raise(rb_eTypeError, "%s is not a symbol", RSTRING_PTR(rb_inspect(name)));
}
return id;
}
@@ -2112,8 +2112,8 @@ rb_str_to_dbl(VALUE str, int badcheck)
long len;
StringValue(str);
- s = RSTRING(str)->ptr;
- len = RSTRING(str)->len;
+ s = RSTRING_PTR(str);
+ len = RSTRING_LEN(str);
if (s) {
if (s[len]) { /* no sentinel somehow */
char *p = ALLOCA_N(char, len+1);
@@ -2204,11 +2204,11 @@ char*
rb_str2cstr(VALUE str, long *len)
{
StringValue(str);
- if (len) *len = RSTRING(str)->len;
- else if (RTEST(ruby_verbose) && RSTRING(str)->len != strlen(RSTRING(str)->ptr)) {
+ if (len) *len = RSTRING_LEN(str);
+ else if (RTEST(ruby_verbose) && RSTRING_LEN(str) != strlen(RSTRING_PTR(str))) {
rb_warn("string contains \\0 character");
}
- return RSTRING(str)->ptr;
+ return RSTRING_PTR(str);
}
VALUE
diff --git a/pack.c b/pack.c
index 8bdef7ce07..4a567ddce8 100644
--- a/pack.c
+++ b/pack.c
@@ -448,8 +448,8 @@ pack_pack(VALUE ary, VALUE fmt)
#endif
StringValue(fmt);
- p = RSTRING(fmt)->ptr;
- pend = p + RSTRING(fmt)->len;
+ p = RSTRING_PTR(fmt);
+ pend = p + RSTRING_LEN(fmt);
res = rb_str_buf_new(0);
items = RARRAY(ary)->len;
@@ -460,7 +460,7 @@ pack_pack(VALUE ary, VALUE fmt)
#define NEXTFROM (items-- > 0 ? RARRAY(ary)->ptr[idx++] : TOO_FEW)
while (p < pend) {
- if (RSTRING(fmt)->ptr + RSTRING(fmt)->len != pend) {
+ if (RSTRING_PTR(fmt) + RSTRING_LEN(fmt) != pend) {
rb_raise(rb_eRuntimeError, "format string modified");
}
type = *p++; /* get data type */
@@ -510,8 +510,8 @@ pack_pack(VALUE ary, VALUE fmt)
}
else {
StringValue(from);
- ptr = RSTRING(from)->ptr;
- plen = RSTRING(from)->len;
+ ptr = RSTRING_PTR(from);
+ plen = RSTRING_LEN(from);
OBJ_INFECT(res, from);
}
@@ -843,15 +843,14 @@ pack_pack(VALUE ary, VALUE fmt)
case 'X': /* back up byte */
shrink:
- plen = RSTRING(res)->len;
+ plen = RSTRING_LEN(res);
if (plen < len)
rb_raise(rb_eArgError, "X outside of string");
- RSTRING(res)->len = plen - len;
- RSTRING(res)->ptr[plen - len] = '\0';
+ rb_str_set_len(res, plen - len);
break;
case '@': /* null fill to absolute position */
- len -= RSTRING(res)->len;
+ len -= RSTRING_LEN(res);
if (len > 0) goto grow;
len = -len;
if (len > 0) goto shrink;
@@ -882,8 +881,8 @@ pack_pack(VALUE ary, VALUE fmt)
case 'm': /* base64 encoded string */
from = NEXTFROM;
StringValue(from);
- ptr = RSTRING(from)->ptr;
- plen = RSTRING(from)->len;
+ ptr = RSTRING_PTR(from);
+ plen = RSTRING_LEN(from);
if (len <= 2)
len = 45;
@@ -913,9 +912,9 @@ pack_pack(VALUE ary, VALUE fmt)
from = THISFROM;
if (!NIL_P(from)) {
StringValue(from);
- if (RSTRING(from)->len < len) {
+ if (RSTRING_LEN(from) < len) {
rb_raise(rb_eArgError, "too short buffer for P(%ld for %ld)",
- RSTRING(from)->len, len);
+ RSTRING_LEN(from), len);
}
}
len = 1;
@@ -970,16 +969,16 @@ pack_pack(VALUE ary, VALUE fmt)
ul >>= 7;
}
- if (RSTRING(buf)->len) {
- bufs = RSTRING(buf)->ptr;
- bufe = bufs + RSTRING(buf)->len - 1;
+ if (RSTRING_LEN(buf)) {
+ bufs = RSTRING_PTR(buf);
+ bufe = bufs + RSTRING_LEN(buf) - 1;
*bufs &= 0x7f; /* clear continue bit */
while (bufs < bufe) { /* reverse */
c = *bufs;
*bufs++ = *bufe;
*bufe-- = c;
}
- rb_str_buf_cat(res, RSTRING(buf)->ptr, RSTRING(buf)->len);
+ rb_str_buf_cat(res, RSTRING_PTR(buf), RSTRING_LEN(buf));
}
else {
c = 0;
@@ -1050,8 +1049,8 @@ qpencode(VALUE str, VALUE from, long len)
{
char buff[1024];
long i = 0, n = 0, prev = EOF;
- unsigned char *s = (unsigned char*)RSTRING(from)->ptr;
- unsigned char *send = s + RSTRING(from)->len;
+ unsigned char *s = (unsigned char*)RSTRING_PTR(from);
+ unsigned char *send = s + RSTRING_LEN(from);
while (s < send) {
if ((*s > 126) ||
@@ -1301,10 +1300,10 @@ pack_unpack(VALUE str, VALUE fmt)
StringValue(str);
StringValue(fmt);
- s = RSTRING(str)->ptr;
- send = s + RSTRING(str)->len;
- p = RSTRING(fmt)->ptr;
- pend = p + RSTRING(fmt)->len;
+ s = RSTRING_PTR(str);
+ send = s + RSTRING_LEN(str);
+ p = RSTRING_PTR(fmt);
+ pend = p + RSTRING_LEN(fmt);
ary = rb_ary_new();
while (p < pend) {
@@ -1398,7 +1397,7 @@ pack_unpack(VALUE str, VALUE fmt)
len = (send - s) * 8;
bits = 0;
rb_ary_push(ary, bitstr = rb_str_new(0, len));
- t = RSTRING(bitstr)->ptr;
+ t = RSTRING_PTR(bitstr);
for (i=0; i<len; i++) {
if (i & 7) bits >>= 1;
else bits = *s++;
@@ -1418,7 +1417,7 @@ pack_unpack(VALUE str, VALUE fmt)
len = (send - s) * 8;
bits = 0;
rb_ary_push(ary, bitstr = rb_str_new(0, len));
- t = RSTRING(bitstr)->ptr;
+ t = RSTRING_PTR(bitstr);
for (i=0; i<len; i++) {
if (i & 7) bits <<= 1;
else bits = *s++;
@@ -1438,7 +1437,7 @@ pack_unpack(VALUE str, VALUE fmt)
len = (send - s) * 2;
bits = 0;
rb_ary_push(ary, bitstr = rb_str_new(0, len));
- t = RSTRING(bitstr)->ptr;
+ t = RSTRING_PTR(bitstr);
for (i=0; i<len; i++) {
if (i & 1)
bits >>= 4;
@@ -1460,7 +1459,7 @@ pack_unpack(VALUE str, VALUE fmt)
len = (send - s) * 2;
bits = 0;
rb_ary_push(ary, bitstr = rb_str_new(0, len));
- t = RSTRING(bitstr)->ptr;
+ t = RSTRING_PTR(bitstr);
for (i=0; i<len; i++) {
if (i & 1)
bits <<= 4;
@@ -1714,7 +1713,7 @@ pack_unpack(VALUE str, VALUE fmt)
case 'u':
{
VALUE buf = infected_str_new(0, (send - s)*3/4, str);
- char *ptr = RSTRING(buf)->ptr;
+ char *ptr = RSTRING_PTR(buf);
long total = 0;
while (s < send && *s > ' ' && *s < 'a') {
@@ -1724,9 +1723,9 @@ pack_unpack(VALUE str, VALUE fmt)
hunk[3] = '\0';
len = (*s++ - ' ') & 077;
total += len;
- if (total > RSTRING(buf)->len) {
- len -= total - RSTRING(buf)->len;
- total = RSTRING(buf)->len;
+ if (total > RSTRING_LEN(buf)) {
+ len -= total - RSTRING_LEN(buf);
+ total = RSTRING_LEN(buf);
}
while (len > 0) {
@@ -1760,9 +1759,8 @@ pack_unpack(VALUE str, VALUE fmt)
else if (s < send && (s+1 == send || s[1] == '\n'))
s += 2; /* possible checksum byte */
}
-
- RSTRING(buf)->ptr[total] = '\0';
- RSTRING(buf)->len = total;
+
+ rb_str_set_len(buf, total);
rb_ary_push(ary, buf);
}
break;
@@ -1770,7 +1768,7 @@ pack_unpack(VALUE str, VALUE fmt)
case 'm':
{
VALUE buf = infected_str_new(0, (send - s)*3/4, str);
- char *ptr = RSTRING(buf)->ptr;
+ char *ptr = RSTRING_PTR(buf);
int a = -1,b = -1,c = 0,d;
static int first = 1;
static int b64_xtable[256];
@@ -1805,8 +1803,7 @@ pack_unpack(VALUE str, VALUE fmt)
*ptr++ = b << 4 | c >> 2;
}
}
- *ptr = '\0';
- RSTRING(buf)->len = ptr - RSTRING(buf)->ptr;
+ rb_str_set_len(buf, ptr - RSTRING_PTR(buf));
rb_ary_push(ary, buf);
}
break;
@@ -1814,7 +1811,7 @@ pack_unpack(VALUE str, VALUE fmt)
case 'M':
{
VALUE buf = infected_str_new(0, send - s, str);
- char *ptr = RSTRING(buf)->ptr;
+ char *ptr = RSTRING_PTR(buf);
int c1, c2;
while (s < send) {
@@ -1834,20 +1831,19 @@ pack_unpack(VALUE str, VALUE fmt)
}
s++;
}
- *ptr = '\0';
- RSTRING(buf)->len = ptr - RSTRING(buf)->ptr;
+ rb_str_set_len(buf, ptr - RSTRING_PTR(buf));
rb_ary_push(ary, buf);
}
break;
case '@':
- if (len > RSTRING(str)->len)
+ if (len > RSTRING_LEN(str))
rb_raise(rb_eArgError, "@ outside of string");
- s = RSTRING(str)->ptr + len;
+ s = RSTRING_PTR(str) + len;
break;
case 'X':
- if (len > s - RSTRING(str)->ptr)
+ if (len > s - RSTRING_PTR(str))
rb_raise(rb_eArgError, "X outside of string");
s -= len;
break;
@@ -1875,8 +1871,8 @@ pack_unpack(VALUE str, VALUE fmt)
p = RARRAY(a)->ptr;
pend = p + RARRAY(a)->len;
while (p < pend) {
- if (TYPE(*p) == T_STRING && RSTRING(*p)->ptr == t) {
- if (len < RSTRING(*p)->len) {
+ if (TYPE(*p) == T_STRING && RSTRING_PTR(*p) == t) {
+ if (len < RSTRING_LEN(*p)) {
tmp = rb_tainted_str_new(t, len);
rb_str_associate(tmp, a);
}
@@ -1920,7 +1916,7 @@ pack_unpack(VALUE str, VALUE fmt)
p = RARRAY(a)->ptr;
pend = p + RARRAY(a)->len;
while (p < pend) {
- if (TYPE(*p) == T_STRING && RSTRING(*p)->ptr == t) {
+ if (TYPE(*p) == T_STRING && RSTRING_PTR(*p) == t) {
tmp = *p;
break;
}
diff --git a/parse.y b/parse.y
index 7139ee6b42..49756f1902 100644
--- a/parse.y
+++ b/parse.y
@@ -3550,8 +3550,8 @@ regexp : tREGEXP_BEG xstring_contents tREGEXP_END
{
VALUE src = node->nd_lit;
nd_set_type(node, NODE_LIT);
- node->nd_lit = rb_reg_compile(RSTRING(src)->ptr,
- RSTRING(src)->len,
+ node->nd_lit = rb_reg_compile(RSTRING_PTR(src),
+ RSTRING_LEN(src),
options & ~RE_OPTION_ONCE);
}
break;
@@ -3792,12 +3792,12 @@ dsym : tSYMBEG xstring_contents tSTRING_END
break;
case NODE_STR:
lit = $$->nd_lit;
- if (RSTRING(lit)->len == 0) {
+ if (RSTRING_LEN(lit) == 0) {
yyerror("empty symbol literal");
break;
}
- if (strlen(RSTRING(lit)->ptr) == RSTRING(lit)->len) {
- $$->nd_lit = ID2SYM(rb_intern(RSTRING($$->nd_lit)->ptr));
+ if (strlen(RSTRING_PTR(lit)) == RSTRING_LEN(lit)) {
+ $$->nd_lit = ID2SYM(rb_intern(RSTRING_PTR($$->nd_lit)));
nd_set_type($$, NODE_LIT);
break;
}
@@ -4601,17 +4601,17 @@ lex_get_str(struct parser_params *parser, VALUE s)
{
char *beg, *end, *pend;
- beg = RSTRING(s)->ptr;
+ beg = RSTRING_PTR(s);
if (lex_gets_ptr) {
- if (RSTRING(s)->len == lex_gets_ptr) return Qnil;
+ if (RSTRING_LEN(s) == lex_gets_ptr) return Qnil;
beg += lex_gets_ptr;
}
- pend = RSTRING(s)->ptr + RSTRING(s)->len;
+ pend = RSTRING_PTR(s) + RSTRING_LEN(s);
end = beg;
while (end < pend) {
if (*end++ == '\n') break;
}
- lex_gets_ptr = end - RSTRING(s)->ptr;
+ lex_gets_ptr = end - RSTRING_PTR(s);
return rb_str_new(beg, end - beg);
}
@@ -4727,8 +4727,8 @@ parser_nextc(struct parser_params *parser)
}
ruby_sourceline++;
parser->line_count++;
- lex_pbeg = lex_p = RSTRING(v)->ptr;
- lex_pend = lex_p + RSTRING(v)->len;
+ lex_pbeg = lex_p = RSTRING_PTR(v);
+ lex_pend = lex_p + RSTRING_LEN(v);
#ifdef RIPPER
ripper_flush(parser);
#endif
@@ -5028,7 +5028,8 @@ enum string_type {
static void
dispose_string(VALUE str)
{
- xfree(RSTRING(str)->ptr);
+ if (RBASIC(str)->flags & RSTRING_NOEMBED)
+ xfree(RSTRING_PTR(str));
rb_gc_force_recycle(str);
}
@@ -5270,8 +5271,8 @@ parser_heredoc_restore(struct parser_params *parser, NODE *here)
#endif
line = here->nd_orig;
lex_lastline = line;
- lex_pbeg = RSTRING(line)->ptr;
- lex_pend = lex_pbeg + RSTRING(line)->len;
+ lex_pbeg = RSTRING_PTR(line);
+ lex_pend = lex_pbeg + RSTRING_LEN(line);
lex_p = lex_pbeg + here->nd_nth;
heredoc_end = ruby_sourceline;
ruby_sourceline = nd_line(here);
@@ -5306,8 +5307,8 @@ parser_here_document(struct parser_params *parser, NODE *here)
long len;
VALUE str = 0;
- eos = RSTRING(here->nd_lit)->ptr;
- len = RSTRING(here->nd_lit)->len - 1;
+ eos = RSTRING_PTR(here->nd_lit);
+ len = RSTRING_LEN(here->nd_lit) - 1;
indent = (func = *eos++) & STR_FUNC_INDENT;
if ((c = nextc()) == -1) {
@@ -5324,7 +5325,7 @@ parser_here_document(struct parser_params *parser, NODE *here)
if (!(func & STR_FUNC_EXPAND)) {
do {
- p = RSTRING(lex_lastline)->ptr;
+ p = RSTRING_PTR(lex_lastline);
pend = lex_pend;
if (pend > p) {
switch (pend[-1]) {
@@ -5469,7 +5470,7 @@ parser_pragma(struct parser_params *parser, const char *str, int len)
const char *beg, *end, *vbeg, *vend;
#define str_copy(_s, _p, _n) ((_s) \
? (rb_str_resize((_s), (_n)), \
- MEMCPY(RSTRING(_s)->ptr, (_p), char, (_n)), (_s)) \
+ MEMCPY(RSTRING_PTR(_s), (_p), char, (_n)), (_s)) \
: ((_s) = rb_str_new((_p), (_n))))
if (len <= 7) return Qfalse;
@@ -5532,9 +5533,9 @@ parser_pragma(struct parser_params *parser, const char *str, int len)
rb_funcall(name, rb_intern("downcase!"), 0);
#ifndef RIPPER
do {
- if (strncmp(p->name, RSTRING(name)->ptr, n) == 0) {
+ if (strncmp(p->name, RSTRING_PTR(name), n) == 0) {
str_copy(val, vbeg, vend - vbeg);
- (*p->func)(parser, RSTRING(name)->ptr, RSTRING(val)->ptr);
+ (*p->func)(parser, RSTRING_PTR(name), RSTRING_PTR(val));
break;
}
} while (++p < pragmas + sizeof(pragmas) / sizeof(*p));
@@ -9218,7 +9219,7 @@ ripper_assert_Qundef(VALUE self, VALUE obj, VALUE msg)
{
StringValue(msg);
if (obj == Qundef) {
- rb_raise(rb_eArgError, RSTRING(msg)->ptr);
+ rb_raise(rb_eArgError, RSTRING_PTR(msg));
}
return Qnil;
}
diff --git a/process.c b/process.c
index a07b0db4e0..ab8a9a3f70 100644
--- a/process.c
+++ b/process.c
@@ -974,7 +974,7 @@ rb_proc_exec_n(int argc, VALUE *argv, const char *prog)
args = ALLOCA_N(char*, argc+1);
for (i=0; i<argc; i++) {
- args[i] = RSTRING(argv[i])->ptr;
+ args[i] = RSTRING_PTR(argv[i]);
}
args[i] = 0;
if (args[0]) {
@@ -1177,7 +1177,7 @@ rb_check_argv(int argc, VALUE *argv)
for (i = 0; i < argc; i++) {
SafeStringValue(argv[i]);
}
- security(RSTRING(prog ? prog : argv[0])->ptr);
+ security(RSTRING_PTR(prog ? prog : argv[0]));
return prog;
}
@@ -1219,12 +1219,12 @@ rb_f_exec(int argc, VALUE *argv)
if (!prog && argc == 1) {
e.argc = 0;
e.argv = 0;
- e.prog = RSTRING(argv[0])->ptr;
+ e.prog = RSTRING_PTR(argv[0]);
}
else {
e.argc = argc;
e.argv = argv;
- e.prog = prog ? RSTRING(prog)->ptr : 0;
+ e.prog = prog ? RSTRING_PTR(prog) : 0;
}
rb_exec(&e);
rb_sys_fail(e.prog);
@@ -1533,7 +1533,7 @@ rb_spawn(int argc, VALUE *argv)
#if defined HAVE_FORK
earg.argc = argc;
earg.argv = argv;
- earg.prog = prog ? RSTRING(prog)->ptr : 0;
+ earg.prog = prog ? RSTRING_PTR(prog) : 0;
status = rb_fork(&status, (int (*)(void*))rb_exec, &earg);
if (prog && argc) argv[0] = prog;
#elif defined HAVE_SPAWNV
@@ -1598,7 +1598,7 @@ rb_f_system(int argc, VALUE *argv)
signal(SIGCHLD, chfunc);
#endif
if (status < 0) {
- rb_sys_fail(RSTRING(argv[0])->ptr);
+ rb_sys_fail(RSTRING_PTR(argv[0]));
}
status = NUM2INT(rb_last_status);
if (status == EXIT_SUCCESS) return Qtrue;
@@ -1619,7 +1619,7 @@ rb_f_spawn(int argc, VALUE *argv)
int pid;
pid = rb_spawn(argc, argv);
- if (pid == -1) rb_sys_fail(RSTRING(argv[0])->ptr);
+ if (pid == -1) rb_sys_fail(RSTRING_PTR(argv[0]));
#if defined(HAVE_FORK) || defined(HAVE_SPAWNV)
return INT2NUM(pid);
#else
@@ -2666,10 +2666,10 @@ proc_setgroups(VALUE obj, VALUE ary)
groups[i] = NUM2INT(g);
}
else {
- gr = getgrnam(RSTRING(tmp)->ptr);
+ gr = getgrnam(RSTRING_PTR(tmp));
if (gr == NULL)
rb_raise(rb_eArgError,
- "can't find group for %s", RSTRING(tmp)->ptr);
+ "can't find group for %s", RSTRING_PTR(tmp));
groups[i] = gr->gr_gid;
}
}
diff --git a/re.c b/re.c
index b3c4c1a49f..dd000140dd 100644
--- a/re.c
+++ b/re.c
@@ -597,9 +597,9 @@ rb_reg_raise(const char *s, long len, const char *err, VALUE re, int ce)
VALUE desc = rb_reg_desc(s, len, re);
if (ce)
- rb_compile_error("%s: %s", err, RSTRING(desc)->ptr);
+ rb_compile_error("%s: %s", err, RSTRING_PTR(desc));
else
- rb_raise(rb_eRegexpError, "%s: %s", err, RSTRING(desc)->ptr);
+ rb_raise(rb_eRegexpError, "%s: %s", err, RSTRING_PTR(desc));
}
@@ -949,13 +949,13 @@ rb_reg_adjust_startpos(VALUE re, VALUE str, long pos, long reverse)
range = -pos;
}
else {
- range = RSTRING(str)->len - pos;
+ range = RSTRING_LEN(str) - pos;
}
enc = (RREGEXP(re)->ptr)->enc;
- if (pos > 0 && ONIGENC_MBC_MAXLEN(enc) != 1 && pos < RSTRING(str)->len) {
- string = (UChar*)RSTRING(str)->ptr;
+ if (pos > 0 && ONIGENC_MBC_MAXLEN(enc) != 1 && pos < RSTRING_LEN(str)) {
+ string = (UChar*)RSTRING_PTR(str);
if (range > 0) {
p = onigenc_get_right_adjust_char_head(enc, string, string + pos);
@@ -977,7 +977,7 @@ rb_reg_search(VALUE re, VALUE str, long pos, long reverse)
static struct re_registers regs;
long range;
- if (pos > RSTRING(str)->len || pos < 0) {
+ if (pos > RSTRING_LEN(str) || pos < 0) {
rb_backref_set(Qnil);
return -1;
}
@@ -994,14 +994,14 @@ rb_reg_search(VALUE re, VALUE str, long pos, long reverse)
range = -pos;
}
else {
- range = RSTRING(str)->len - pos;
+ range = RSTRING_LEN(str) - pos;
}
result = onig_search(RREGEXP(re)->ptr,
- (UChar*)(RSTRING(str)->ptr),
- ((UChar*)(RSTRING(str)->ptr) + RSTRING(str)->len),
- ((UChar*)(RSTRING(str)->ptr) + pos),
- ((UChar*)(RSTRING(str)->ptr) + pos + range),
+ (UChar*)(RSTRING_PTR(str)),
+ ((UChar*)(RSTRING_PTR(str)) + RSTRING_LEN(str)),
+ ((UChar*)(RSTRING_PTR(str)) + pos),
+ ((UChar*)(RSTRING_PTR(str)) + pos + range),
&regs, ONIG_OPTION_NONE);
if (FL_TEST(re, KCODE_FIXED))
@@ -1130,7 +1130,7 @@ rb_reg_match_post(VALUE match)
if (RMATCH(match)->BEG(0) == -1) return Qnil;
str = RMATCH(match)->str;
pos = RMATCH(match)->END(0);
- str = rb_str_substr(str, pos, RSTRING(str)->len - pos);
+ str = rb_str_substr(str, pos, RSTRING_LEN(str) - pos);
if (OBJ_TAINTED(match)) OBJ_TAINT(str);
return str;
}
@@ -1509,15 +1509,15 @@ VALUE
rb_reg_regcomp(VALUE str)
{
volatile VALUE save_str = str;
- if (reg_cache && RREGEXP(reg_cache)->len == RSTRING(str)->len
+ if (reg_cache && RREGEXP(reg_cache)->len == RSTRING_LEN(str)
&& case_cache == ruby_ignorecase
&& kcode_cache == reg_kcode
- && memcmp(RREGEXP(reg_cache)->str, RSTRING(str)->ptr, RSTRING(str)->len) == 0)
+ && memcmp(RREGEXP(reg_cache)->str, RSTRING_PTR(str), RSTRING_LEN(str)) == 0)
return reg_cache;
case_cache = ruby_ignorecase;
kcode_cache = reg_kcode;
- return reg_cache = rb_reg_new(RSTRING(str)->ptr, RSTRING(str)->len,
+ return reg_cache = rb_reg_new(RSTRING_PTR(str), RSTRING_LEN(str),
ruby_ignorecase);
}
@@ -1595,7 +1595,7 @@ rb_reg_match_pos(VALUE re, VALUE str, long pos)
StringValue(str);
if (pos != 0) {
if (pos < 0) {
- pos += RSTRING(str)->len;
+ pos += RSTRING_LEN(str);
if (pos < 0) {
return Qnil;
}
@@ -1796,7 +1796,7 @@ rb_reg_initialize_m(int argc, VALUE *argv, VALUE self)
flags |= char_to_arg_kcode((int )kcode[0]);
}
s = StringValuePtr(argv[0]);
- len = RSTRING(argv[0])->len;
+ len = RSTRING_LEN(argv[0]);
}
rb_reg_initialize(self, s, len, flags, Qfalse);
return self;
@@ -1809,8 +1809,8 @@ rb_reg_quote(VALUE str)
VALUE tmp;
int c;
- s = RSTRING(str)->ptr;
- send = s + RSTRING(str)->len;
+ s = RSTRING_PTR(str);
+ send = s + RSTRING_LEN(str);
for (; s < send; s++) {
c = *s;
if (ismbchar(*s)) {
@@ -1834,11 +1834,11 @@ rb_reg_quote(VALUE str)
return str;
meta_found:
- tmp = rb_str_new(0, RSTRING(str)->len*2);
- t = RSTRING(tmp)->ptr;
+ tmp = rb_str_new(0, RSTRING_LEN(str)*2);
+ t = RSTRING_PTR(tmp);
/* copy upto metacharacter */
- memcpy(t, RSTRING(str)->ptr, s - RSTRING(str)->ptr);
- t += s - RSTRING(str)->ptr;
+ memcpy(t, RSTRING_PTR(str), s - RSTRING_PTR(str));
+ t += s - RSTRING_PTR(str);
for (; s < send; s++) {
c = *s;
@@ -1881,7 +1881,7 @@ rb_reg_quote(VALUE str)
}
*t++ = c;
}
- rb_str_resize(tmp, t - RSTRING(tmp)->ptr);
+ rb_str_resize(tmp, t - RSTRING_PTR(tmp));
OBJ_INFECT(tmp, str);
return tmp;
}
@@ -2003,7 +2003,7 @@ rb_reg_s_union(int argc, VALUE *argv)
str1 = rb_inspect(kcode_re);
str2 = rb_inspect(v);
rb_raise(rb_eArgError, "mixed kcode: %s and %s",
- RSTRING(str1)->ptr, RSTRING(str2)->ptr);
+ RSTRING_PTR(str1), RSTRING_PTR(str2));
}
}
v = rb_reg_to_s(v);
@@ -2062,8 +2062,8 @@ rb_reg_regsub(VALUE str, VALUE src, struct re_registers *regs, VALUE regexp)
int no;
- p = s = RSTRING(str)->ptr;
- e = s + RSTRING(str)->len;
+ p = s = RSTRING_PTR(str);
+ e = s + RSTRING_LEN(str);
while (s < e) {
char *ss = s;
@@ -2125,11 +2125,11 @@ rb_reg_regsub(VALUE str, VALUE src, struct re_registers *regs, VALUE regexp)
break;
case '`':
- rb_str_buf_cat(val, RSTRING(src)->ptr, BEG(0));
+ rb_str_buf_cat(val, RSTRING_PTR(src), BEG(0));
continue;
case '\'':
- rb_str_buf_cat(val, RSTRING(src)->ptr+END(0), RSTRING(src)->len-END(0));
+ rb_str_buf_cat(val, RSTRING_PTR(src)+END(0), RSTRING_LEN(src)-END(0));
continue;
case '+':
@@ -2150,7 +2150,7 @@ rb_reg_regsub(VALUE str, VALUE src, struct re_registers *regs, VALUE regexp)
if (no >= 0) {
if (no >= regs->num_regs) continue;
if (BEG(no) == -1) continue;
- rb_str_buf_cat(val, RSTRING(src)->ptr+BEG(no), END(no)-BEG(no));
+ rb_str_buf_cat(val, RSTRING_PTR(src)+BEG(no), END(no)-BEG(no));
}
}
diff --git a/ruby.c b/ruby.c
index 1fa10e1f00..4ce58abaab 100644
--- a/ruby.c
+++ b/ruby.c
@@ -217,7 +217,7 @@ ruby_incpush(const char *path)
static VALUE
expand_include_path(VALUE path)
{
- char *p = RSTRING(path)->ptr;
+ char *p = RSTRING_PTR(path);
if (!p) return path;
if (*p == '.' && p[1] == '/') return path;
return rb_file_expand_path(path, Qnil);
@@ -883,10 +883,10 @@ load_file(const char *fname, int script)
xflag = Qfalse;
while (!NIL_P(line = rb_io_gets(f))) {
line_start++;
- if (RSTRING(line)->len > 2
- && RSTRING(line)->ptr[0] == '#'
- && RSTRING(line)->ptr[1] == '!') {
- if ((p = strstr(RSTRING(line)->ptr, "ruby")) != 0) {
+ if (RSTRING_LEN(line) > 2
+ && RSTRING_PTR(line)[0] == '#'
+ && RSTRING_PTR(line)[1] == '!') {
+ if ((p = strstr(RSTRING_PTR(line), "ruby")) != 0) {
goto start_read;
}
}
@@ -901,13 +901,13 @@ load_file(const char *fname, int script)
line = rb_io_gets(f);
if (NIL_P(line)) return;
- if ((p = strstr(RSTRING(line)->ptr, "ruby")) == 0) {
+ if ((p = strstr(RSTRING_PTR(line), "ruby")) == 0) {
/* not ruby script, kick the program */
char **argv;
char *path;
- char *pend = RSTRING(line)->ptr + RSTRING(line)->len;
+ char *pend = RSTRING_PTR(line) + RSTRING_LEN(line);
- p = RSTRING(line)->ptr; /* skip `#!' */
+ p = RSTRING_PTR(line); /* skip `#!' */
if (pend[-1] == '\n') pend--; /* chomp line */
if (pend[-1] == '\r') pend--;
*pend = '\0';
@@ -935,9 +935,9 @@ load_file(const char *fname, int script)
start_read:
p += 4;
- RSTRING(line)->ptr[RSTRING(line)->len-1] = '\0';
- if (RSTRING(line)->ptr[RSTRING(line)->len-2] == '\r')
- RSTRING(line)->ptr[RSTRING(line)->len-2] = '\0';
+ RSTRING_PTR(line)[RSTRING_LEN(line)-1] = '\0';
+ if (RSTRING_PTR(line)[RSTRING_LEN(line)-2] == '\r')
+ RSTRING_PTR(line)[RSTRING_LEN(line)-2] = '\0';
if ((p = strstr(p, " -")) != 0) {
p++; /* skip space before `-' */
while (*p == '-') {
@@ -1032,14 +1032,14 @@ set_arg0(VALUE val, ID id)
if (origargv == 0) rb_raise(rb_eRuntimeError, "$0 not initialized");
StringValue(val);
- s = RSTRING(val)->ptr;
- i = RSTRING(val)->len;
+ s = RSTRING_PTR(val);
+ i = RSTRING_LEN(val);
#if defined(PSTAT_SETCMD)
if (i >= PST_CLEN) {
union pstun j;
j.pst_command = s;
i = PST_CLEN;
- RSTRING(val)->len = i;
+ RSTRING_LEN(val) = i;
*(s + i) = '\0';
pstat(PSTAT_SETCMD, j, PST_CLEN, 0, 0);
}
diff --git a/ruby.h b/ruby.h
index 48de854e75..e0025083e5 100644
--- a/ruby.h
+++ b/ruby.h
@@ -317,8 +317,8 @@ char *rb_str2cstr(VALUE,long*);
/* obsolete API - use StringValuePtr() */
#define STR2CSTR(x) rb_str2cstr((VALUE)(x),0)
-#define NUM2CHR(x) (((TYPE(x) == T_STRING)&&(RSTRING(x)->len>=1))?\
- RSTRING(x)->ptr[0]:(char)(NUM2INT(x)&0xff))
+#define NUM2CHR(x) (((TYPE(x) == T_STRING)&&(RSTRING_LEN(x)>=1))?\
+ RSTRING_PTR(x)[0]:(char)(NUM2INT(x)&0xff))
#define CHR2FIX(x) INT2FIX((long)((x)&0xff))
VALUE rb_newobj(void);
@@ -362,15 +362,33 @@ struct RFloat {
#define ELTS_SHARED FL_USER2
+#define RSTRING_EMBED_LEN_MAX ((sizeof(VALUE)*3)/sizeof(char)-1)
struct RString {
struct RBasic basic;
- long len;
- char *ptr;
union {
- long capa;
- VALUE shared;
- } aux;
+ struct {
+ long len;
+ char *ptr;
+ union {
+ long capa;
+ VALUE shared;
+ } aux;
+ } heap;
+ char ary[RSTRING_EMBED_LEN_MAX];
+ } as;
};
+#define RSTRING_NOEMBED FL_USER1
+#define RSTRING_EMBED_LEN_MASK (FL_USER2|FL_USER3|FL_USER4|FL_USER5)
+#define RSTRING_EMBED_LEN_SHIFT (FL_USHIFT+2)
+#define RSTRING_LEN(str) \
+ (!(RBASIC(str)->flags & RSTRING_NOEMBED) ? \
+ (long)((RBASIC(str)->flags >> RSTRING_EMBED_LEN_SHIFT) & \
+ (RSTRING_EMBED_LEN_MASK >> RSTRING_EMBED_LEN_SHIFT)) : \
+ RSTRING(str)->as.heap.len)
+#define RSTRING_PTR(str) \
+ (!(RBASIC(str)->flags & RSTRING_NOEMBED) ? \
+ RSTRING(str)->as.ary : \
+ RSTRING(str)->as.heap.ptr)
struct RArray {
struct RBasic basic;
@@ -446,8 +464,8 @@ struct RStruct {
#define RSTRUCT_EMBED_LEN_SHIFT (FL_USHIFT+1)
#define RSTRUCT_LEN(st) \
((RBASIC(st)->flags & RSTRUCT_EMBED_LEN_MASK) ? \
- (RBASIC(st)->flags >> RSTRUCT_EMBED_LEN_SHIFT) & \
- (RSTRUCT_EMBED_LEN_MASK >> RSTRUCT_EMBED_LEN_SHIFT) : \
+ (long)((RBASIC(st)->flags >> RSTRUCT_EMBED_LEN_SHIFT) & \
+ (RSTRUCT_EMBED_LEN_MASK >> RSTRUCT_EMBED_LEN_SHIFT)) : \
RSTRUCT(st)->as.heap.len)
#define RSTRUCT_PTR(st) \
((RBASIC(st)->flags & RSTRUCT_EMBED_LEN_MASK) ? \
@@ -499,6 +517,8 @@ struct RBignum {
#define FL_ABLE(x) (!SPECIAL_CONST_P(x) && BUILTIN_TYPE(x) != T_NODE)
#define FL_TEST(x,f) (FL_ABLE(x)?(RBASIC(x)->flags&(f)):0)
+#define FL_ANY(x,f) FL_TEST(x,f)
+#define FL_ALL(x,f) (FL_TEST(x,f) == (f))
#define FL_SET(x,f) do {if (FL_ABLE(x)) RBASIC(x)->flags |= (f);} while (0)
#define FL_UNSET(x,f) do {if (FL_ABLE(x)) RBASIC(x)->flags &= ~(f);} while (0)
#define FL_REVERSE(x,f) do {if (FL_ABLE(x)) RBASIC(x)->flags ^= (f);} while (0)
diff --git a/signal.c b/signal.c
index 8e76090487..1a46bac910 100644
--- a/signal.c
+++ b/signal.c
@@ -242,7 +242,7 @@ rb_f_kill(int argc, VALUE *argv)
goto str_signal;
case T_STRING:
- s = RSTRING(argv[0])->ptr;
+ s = RSTRING_PTR(argv[0]);
if (s[0] == '-') {
negative++;
s++;
@@ -263,7 +263,7 @@ rb_f_kill(int argc, VALUE *argv)
str = rb_check_string_type(argv[0]);
if (!NIL_P(str)) {
- s = RSTRING(str)->ptr;
+ s = RSTRING_PTR(str);
goto str_signal;
}
rb_raise(rb_eArgError, "bad signal type %s",
@@ -574,28 +574,28 @@ trap(struct trap_arg *arg)
command = rb_check_string_type(arg->cmd);
if (!NIL_P(command)) {
SafeStringValue(command); /* taint check */
- switch (RSTRING(command)->len) {
+ switch (RSTRING_LEN(command)) {
case 0:
func = SIG_IGN;
break;
case 7:
- if (strncmp(RSTRING(command)->ptr, "SIG_IGN", 7) == 0) {
+ if (strncmp(RSTRING_PTR(command), "SIG_IGN", 7) == 0) {
func = SIG_IGN;
}
- else if (strncmp(RSTRING(command)->ptr, "SIG_DFL", 7) == 0) {
+ else if (strncmp(RSTRING_PTR(command), "SIG_DFL", 7) == 0) {
func = SIG_DFL;
}
- else if (strncmp(RSTRING(command)->ptr, "DEFAULT", 7) == 0) {
+ else if (strncmp(RSTRING_PTR(command), "DEFAULT", 7) == 0) {
func = SIG_DFL;
}
break;
case 6:
- if (strncmp(RSTRING(command)->ptr, "IGNORE", 6) == 0) {
+ if (strncmp(RSTRING_PTR(command), "IGNORE", 6) == 0) {
func = SIG_IGN;
}
break;
case 4:
- if (strncmp(RSTRING(command)->ptr, "EXIT", 4) == 0) {
+ if (strncmp(RSTRING_PTR(command), "EXIT", 4) == 0) {
arg->cmd = Qundef;
}
break;
@@ -620,7 +620,7 @@ trap(struct trap_arg *arg)
goto str_signal;
case T_STRING:
- s = RSTRING(arg->sig)->ptr;
+ s = RSTRING_PTR(arg->sig);
str_signal:
if (strncmp("SIG", s, 3) == 0)
diff --git a/sprintf.c b/sprintf.c
index 4c5e56843c..585db5b718 100644
--- a/sprintf.c
+++ b/sprintf.c
@@ -85,7 +85,7 @@ sign_bits(int base, const char *p)
bsiz*=2;\
}\
rb_str_resize(result, bsiz);\
- buf = RSTRING(result)->ptr;\
+ buf = RSTRING_PTR(result);\
} while (0)
#define PUSH(s, l) do { \
@@ -268,12 +268,12 @@ rb_str_format(int argc, const VALUE *argv, VALUE fmt)
if (OBJ_TAINTED(fmt)) tainted = 1;
StringValue(fmt);
fmt = rb_str_new4(fmt);
- p = RSTRING(fmt)->ptr;
- end = p + RSTRING(fmt)->len;
+ p = RSTRING_PTR(fmt);
+ end = p + RSTRING_LEN(fmt);
blen = 0;
bsiz = 120;
result = rb_str_buf_new(bsiz);
- buf = RSTRING(result)->ptr;
+ buf = RSTRING_PTR(result);
for (; p < end; p++) {
const char *t;
@@ -404,10 +404,10 @@ rb_str_format(int argc, const VALUE *argv, VALUE fmt)
tmp = rb_check_string_type(val);
if (!NIL_P(tmp)) {
- if (RSTRING(tmp)->len != 1) {
+ if (RSTRING_LEN(tmp) != 1) {
rb_raise(rb_eArgError, "%%c requires a character");
}
- c = RSTRING(tmp)->ptr[0];
+ c = RSTRING_PTR(tmp)[0];
}
else {
c = NUM2INT(val) & 0xff;
@@ -431,7 +431,7 @@ rb_str_format(int argc, const VALUE *argv, VALUE fmt)
if (*p == 'p') arg = rb_inspect(arg);
str = rb_obj_as_string(arg);
if (OBJ_TAINTED(str)) tainted = 1;
- len = RSTRING(str)->len;
+ len = RSTRING_LEN(str);
if (flags&FPREC) {
if (prec < len) {
len = prec;
@@ -447,7 +447,7 @@ rb_str_format(int argc, const VALUE *argv, VALUE fmt)
buf[blen++] = ' ';
}
}
- memcpy(&buf[blen], RSTRING(str)->ptr, len);
+ memcpy(&buf[blen], RSTRING_PTR(str), len);
blen += len;
if (flags&FMINUS) {
while (width--) {
@@ -457,7 +457,7 @@ rb_str_format(int argc, const VALUE *argv, VALUE fmt)
break;
}
}
- PUSH(RSTRING(str)->ptr, len);
+ PUSH(RSTRING_PTR(str), len);
}
break;
@@ -606,7 +606,7 @@ rb_str_format(int argc, const VALUE *argv, VALUE fmt)
else {
if (sign) {
tmp = rb_big2str(val, base);
- s = RSTRING(tmp)->ptr;
+ s = RSTRING_PTR(tmp);
if (s[0] == '-') {
s++;
sc = '-';
@@ -628,14 +628,14 @@ rb_str_format(int argc, const VALUE *argv, VALUE fmt)
rb_big_2comp(val);
}
tmp1 = tmp = rb_big2str(val, base);
- s = RSTRING(tmp)->ptr;
+ s = RSTRING_PTR(tmp);
if (*s == '-') {
if (base == 10) {
rb_warning("negative number for %%u specifier");
}
remove_sign_bits(++s, base);
tmp = rb_str_new(0, 3+strlen(s));
- t = RSTRING(tmp)->ptr;
+ t = RSTRING_PTR(tmp);
if (!(flags&(FPREC|FZERO))) {
strcpy(t, "..");
t += 2;
@@ -649,7 +649,7 @@ rb_str_format(int argc, const VALUE *argv, VALUE fmt)
if (s[0] != '1') strcpy(t++, "1"); break;
}
strcpy(t, s);
- s = RSTRING(tmp)->ptr;
+ s = RSTRING_PTR(tmp);
}
}
}
@@ -864,7 +864,7 @@ ruby__sfvwrite(register rb_printf_buffer *fp, register struct __suio *uio)
VALUE result = (VALUE)fp->_bf._base;
char *buf = (char*)fp->_p;
size_t len, n;
- int blen = buf - RSTRING(result)->ptr, bsiz = fp->_w;
+ int blen = buf - RSTRING_PTR(result), bsiz = fp->_w;
if (RBASIC(result)->klass) {
rb_raise(rb_eRuntimeError, "rb_vsprintf reentered");
@@ -894,12 +894,12 @@ rb_vsprintf(const char *fmt, va_list ap)
f._w = 120;
result = rb_str_buf_new(f._w);
f._bf._base = (unsigned char *)result;
- f._p = (unsigned char *)RSTRING(result)->ptr;
+ f._p = (unsigned char *)RSTRING_PTR(result);
RBASIC(result)->klass = 0;
f.vwrite = ruby__sfvwrite;
BSD_vfprintf(&f, fmt, ap);
RBASIC(result)->klass = rb_cString;
- rb_str_resize(result, (char *)f._p - RSTRING(result)->ptr);
+ rb_str_resize(result, (char *)f._p - RSTRING_PTR(result));
return result;
}
diff --git a/string.c b/string.c
index f6eda3745b..d28b2da2e1 100644
--- a/string.c
+++ b/string.c
@@ -27,22 +27,78 @@
VALUE rb_cString;
-#define STR_TMPLOCK FL_USER1
+#define STR_TMPLOCK FL_USER7
+#define STR_NOEMBED FL_USER1
#define STR_ASSOC FL_USER3
-#define STR_NOCAPA (ELTS_SHARED|STR_ASSOC)
+#define STR_SHARED_P(s) FL_ALL(s, STR_NOEMBED|ELTS_SHARED)
+#define STR_ASSOC_P(s) FL_ALL(s, STR_NOEMBED|STR_ASSOC)
+#define STR_NOCAPA (STR_NOEMBED|ELTS_SHARED|STR_ASSOC)
+#define STR_NOCAPA_P(s) (FL_TEST(s,STR_NOEMBED) && FL_ANY(s,ELTS_SHARED|STR_ASSOC))
+#define STR_UNSET_NOCAPA(s) do {\
+ if (FL_TEST(s,STR_NOEMBED)) FL_UNSET(s,(ELTS_SHARED|STR_ASSOC));\
+} while (0)
+
+#define STR_SET_NOEMBED(str) do {\
+ FL_SET(str, STR_NOEMBED);\
+ STR_SET_EMBED_LEN(str, 0);\
+} while (0)
+#define STR_EMBED_P(str) (!FL_TEST(str, STR_NOEMBED))
+#define STR_SET_EMBED_LEN(str, n) do { \
+ long tmp_n = (n);\
+ RBASIC(str)->flags &= ~RSTRING_EMBED_LEN_MASK;\
+ RBASIC(str)->flags |= (tmp_n) << RSTRING_EMBED_LEN_SHIFT;\
+} while (0)
+
+#define STR_SET_LEN(str, n) do { \
+ if (STR_EMBED_P(str)) {\
+ STR_SET_EMBED_LEN(str, n);\
+ }\
+ else {\
+ RSTRING(str)->as.heap.len = (n);\
+ }\
+} while (0)
+
+#define STR_DEC_LEN(str) do {\
+ if (STR_EMBED_P(str)) {\
+ long n = RSTRING_LEN(str);\
+ n--;\
+ STR_SET_EMBED_LEN(str, n);\
+ }\
+ else {\
+ RSTRING(str)->as.heap.len--;\
+ }\
+} while (0)
+
#define RESIZE_CAPA(str,capacity) do {\
- REALLOC_N(RSTRING(str)->ptr, char, (capacity)+1);\
- if (!FL_TEST(str, STR_NOCAPA))\
- RSTRING(str)->aux.capa = (capacity);\
+ if (STR_EMBED_P(str)) {\
+ if ((capacity) > RSTRING_EMBED_LEN_MAX) {\
+ char *tmp = ALLOC_N(char, capacity+1);\
+ memcpy(tmp, RSTRING_PTR(str), RSTRING_LEN(str));\
+ RSTRING(str)->as.heap.ptr = tmp;\
+ RSTRING(str)->as.heap.len = RSTRING_LEN(str);\
+ STR_SET_NOEMBED(str);\
+ RSTRING(str)->as.heap.aux.capa = (capacity);\
+ }\
+ }\
+ else {\
+ REALLOC_N(RSTRING(str)->as.heap.ptr, char, (capacity)+1);\
+ if (!STR_NOCAPA_P(str))\
+ RSTRING(str)->as.heap.aux.capa = (capacity);\
+ }\
} while (0)
+char *
+rb_str_ptr(VALUE str) {
+ return RSTRING_PTR(str);
+}
+
VALUE rb_fs;
static inline void
str_mod_check(VALUE s, char *p, long len)
{
- if (RSTRING(s)->ptr != p || RSTRING(s)->len != len){
+ if (RSTRING_PTR(s) != p || RSTRING_LEN(s) != len){
rb_raise(rb_eRuntimeError, "string modified");
}
}
@@ -61,9 +117,9 @@ str_alloc(VALUE klass)
NEWOBJ(str, struct RString);
OBJSETUP(str, klass, T_STRING);
- str->ptr = 0;
- str->len = 0;
- str->aux.capa = 0;
+ str->as.heap.ptr = 0;
+ str->as.heap.len = 0;
+ str->as.heap.aux.capa = 0;
return (VALUE)str;
}
@@ -78,13 +134,16 @@ str_new(VALUE klass, const char *ptr, long len)
}
str = str_alloc(klass);
- RSTRING(str)->len = len;
- RSTRING(str)->aux.capa = len;
- RSTRING(str)->ptr = ALLOC_N(char,len+1);
+ if (len > RSTRING_EMBED_LEN_MAX) {
+ RSTRING(str)->as.heap.aux.capa = len;
+ RSTRING(str)->as.heap.ptr = ALLOC_N(char,len+1);
+ STR_SET_NOEMBED(str);
+ }
if (ptr) {
- memcpy(RSTRING(str)->ptr, ptr, len);
+ memcpy(RSTRING_PTR(str), ptr, len);
}
- RSTRING(str)->ptr[len] = '\0';
+ STR_SET_LEN(str, len);
+ RSTRING_PTR(str)[len] = '\0';
return str;
}
@@ -126,9 +185,10 @@ str_new3(VALUE klass, VALUE str)
{
VALUE str2 = str_alloc(klass);
- RSTRING(str2)->len = RSTRING(str)->len;
- RSTRING(str2)->ptr = RSTRING(str)->ptr;
- RSTRING(str2)->aux.shared = str;
+ FL_SET(str2, STR_NOEMBED);
+ RSTRING(str2)->as.heap.len = RSTRING_LEN(str);
+ RSTRING(str2)->as.heap.ptr = RSTRING_PTR(str);
+ RSTRING(str2)->as.heap.aux.shared = str;
FL_SET(str2, ELTS_SHARED);
OBJ_INFECT(str2, str);
@@ -144,19 +204,21 @@ rb_str_new3(VALUE str)
static VALUE
str_new4(VALUE klass, VALUE str)
{
- VALUE str2 = str_alloc(klass);
+ VALUE str2;
- RSTRING(str2)->len = RSTRING(str)->len;
- RSTRING(str2)->ptr = RSTRING(str)->ptr;
- if (FL_TEST(str, ELTS_SHARED)) {
+ str2 = str_alloc(klass);
+ STR_SET_NOEMBED(str2);
+ RSTRING(str2)->as.heap.len = RSTRING_LEN(str);
+ RSTRING(str2)->as.heap.ptr = RSTRING_PTR(str);
+ if (STR_SHARED_P(str)) {
FL_SET(str2, ELTS_SHARED);
- RSTRING(str2)->aux.shared = RSTRING(str)->aux.shared;
+ RSTRING(str2)->as.heap.aux.shared = RSTRING(str)->as.heap.aux.shared;
}
else {
FL_SET(str, ELTS_SHARED);
- RSTRING(str)->aux.shared = str2;
+ RSTRING(str)->as.heap.aux.shared = str2;
}
-
+ OBJ_INFECT(str2, str);
return str2;
}
@@ -167,17 +229,18 @@ rb_str_new4(VALUE orig)
if (OBJ_FROZEN(orig)) return orig;
klass = rb_obj_class(orig);
- if (FL_TEST(orig, ELTS_SHARED) && (str = RSTRING(orig)->aux.shared) && klass == RBASIC(str)->klass) {
+ if (STR_SHARED_P(orig) && (str = RSTRING(orig)->as.heap.aux.shared)
+ && klass == RBASIC(str)->klass) {
long ofs;
- ofs = RSTRING(str)->len - RSTRING(orig)->len;
+ ofs = RSTRING_LEN(str) - RSTRING_LEN(orig);
if (ofs > 0) {
str = str_new3(klass, str);
- RSTRING(str)->ptr += ofs;
- RSTRING(str)->len -= ofs;
+ RSTRING(str)->as.heap.ptr += ofs;
+ RSTRING(str)->as.heap.len -= ofs;
}
}
- else if (FL_TEST(orig, STR_ASSOC)) {
- str = str_new(klass, RSTRING(orig)->ptr, RSTRING(orig)->len);
+ else if (STR_ASSOC_P(orig) || STR_EMBED_P(orig)) {
+ str = str_new(klass, RSTRING_PTR(orig), RSTRING_LEN(orig));
}
else {
str = str_new4(klass, orig);
@@ -203,11 +266,10 @@ rb_str_buf_new(long capa)
if (capa < STR_BUF_MIN_SIZE) {
capa = STR_BUF_MIN_SIZE;
}
- RSTRING(str)->ptr = 0;
- RSTRING(str)->len = 0;
- RSTRING(str)->aux.capa = capa;
- RSTRING(str)->ptr = ALLOC_N(char, capa+1);
- RSTRING(str)->ptr[0] = '\0';
+ FL_SET(str, STR_NOEMBED);
+ RSTRING(str)->as.heap.aux.capa = capa;
+ RSTRING(str)->as.heap.ptr = ALLOC_N(char, capa+1);
+ RSTRING(str)->as.heap.ptr[0] = '\0';
return str;
}
@@ -235,22 +297,31 @@ rb_str_shared_replace(VALUE str, VALUE str2)
{
if (str == str2) return;
rb_str_modify(str);
- if (!FL_TEST(str, ELTS_SHARED)) free(RSTRING(str)->ptr);
- RSTRING(str)->ptr = RSTRING(str2)->ptr;
- RSTRING(str)->len = RSTRING(str2)->len;
- FL_UNSET(str, STR_NOCAPA);
- if (FL_TEST(str2, STR_NOCAPA)) {
+ if (OBJ_TAINTED(str2)) OBJ_TAINT(str);
+ if (RSTRING_LEN(str2) <= RSTRING_EMBED_LEN_MAX) {
+ FL_UNSET(str, STR_NOEMBED);
+ memcpy(RSTRING_PTR(str), RSTRING_PTR(str2), RSTRING_LEN(str2)+1);
+ STR_SET_EMBED_LEN(str, RSTRING_LEN(str2));
+ return;
+ }
+ STR_SET_NOEMBED(str);
+ if (!STR_SHARED_P(str) && !STR_EMBED_P(str)) {
+ free(RSTRING_PTR(str));
+ }
+ STR_UNSET_NOCAPA(str);
+ RSTRING(str)->as.heap.ptr = RSTRING_PTR(str2);
+ RSTRING(str)->as.heap.len = RSTRING_LEN(str2);
+ if (STR_NOCAPA_P(str2)) {
FL_SET(str, RBASIC(str2)->flags & STR_NOCAPA);
- RSTRING(str)->aux.shared = RSTRING(str2)->aux.shared;
+ RSTRING(str)->as.heap.aux.shared = RSTRING(str2)->as.heap.aux.shared;
}
else {
- RSTRING(str)->aux.capa = RSTRING(str2)->aux.capa;
+ RSTRING(str)->as.heap.aux.capa = RSTRING(str2)->as.heap.aux.capa;
}
- RSTRING(str2)->ptr = 0; /* abandon str2 */
- RSTRING(str2)->len = 0;
- RSTRING(str2)->aux.capa = 0;
- FL_UNSET(str2, STR_NOCAPA);
- if (OBJ_TAINTED(str2)) OBJ_TAINT(str);
+ RSTRING(str2)->as.heap.ptr = 0; /* abandon str2 */
+ RSTRING(str2)->as.heap.len = 0;
+ RSTRING(str2)->as.heap.aux.capa = 0;
+ STR_UNSET_NOCAPA(str2);
}
static ID id_to_s;
@@ -308,7 +379,8 @@ rb_str_init(int argc, VALUE *argv, VALUE str)
static VALUE
rb_str_length(VALUE str)
{
- return LONG2NUM(RSTRING(str)->len);
+ long len = RSTRING_LEN(str);
+ return LONG2NUM(len);
}
/*
@@ -324,7 +396,7 @@ rb_str_length(VALUE str)
static VALUE
rb_str_empty(VALUE str)
{
- if (RSTRING(str)->len == 0)
+ if (RSTRING_LEN(str) == 0)
return Qtrue;
return Qfalse;
}
@@ -345,11 +417,11 @@ rb_str_plus(VALUE str1, VALUE str2)
VALUE str3;
StringValue(str2);
- str3 = rb_str_new(0, RSTRING(str1)->len+RSTRING(str2)->len);
- memcpy(RSTRING(str3)->ptr, RSTRING(str1)->ptr, RSTRING(str1)->len);
- memcpy(RSTRING(str3)->ptr + RSTRING(str1)->len,
- RSTRING(str2)->ptr, RSTRING(str2)->len);
- RSTRING(str3)->ptr[RSTRING(str3)->len] = '\0';
+ str3 = rb_str_new(0, RSTRING_LEN(str1)+RSTRING_LEN(str2));
+ memcpy(RSTRING_PTR(str3), RSTRING_PTR(str1), RSTRING_LEN(str1));
+ memcpy(RSTRING_PTR(str3) + RSTRING_LEN(str1),
+ RSTRING_PTR(str2), RSTRING_LEN(str2));
+ RSTRING_PTR(str3)[RSTRING_LEN(str3)] = '\0';
if (OBJ_TAINTED(str1) || OBJ_TAINTED(str2))
OBJ_TAINT(str3);
@@ -376,16 +448,16 @@ rb_str_times(VALUE str, VALUE times)
if (len < 0) {
rb_raise(rb_eArgError, "negative argument");
}
- if (len && LONG_MAX/len < RSTRING(str)->len) {
+ if (len && LONG_MAX/len < RSTRING_LEN(str)) {
rb_raise(rb_eArgError, "argument too big");
}
- str2 = rb_str_new5(str,0, len *= RSTRING(str)->len);
- for (i = 0; i < len; i += RSTRING(str)->len) {
- memcpy(RSTRING(str2)->ptr + i,
- RSTRING(str)->ptr, RSTRING(str)->len);
+ str2 = rb_str_new5(str,0, len *= RSTRING_LEN(str));
+ for (i = 0; i < len; i += RSTRING_LEN(str)) {
+ memcpy(RSTRING_PTR(str2) + i,
+ RSTRING_PTR(str), RSTRING_LEN(str));
}
- RSTRING(str2)->ptr[RSTRING(str2)->len] = '\0';
+ RSTRING_PTR(str2)[RSTRING_LEN(str2)] = '\0';
OBJ_INFECT(str2, str);
@@ -424,7 +496,8 @@ str_independent(VALUE str)
if (OBJ_FROZEN(str)) rb_error_frozen("string");
if (!OBJ_TAINTED(str) && rb_safe_level() >= 4)
rb_raise(rb_eSecurityError, "Insecure: can't modify string");
- if (!FL_TEST(str, ELTS_SHARED)) return 1;
+ if (!STR_SHARED_P(str)) return 1;
+ if (STR_EMBED_P(str)) return 1;
return 0;
}
@@ -432,15 +505,17 @@ static void
str_make_independent(VALUE str)
{
char *ptr;
+ long len = RSTRING_LEN(str);
- ptr = ALLOC_N(char, RSTRING(str)->len+1);
- if (RSTRING(str)->ptr) {
- memcpy(ptr, RSTRING(str)->ptr, RSTRING(str)->len);
+ ptr = ALLOC_N(char, len+1);
+ if (RSTRING_PTR(str)) {
+ memcpy(ptr, RSTRING_PTR(str), len);
}
- ptr[RSTRING(str)->len] = 0;
- RSTRING(str)->ptr = ptr;
- RSTRING(str)->aux.capa = RSTRING(str)->len;
- FL_UNSET(str, STR_NOCAPA);
+ STR_SET_NOEMBED(str);
+ ptr[len] = 0;
+ RSTRING(str)->as.heap.ptr = ptr;
+ RSTRING(str)->as.heap.aux.capa = len;
+ STR_UNSET_NOCAPA(str);
}
void
@@ -453,33 +528,31 @@ rb_str_modify(VALUE str)
void
rb_str_associate(VALUE str, VALUE add)
{
- if (FL_TEST(str, STR_ASSOC)) {
+ if (STR_ASSOC_P(str)) {
/* already associated */
- rb_ary_concat(RSTRING(str)->aux.shared, add);
+ rb_ary_concat(RSTRING(str)->as.heap.aux.shared, add);
}
else {
- if (FL_TEST(str, ELTS_SHARED)) {
+ if (STR_SHARED_P(str) || STR_EMBED_P(str)) {
str_make_independent(str);
}
- else if (RSTRING(str)->aux.capa != RSTRING(str)->len) {
- RESIZE_CAPA(str, RSTRING(str)->len);
+ else if (RSTRING(str)->as.heap.aux.capa != RSTRING_LEN(str)) {
+ RESIZE_CAPA(str, RSTRING_LEN(str));
}
- RSTRING(str)->aux.shared = add;
FL_SET(str, STR_ASSOC);
+ RSTRING(str)->as.heap.aux.shared = add;
}
}
VALUE
rb_str_associated(VALUE str)
{
- if (FL_TEST(str, STR_ASSOC)) {
- return RSTRING(str)->aux.shared;
+ if (STR_ASSOC_P(str)) {
+ return RSTRING(str)->as.heap.aux.shared;
}
return Qfalse;
}
-static char *null_str = "";
-
VALUE
rb_string_value(volatile VALUE *ptr)
{
@@ -488,26 +561,22 @@ rb_string_value(volatile VALUE *ptr)
s = rb_str_to_str(s);
*ptr = s;
}
- if (!RSTRING(s)->ptr) {
- FL_SET(s, ELTS_SHARED);
- RSTRING(s)->ptr = null_str;
- }
return s;
}
char *
rb_string_value_ptr(volatile VALUE *ptr)
{
- return RSTRING(rb_string_value(ptr))->ptr;
+ return RSTRING_PTR(rb_string_value(ptr));
}
char *
rb_string_value_cstr(volatile VALUE *ptr)
{
VALUE str = rb_string_value(ptr);
- char *s = RSTRING(str)->ptr;
+ char *s = RSTRING_PTR(str);
- if (!s || RSTRING(str)->len != strlen(s)) {
+ if (!s || RSTRING_LEN(str) != strlen(s)) {
rb_raise(rb_eArgError, "string contains null byte");
}
return s;
@@ -517,10 +586,6 @@ VALUE
rb_check_string_type(VALUE str)
{
str = rb_check_convert_type(str, T_STRING, "String", "to_str");
- if (!NIL_P(str) && !RSTRING(str)->ptr) {
- FL_SET(str, ELTS_SHARED);
- RSTRING(str)->ptr = null_str;
- }
return str;
}
@@ -530,13 +595,13 @@ rb_str_substr(VALUE str, long beg, long len)
VALUE str2;
if (len < 0) return Qnil;
- if (beg > RSTRING(str)->len) return Qnil;
+ if (beg > RSTRING_LEN(str)) return Qnil;
if (beg < 0) {
- beg += RSTRING(str)->len;
+ beg += RSTRING_LEN(str);
if (beg < 0) return Qnil;
}
- if (beg + len > RSTRING(str)->len) {
- len = RSTRING(str)->len - beg;
+ if (beg + len > RSTRING_LEN(str)) {
+ len = RSTRING_LEN(str) - beg;
}
if (len < 0) {
len = 0;
@@ -544,14 +609,14 @@ rb_str_substr(VALUE str, long beg, long len)
if (len == 0) {
str2 = rb_str_new5(str,0,0);
}
- else if (len > sizeof(struct RString)/2 &&
- beg + len == RSTRING(str)->len && !FL_TEST(str, STR_ASSOC)) {
+ else if (len > RSTRING_EMBED_LEN_MAX &&
+ beg + len == RSTRING_LEN(str) && !STR_ASSOC_P(str)) {
str2 = rb_str_new3(rb_str_new4(str));
- RSTRING(str2)->ptr += RSTRING(str2)->len - len;
- RSTRING(str2)->len = len;
+ RSTRING(str2)->as.heap.ptr += RSTRING_LEN(str2) - len;
+ RSTRING(str2)->as.heap.len = len;
}
else {
- str2 = rb_str_new5(str, RSTRING(str)->ptr+beg, len);
+ str2 = rb_str_new5(str, RSTRING_PTR(str)+beg, len);
}
OBJ_INFECT(str2, str);
@@ -567,9 +632,9 @@ rb_str_freeze(VALUE str)
VALUE
rb_str_dup_frozen(VALUE str)
{
- if (FL_TEST(str, ELTS_SHARED) && RSTRING(str)->aux.shared) {
- VALUE shared = RSTRING(str)->aux.shared;
- if (RSTRING(shared)->len == RSTRING(str)->len) {
+ if (STR_SHARED_P(str) && RSTRING(str)->as.heap.aux.shared) {
+ VALUE shared = RSTRING(str)->as.heap.aux.shared;
+ if (RSTRING_LEN(shared) == RSTRING_LEN(str)) {
OBJ_FREEZE(shared);
return shared;
}
@@ -600,6 +665,13 @@ rb_str_unlocktmp(VALUE str)
return str;
}
+void
+rb_str_set_len(VALUE str, long len)
+{
+ STR_SET_LEN(str, len);
+ RSTRING_PTR(str)[len] = '\0';
+}
+
VALUE
rb_str_resize(VALUE str, long len)
{
@@ -608,15 +680,24 @@ rb_str_resize(VALUE str, long len)
}
rb_str_modify(str);
- if (len != RSTRING(str)->len) {
- if (RSTRING(str)->len < len || RSTRING(str)->len - len > 1024) {
- REALLOC_N(RSTRING(str)->ptr, char, len+1);
- if (!FL_TEST(str, STR_NOCAPA)) {
- RSTRING(str)->aux.capa = len;
+ if (len != RSTRING_LEN(str)) {
+ if (STR_EMBED_P(str)) {
+ if (len <= RSTRING_EMBED_LEN_MAX) {
+ STR_SET_EMBED_LEN(str, len);
+ RSTRING_PTR(str)[len] = '\0';
+ return str;
}
+ RSTRING(str)->as.heap.ptr = ALLOC_N(char,len+1);
+ STR_SET_NOEMBED(str);
+ }
+ else if (RSTRING_LEN(str) < len || RSTRING_LEN(str) - len > 1024) {
+ REALLOC_N(RSTRING(str)->as.heap.ptr, char, len+1);
+ }
+ if (!STR_NOCAPA_P(str)) {
+ RSTRING(str)->as.heap.aux.capa = len;
}
- RSTRING(str)->len = len;
- RSTRING(str)->ptr[len] = '\0'; /* sentinel */
+ RSTRING(str)->as.heap.len = len;
+ RSTRING(str)->as.heap.ptr[len] = '\0'; /* sentinel */
}
return str;
}
@@ -631,23 +712,26 @@ rb_str_buf_cat(VALUE str, const char *ptr, long len)
rb_raise(rb_eArgError, "negative string size (or size too big)");
}
rb_str_modify(str);
- if (FL_TEST(str, STR_ASSOC)) {
+ if (STR_ASSOC_P(str)) {
FL_UNSET(str, STR_ASSOC);
- capa = RSTRING(str)->aux.capa = RSTRING(str)->len;
+ capa = RSTRING(str)->as.heap.aux.capa = RSTRING_LEN(str);
+ }
+ else if (STR_EMBED_P(str)) {
+ capa = RSTRING_EMBED_LEN_MAX;
}
else {
- capa = RSTRING(str)->aux.capa;
+ capa = RSTRING(str)->as.heap.aux.capa;
}
- total = RSTRING(str)->len+len;
+ total = RSTRING_LEN(str)+len;
if (capa <= total) {
while (total > capa) {
capa = (capa + 1) * 2;
}
RESIZE_CAPA(str, capa);
}
- memcpy(RSTRING(str)->ptr + RSTRING(str)->len, ptr, len);
- RSTRING(str)->len = total;
- RSTRING(str)->ptr[total] = '\0'; /* sentinel */
+ memcpy(RSTRING_PTR(str) + RSTRING_LEN(str), ptr, len);
+ STR_SET_LEN(str, total);
+ RSTRING_PTR(str)[total] = '\0'; /* sentinel */
return str;
}
@@ -664,12 +748,13 @@ rb_str_cat(VALUE str, const char *ptr, long len)
if (len < 0) {
rb_raise(rb_eArgError, "negative string size (or size too big)");
}
- if (FL_TEST(str, STR_ASSOC)) {
+ if (STR_ASSOC_P(str)) {
rb_str_modify(str);
- REALLOC_N(RSTRING(str)->ptr, char, RSTRING(str)->len+len);
- memcpy(RSTRING(str)->ptr + RSTRING(str)->len, ptr, len);
- RSTRING(str)->len += len;
- RSTRING(str)->ptr[RSTRING(str)->len] = '\0'; /* sentinel */
+ if (STR_EMBED_P(str)) str_make_independent(str);
+ REALLOC_N(RSTRING(str)->as.heap.ptr, char, RSTRING(str)->as.heap.len+len);
+ memcpy(RSTRING(str)->as.heap.ptr + RSTRING(str)->as.heap.len, ptr, len);
+ RSTRING(str)->as.heap.len += len;
+ RSTRING(str)->as.heap.ptr[RSTRING(str)->as.heap.len] = '\0'; /* sentinel */
return str;
}
@@ -688,24 +773,26 @@ rb_str_buf_append(VALUE str, VALUE str2)
long capa, len;
rb_str_modify(str);
- if (FL_TEST(str, STR_ASSOC)) {
+ if (STR_ASSOC_P(str)) {
FL_UNSET(str, STR_ASSOC);
- capa = RSTRING(str)->aux.capa = RSTRING(str)->len;
+ capa = RSTRING(str)->as.heap.aux.capa = RSTRING_LEN(str);
+ }
+ else if (STR_EMBED_P(str)) {
+ capa = RSTRING_EMBED_LEN_MAX;
}
else {
- capa = RSTRING(str)->aux.capa;
+ capa = RSTRING(str)->as.heap.aux.capa;
}
- len = RSTRING(str)->len+RSTRING(str2)->len;
+ len = RSTRING_LEN(str)+RSTRING_LEN(str2);
if (capa <= len) {
while (len > capa) {
capa = (capa + 1) * 2;
}
RESIZE_CAPA(str, capa);
}
- memcpy(RSTRING(str)->ptr + RSTRING(str)->len,
- RSTRING(str2)->ptr, RSTRING(str2)->len);
- RSTRING(str)->len += RSTRING(str2)->len;
- RSTRING(str)->ptr[RSTRING(str)->len] = '\0'; /* sentinel */
+ memcpy(RSTRING_PTR(str) + RSTRING_LEN(str),
+ RSTRING_PTR(str2), RSTRING_LEN(str2)+1);
+ STR_SET_LEN(str, len);
OBJ_INFECT(str, str2);
return str;
@@ -716,14 +803,13 @@ rb_str_append(VALUE str, VALUE str2)
{
StringValue(str2);
rb_str_modify(str);
- if (RSTRING(str2)->len > 0) {
- if (FL_TEST(str, STR_ASSOC)) {
- long len = RSTRING(str)->len+RSTRING(str2)->len;
- REALLOC_N(RSTRING(str)->ptr, char, len+1);
- memcpy(RSTRING(str)->ptr + RSTRING(str)->len,
- RSTRING(str2)->ptr, RSTRING(str2)->len);
- RSTRING(str)->ptr[len] = '\0'; /* sentinel */
- RSTRING(str)->len = len;
+ if (RSTRING_LEN(str2) > 0) {
+ if (STR_ASSOC_P(str)) {
+ long len = RSTRING_LEN(str)+RSTRING_LEN(str2);
+ REALLOC_N(RSTRING(str)->as.heap.ptr, char, len+1);
+ memcpy(RSTRING(str)->as.heap.ptr + RSTRING(str)->as.heap.len,
+ RSTRING_PTR(str2), RSTRING_LEN(str2)+1);
+ RSTRING(str)->as.heap.len = len;
}
else {
return rb_str_buf_append(str, str2);
@@ -760,9 +846,7 @@ rb_str_concat(VALUE str1, VALUE str2)
return rb_str_cat(str1, &c, 1);
}
}
- str1 = rb_str_append(str1, str2);
-
- return str1;
+ return rb_str_append(str1, str2);
}
/*
@@ -866,7 +950,7 @@ rb_memhash(const void *ptr, long len)
int
rb_str_hash(VALUE str)
{
- return rb_memhash(RSTRING(str)->ptr, RSTRING(str)->len);
+ return rb_memhash(RSTRING_PTR(str), RSTRING_LEN(str));
}
/*
@@ -891,11 +975,11 @@ rb_str_cmp(VALUE str1, VALUE str2)
long len;
int retval;
- len = lesser(RSTRING(str1)->len, RSTRING(str2)->len);
- retval = rb_memcmp(RSTRING(str1)->ptr, RSTRING(str2)->ptr, len);
+ len = lesser(RSTRING_LEN(str1), RSTRING_LEN(str2));
+ retval = rb_memcmp(RSTRING_PTR(str1), RSTRING_PTR(str2), len);
if (retval == 0) {
- if (RSTRING(str1)->len == RSTRING(str2)->len) return 0;
- if (RSTRING(str1)->len > RSTRING(str2)->len) return 1;
+ if (RSTRING_LEN(str1) == RSTRING_LEN(str2)) return 0;
+ if (RSTRING_LEN(str1) > RSTRING_LEN(str2)) return 1;
return -1;
}
if (retval > 0) return 1;
@@ -922,7 +1006,7 @@ rb_str_equal(VALUE str1, VALUE str2)
}
return rb_equal(str2, str1);
}
- if (RSTRING(str1)->len == RSTRING(str2)->len &&
+ if (RSTRING_LEN(str1) == RSTRING_LEN(str2) &&
rb_str_cmp(str1, str2) == 0) {
return Qtrue;
}
@@ -939,11 +1023,11 @@ rb_str_equal(VALUE str1, VALUE str2)
static VALUE
rb_str_eql(VALUE str1, VALUE str2)
{
- if (TYPE(str2) != T_STRING || RSTRING(str1)->len != RSTRING(str2)->len)
+ if (TYPE(str2) != T_STRING || RSTRING_LEN(str1) != RSTRING_LEN(str2))
return Qfalse;
- if (memcmp(RSTRING(str1)->ptr, RSTRING(str2)->ptr,
- lesser(RSTRING(str1)->len, RSTRING(str2)->len)) == 0)
+ if (memcmp(RSTRING_PTR(str1), RSTRING_PTR(str2),
+ lesser(RSTRING_LEN(str1), RSTRING_LEN(str2))) == 0)
return Qtrue;
return Qfalse;
@@ -1021,11 +1105,11 @@ rb_str_casecmp(VALUE str1, VALUE str2)
int retval;
StringValue(str2);
- len = lesser(RSTRING(str1)->len, RSTRING(str2)->len);
- retval = rb_memcicmp(RSTRING(str1)->ptr, RSTRING(str2)->ptr, len);
+ len = lesser(RSTRING_LEN(str1), RSTRING_LEN(str2));
+ retval = rb_memcicmp(RSTRING_PTR(str1), RSTRING_PTR(str2), len);
if (retval == 0) {
- if (RSTRING(str1)->len == RSTRING(str2)->len) return INT2FIX(0);
- if (RSTRING(str1)->len > RSTRING(str2)->len) return INT2FIX(1);
+ if (RSTRING_LEN(str1) == RSTRING_LEN(str2)) return INT2FIX(0);
+ if (RSTRING_LEN(str1) > RSTRING_LEN(str2)) return INT2FIX(1);
return INT2FIX(-1);
}
if (retval == 0) return INT2FIX(0);
@@ -1039,13 +1123,13 @@ rb_str_index(VALUE str, VALUE sub, long offset)
long pos;
if (offset < 0) {
- offset += RSTRING(str)->len;
+ offset += RSTRING_LEN(str);
if (offset < 0) return -1;
}
- if (RSTRING(str)->len - offset < RSTRING(sub)->len) return -1;
- if (RSTRING(sub)->len == 0) return offset;
- pos = rb_memsearch(RSTRING(sub)->ptr, RSTRING(sub)->len,
- RSTRING(str)->ptr+offset, RSTRING(str)->len-offset);
+ if (RSTRING_LEN(str) - offset < RSTRING_LEN(sub)) return -1;
+ if (RSTRING_LEN(sub) == 0) return offset;
+ pos = rb_memsearch(RSTRING_PTR(sub), RSTRING_LEN(sub),
+ RSTRING_PTR(str)+offset, RSTRING_LEN(str)-offset);
if (pos < 0) return pos;
return pos + offset;
}
@@ -1083,7 +1167,7 @@ rb_str_index_m(int argc, VALUE *argv, VALUE str)
pos = 0;
}
if (pos < 0) {
- pos += RSTRING(str)->len;
+ pos += RSTRING_LEN(str);
if (pos < 0) {
if (TYPE(sub) == T_REGEXP) {
rb_backref_set(Qnil);
@@ -1101,8 +1185,8 @@ rb_str_index_m(int argc, VALUE *argv, VALUE str)
case T_FIXNUM:
{
int c = FIX2INT(sub);
- long len = RSTRING(str)->len;
- char *p = RSTRING(str)->ptr;
+ long len = RSTRING_LEN(str);
+ char *p = RSTRING_PTR(str);
for (;pos<len;pos++) {
if ((unsigned char)p[pos] == c) return LONG2NUM(pos);
@@ -1133,21 +1217,21 @@ rb_str_index_m(int argc, VALUE *argv, VALUE str)
static long
rb_str_rindex(VALUE str, VALUE sub, long pos)
{
- long len = RSTRING(sub)->len;
+ long len = RSTRING_LEN(sub);
char *s, *sbeg, *t;
/* substring longer than string */
- if (RSTRING(str)->len < len) return -1;
- if (RSTRING(str)->len - pos < len) {
- pos = RSTRING(str)->len - len;
+ if (RSTRING_LEN(str) < len) return -1;
+ if (RSTRING_LEN(str) - pos < len) {
+ pos = RSTRING_LEN(str) - len;
}
- sbeg = RSTRING(str)->ptr;
- s = RSTRING(str)->ptr + pos;
- t = RSTRING(sub)->ptr;
+ sbeg = RSTRING_PTR(str);
+ s = RSTRING_PTR(str) + pos;
+ t = RSTRING_PTR(sub);
if (len) {
while (sbeg <= s) {
if (rb_memcmp(s, t, len) == 0) {
- return s - RSTRING(str)->ptr;
+ return s - RSTRING_PTR(str);
}
s--;
}
@@ -1188,7 +1272,7 @@ rb_str_rindex_m(int argc, VALUE *argv, VALUE str)
if (rb_scan_args(argc, argv, "11", &sub, &position) == 2) {
pos = NUM2LONG(position);
if (pos < 0) {
- pos += RSTRING(str)->len;
+ pos += RSTRING_LEN(str);
if (pos < 0) {
if (TYPE(sub) == T_REGEXP) {
rb_backref_set(Qnil);
@@ -1196,10 +1280,10 @@ rb_str_rindex_m(int argc, VALUE *argv, VALUE str)
return Qnil;
}
}
- if (pos > RSTRING(str)->len) pos = RSTRING(str)->len;
+ if (pos > RSTRING_LEN(str)) pos = RSTRING_LEN(str);
}
else {
- pos = RSTRING(str)->len;
+ pos = RSTRING_LEN(str);
}
switch (TYPE(sub)) {
@@ -1219,16 +1303,16 @@ rb_str_rindex_m(int argc, VALUE *argv, VALUE str)
case T_FIXNUM:
{
int c = FIX2INT(sub);
- char *p = RSTRING(str)->ptr + pos;
- char *pbeg = RSTRING(str)->ptr;
+ char *p = RSTRING_PTR(str) + pos;
+ char *pbeg = RSTRING_PTR(str);
- if (pos == RSTRING(str)->len) {
+ if (pos == RSTRING_LEN(str)) {
if (pos == 0) return Qnil;
--p;
}
while (pbeg <= p) {
if ((unsigned char)*p == c)
- return LONG2NUM((char*)p - RSTRING(str)->ptr);
+ return LONG2NUM((char*)p - RSTRING_PTR(str));
p--;
}
return Qnil;
@@ -1358,11 +1442,11 @@ rb_str_succ(VALUE orig)
int c = -1;
long n = 0;
- str = rb_str_new5(orig, RSTRING(orig)->ptr, RSTRING(orig)->len);
+ str = rb_str_new5(orig, RSTRING_PTR(orig), RSTRING_LEN(orig));
OBJ_INFECT(str, orig);
- if (RSTRING(str)->len == 0) return str;
+ if (RSTRING_LEN(str) == 0) return str;
- sbeg = RSTRING(str)->ptr; s = sbeg + RSTRING(str)->len - 1;
+ sbeg = RSTRING_PTR(str); s = sbeg + RSTRING_LEN(str) - 1;
while (sbeg <= s) {
if (ISALNUM(*s)) {
@@ -1372,7 +1456,7 @@ rb_str_succ(VALUE orig)
s--;
}
if (c == -1) { /* str contains no alnum */
- sbeg = RSTRING(str)->ptr; s = sbeg + RSTRING(str)->len - 1;
+ sbeg = RSTRING_PTR(str); s = sbeg + RSTRING_LEN(str) - 1;
c = '\001';
while (sbeg <= s) {
if ((*s += 1) != 0) break;
@@ -1380,12 +1464,12 @@ rb_str_succ(VALUE orig)
}
}
if (s < sbeg) {
- RESIZE_CAPA(str, RSTRING(str)->len + 1);
- s = RSTRING(str)->ptr + n;
- memmove(s+1, s, RSTRING(str)->len - n);
+ RESIZE_CAPA(str, RSTRING_LEN(str) + 1);
+ s = RSTRING_PTR(str) + n;
+ memmove(s+1, s, RSTRING_LEN(str) - n);
*s = c;
- RSTRING(str)->len += 1;
- RSTRING(str)->ptr[RSTRING(str)->len] = '\0';
+ STR_SET_LEN(str, RSTRING_LEN(str) + 1);
+ RSTRING_PTR(str)[RSTRING_LEN(str)] = '\0';
}
return str;
@@ -1428,7 +1512,7 @@ rb_str_upto(VALUE beg, VALUE end, int excl)
StringValue(current);
if (excl && rb_str_equal(current, end)) break;
StringValue(current);
- if (RSTRING(current)->len > RSTRING(end)->len)
+ if (RSTRING_LEN(current) > RSTRING_LEN(end))
break;
}
@@ -1482,9 +1566,9 @@ rb_str_aref(VALUE str, VALUE indx)
num_index:
if (idx < 0) {
- idx = RSTRING(str)->len + idx;
+ idx = RSTRING_LEN(str) + idx;
}
- if (idx < 0 || RSTRING(str)->len <= idx) {
+ if (idx < 0 || RSTRING_LEN(str) <= idx) {
return Qnil;
}
return rb_str_substr(str, idx, 1);
@@ -1503,7 +1587,7 @@ rb_str_aref(VALUE str, VALUE indx)
long beg, len;
VALUE tmp;
- switch (rb_range_beg_len(indx, &beg, &len, RSTRING(str)->len, 0)) {
+ switch (rb_range_beg_len(indx, &beg, &len, RSTRING_LEN(str), 0)) {
case Qfalse:
break;
case Qnil:
@@ -1591,39 +1675,39 @@ rb_str_splice(VALUE str, long beg, long len, VALUE val)
StringValue(val);
rb_str_modify(str);
- if (RSTRING(str)->len < beg) {
+ if (RSTRING_LEN(str) < beg) {
out_of_range:
rb_raise(rb_eIndexError, "index %ld out of string", beg);
}
if (beg < 0) {
- if (-beg > RSTRING(str)->len) {
+ if (-beg > RSTRING_LEN(str)) {
goto out_of_range;
}
- beg += RSTRING(str)->len;
+ beg += RSTRING_LEN(str);
}
- if (RSTRING(str)->len < beg + len) {
- len = RSTRING(str)->len - beg;
+ if (RSTRING_LEN(str) < beg + len) {
+ len = RSTRING_LEN(str) - beg;
}
- if (len < RSTRING(val)->len) {
+ if (len < RSTRING_LEN(val)) {
/* expand string */
- RESIZE_CAPA(str, RSTRING(str)->len + RSTRING(val)->len - len + 1);
+ RESIZE_CAPA(str, RSTRING_LEN(str) + RSTRING_LEN(val) - len + 1);
}
- if (RSTRING(val)->len != len) {
- memmove(RSTRING(str)->ptr + beg + RSTRING(val)->len,
- RSTRING(str)->ptr + beg + len,
- RSTRING(str)->len - (beg + len));
+ if (RSTRING_LEN(val) != len) {
+ memmove(RSTRING_PTR(str) + beg + RSTRING_LEN(val),
+ RSTRING_PTR(str) + beg + len,
+ RSTRING_LEN(str) - (beg + len));
}
- if (RSTRING(str)->len < beg && len < 0) {
- MEMZERO(RSTRING(str)->ptr + RSTRING(str)->len, char, -len);
+ if (RSTRING_LEN(str) < beg && len < 0) {
+ MEMZERO(RSTRING_PTR(str) + RSTRING_LEN(str), char, -len);
}
- if (RSTRING(val)->len > 0) {
- memmove(RSTRING(str)->ptr+beg, RSTRING(val)->ptr, RSTRING(val)->len);
+ if (RSTRING_LEN(val) > 0) {
+ memmove(RSTRING_PTR(str)+beg, RSTRING_PTR(val), RSTRING_LEN(val));
}
- RSTRING(str)->len += RSTRING(val)->len - len;
- if (RSTRING(str)->ptr) {
- RSTRING(str)->ptr[RSTRING(str)->len] = '\0';
+ STR_SET_LEN(str, RSTRING_LEN(str) + RSTRING_LEN(val) - len);
+ if (RSTRING_PTR(str)) {
+ RSTRING_PTR(str)[RSTRING_LEN(str)] = '\0';
}
OBJ_INFECT(str, val);
}
@@ -1673,14 +1757,14 @@ rb_str_aset(VALUE str, VALUE indx, VALUE val)
case T_FIXNUM:
num_index:
idx = FIX2LONG(indx);
- if (RSTRING(str)->len <= idx) {
+ if (RSTRING_LEN(str) <= idx) {
out_of_range:
rb_raise(rb_eIndexError, "index %ld out of string", idx);
}
if (idx < 0) {
- if (-idx > RSTRING(str)->len)
+ if (-idx > RSTRING_LEN(str))
goto out_of_range;
- idx += RSTRING(str)->len;
+ idx += RSTRING_LEN(str);
}
rb_str_splice(str, idx, 1, val);
return val;
@@ -1694,14 +1778,14 @@ rb_str_aset(VALUE str, VALUE indx, VALUE val)
if (beg < 0) {
rb_raise(rb_eIndexError, "string not matched");
}
- rb_str_splice(str, beg, RSTRING(indx)->len, val);
+ rb_str_splice(str, beg, RSTRING_LEN(indx), val);
return val;
default:
/* check if indx is Range */
{
long beg, len;
- if (rb_range_beg_len(indx, &beg, &len, RSTRING(str)->len, 2)) {
+ if (rb_range_beg_len(indx, &beg, &len, RSTRING_LEN(str), 2)) {
rb_str_splice(str, beg, len, val);
return val;
}
@@ -1776,7 +1860,7 @@ rb_str_insert(VALUE str, VALUE idx, VALUE str2)
long pos = NUM2LONG(idx);
if (pos == -1) {
- pos = RSTRING(str)->len;
+ pos = RSTRING_LEN(str);
}
else if (pos < 0) {
pos++;
@@ -1895,7 +1979,7 @@ rb_str_sub_bang(int argc, VALUE *argv, VALUE str)
regs = RMATCH(match)->regs;
if (iter) {
- char *p = RSTRING(str)->ptr; long len = RSTRING(str)->len;
+ char *p = RSTRING_PTR(str); long len = RSTRING_LEN(str);
rb_match_busy(match);
repl = rb_obj_as_string(rb_yield(rb_reg_nth_match(0, match)));
@@ -1908,18 +1992,18 @@ rb_str_sub_bang(int argc, VALUE *argv, VALUE str)
}
if (OBJ_TAINTED(repl)) tainted = 1;
plen = END(0) - BEG(0);
- if (RSTRING(repl)->len > plen) {
- RESIZE_CAPA(str, RSTRING(str)->len + RSTRING(repl)->len - plen);
+ if (RSTRING_LEN(repl) > plen) {
+ RESIZE_CAPA(str, RSTRING_LEN(str) + RSTRING_LEN(repl) - plen);
}
- if (RSTRING(repl)->len != plen) {
- memmove(RSTRING(str)->ptr + BEG(0) + RSTRING(repl)->len,
- RSTRING(str)->ptr + BEG(0) + plen,
- RSTRING(str)->len - BEG(0) - plen);
+ if (RSTRING_LEN(repl) != plen) {
+ memmove(RSTRING_PTR(str) + BEG(0) + RSTRING_LEN(repl),
+ RSTRING_PTR(str) + BEG(0) + plen,
+ RSTRING_LEN(str) - BEG(0) - plen);
}
- memcpy(RSTRING(str)->ptr + BEG(0),
- RSTRING(repl)->ptr, RSTRING(repl)->len);
- RSTRING(str)->len += RSTRING(repl)->len - plen;
- RSTRING(str)->ptr[RSTRING(str)->len] = '\0';
+ memcpy(RSTRING_PTR(str) + BEG(0),
+ RSTRING_PTR(repl), RSTRING_LEN(repl));
+ STR_SET_LEN(str, RSTRING_LEN(str) + RSTRING_LEN(repl) - plen);
+ RSTRING_PTR(str)[RSTRING_LEN(str)] = '\0';
if (tainted) OBJ_TAINT(str);
return str;
@@ -2000,12 +2084,12 @@ str_gsub(int argc, VALUE *argv, VALUE str, int bang)
return rb_str_dup(str);
}
- blen = RSTRING(str)->len + 30; /* len + margin */
+ blen = RSTRING_LEN(str) + 30; /* len + margin */
dest = str_new(0, 0, blen);
- buf = RSTRING(dest)->ptr;
+ buf = RSTRING_PTR(dest);
bp = buf;
- sp = cp = RSTRING(str)->ptr;
- slen = RSTRING(str)->len;
+ sp = cp = RSTRING_PTR(str);
+ slen = RSTRING_LEN(str);
rb_str_locktmp(dest);
while (beg >= 0) {
@@ -2026,66 +2110,67 @@ str_gsub(int argc, VALUE *argv, VALUE str, int bang)
val = rb_reg_regsub(repl, str, regs, pat);
}
if (OBJ_TAINTED(val)) tainted = 1;
- len = (bp - buf) + (beg - offset) + RSTRING(val)->len + 3;
+ len = (bp - buf) + (beg - offset) + RSTRING_LEN(val) + 3;
if (blen < len) {
while (blen < len) blen *= 2;
len = bp - buf;
RESIZE_CAPA(dest, blen);
- RSTRING(dest)->len = blen;
- buf = RSTRING(dest)->ptr;
+ STR_SET_LEN(dest, blen);
+ buf = RSTRING_PTR(dest);
bp = buf + len;
}
len = beg - offset; /* copy pre-match substr */
memcpy(bp, cp, len);
bp += len;
- memcpy(bp, RSTRING(val)->ptr, RSTRING(val)->len);
- bp += RSTRING(val)->len;
+ memcpy(bp, RSTRING_PTR(val), RSTRING_LEN(val));
+ bp += RSTRING_LEN(val);
offset = END(0);
if (BEG(0) == END(0)) {
/*
* Always consume at least one character of the input string
* in order to prevent infinite loops.
*/
- if (RSTRING(str)->len <= END(0)) break;
- len = mbclen2(RSTRING(str)->ptr[END(0)], pat);
- memcpy(bp, RSTRING(str)->ptr+END(0), len);
+ if (RSTRING_LEN(str) <= END(0)) break;
+ len = mbclen2(RSTRING_PTR(str)[END(0)], pat);
+ memcpy(bp, RSTRING_PTR(str)+END(0), len);
bp += len;
offset = END(0) + len;
}
- cp = RSTRING(str)->ptr + offset;
- if (offset > RSTRING(str)->len) break;
+ cp = RSTRING_PTR(str) + offset;
+ if (offset > RSTRING_LEN(str)) break;
beg = rb_reg_search(pat, str, offset, 0);
}
- if (RSTRING(str)->len > offset) {
+ if (RSTRING_LEN(str) > offset) {
len = bp - buf;
- if (blen - len < RSTRING(str)->len - offset) {
- blen = len + RSTRING(str)->len - offset;
+ if (blen - len < RSTRING_LEN(str) - offset) {
+ blen = len + RSTRING_LEN(str) - offset;
RESIZE_CAPA(dest, blen);
- buf = RSTRING(dest)->ptr;
+ buf = RSTRING_PTR(dest);
bp = buf + len;
}
- memcpy(bp, cp, RSTRING(str)->len - offset);
- bp += RSTRING(str)->len - offset;
+ memcpy(bp, cp, RSTRING_LEN(str) - offset);
+ bp += RSTRING_LEN(str) - offset;
}
rb_backref_set(match);
*bp = '\0';
rb_str_unlocktmp(dest);
if (bang) {
- if (str_independent(str)) {
- free(RSTRING(str)->ptr);
+ if (str_independent(str) && !STR_EMBED_P(str)) {
+ free(RSTRING_PTR(str));
}
- FL_UNSET(str, STR_NOCAPA);
- RSTRING(str)->ptr = buf;
- RSTRING(str)->aux.capa = blen;
- RSTRING(dest)->ptr = 0;
- RSTRING(dest)->len = 0;
+ STR_SET_NOEMBED(str);
+ STR_UNSET_NOCAPA(str);
+ RSTRING(str)->as.heap.ptr = buf;
+ RSTRING(str)->as.heap.aux.capa = blen;
+ RSTRING(dest)->as.heap.ptr = 0;
+ RSTRING(dest)->as.heap.len = 0;
}
else {
RBASIC(dest)->klass = rb_obj_class(str);
OBJ_INFECT(dest, str);
str = dest;
}
- RSTRING(str)->len = bp - buf;
+ STR_SET_LEN(str, bp - buf);
if (tainted) OBJ_TAINT(str);
return str;
@@ -2162,27 +2247,34 @@ rb_str_gsub(int argc, VALUE *argv, VALUE str)
static VALUE
rb_str_replace(VALUE str, VALUE str2)
{
+ long len;
if (str == str2) return str;
StringValue(str2);
- if (FL_TEST(str2, ELTS_SHARED)) {
- if (str_independent(str)) {
- free(RSTRING(str)->ptr);
+ len = RSTRING_LEN(str2);
+ if (STR_SHARED_P(str2)) {
+ if (str_independent(str) && !STR_EMBED_P(str)) {
+ free(RSTRING_PTR(str));
}
- RSTRING(str)->len = RSTRING(str2)->len;
- RSTRING(str)->ptr = RSTRING(str2)->ptr;
+ STR_SET_NOEMBED(str);
+ RSTRING(str)->as.heap.len = len;
+ RSTRING(str)->as.heap.ptr = RSTRING_PTR(str2);
FL_SET(str, ELTS_SHARED);
FL_UNSET(str, STR_ASSOC);
- RSTRING(str)->aux.shared = RSTRING(str2)->aux.shared;
+ RSTRING(str)->as.heap.aux.shared = RSTRING(str2)->as.heap.aux.shared;
+ }
+ else if (STR_ASSOC_P(str2)) {
+ rb_str_modify(str);
+ STR_SET_NOEMBED(str);
+ RSTRING(str)->as.heap.ptr = ALLOC_N(char,len+1);
+ memcpy(RSTRING_PTR(str), RSTRING_PTR(str2), len+1);
+ FL_SET(str, STR_ASSOC);
+ RSTRING(str)->as.heap.aux.shared = RSTRING(str2)->as.heap.aux.shared;
}
else {
rb_str_modify(str);
- rb_str_resize(str, RSTRING(str2)->len);
- memcpy(RSTRING(str)->ptr, RSTRING(str2)->ptr, RSTRING(str2)->len);
- if (FL_TEST(str2, STR_ASSOC)) {
- FL_SET(str, STR_ASSOC);
- RSTRING(str)->aux.shared = RSTRING(str2)->aux.shared;
- }
+ rb_str_resize(str, len);
+ memcpy(RSTRING_PTR(str), RSTRING_PTR(str2), len+1);
}
OBJ_INFECT(str, str2);
@@ -2204,13 +2296,11 @@ rb_str_clear(VALUE str)
{
/* rb_str_modify() */ /* no need for str_make_independent */
if (str_independent(str)) {
- free(RSTRING(str)->ptr);
+ free(RSTRING_PTR(str));
}
- RSTRING(str)->aux.shared = 0;
- FL_UNSET(str, STR_NOCAPA);
- FL_SET(str, ELTS_SHARED);
- RSTRING(str)->ptr = null_str;
- RSTRING(str)->len = 0;
+ FL_UNSET(str, STR_NOEMBED);
+ STR_SET_EMBED_LEN(str, 0);
+ RSTRING_PTR(str)[0] = 0;
return str;
}
@@ -2243,10 +2333,10 @@ rb_str_reverse_bang(VALUE str)
char *s, *e;
char c;
- if (RSTRING(str)->len > 1) {
+ if (RSTRING_LEN(str) > 1) {
rb_str_modify(str);
- s = RSTRING(str)->ptr;
- e = s + RSTRING(str)->len - 1;
+ s = RSTRING_PTR(str);
+ e = s + RSTRING_LEN(str) - 1;
while (s < e) {
c = *s;
*s++ = *e;
@@ -2272,11 +2362,11 @@ rb_str_reverse(VALUE str)
VALUE obj;
char *s, *e, *p;
- if (RSTRING(str)->len <= 1) return rb_str_dup(str);
+ if (RSTRING_LEN(str) <= 1) return rb_str_dup(str);
- obj = rb_str_new5(str, 0, RSTRING(str)->len);
- s = RSTRING(str)->ptr; e = s + RSTRING(str)->len - 1;
- p = RSTRING(obj)->ptr;
+ obj = rb_str_new5(str, 0, RSTRING_LEN(str));
+ s = RSTRING_PTR(str); e = s + RSTRING_LEN(str) - 1;
+ p = RSTRING_PTR(obj);
while (e >= s) {
*p++ = *e--;
@@ -2306,7 +2396,7 @@ rb_str_include(VALUE str, VALUE arg)
long i;
if (FIXNUM_P(arg)) {
- if (memchr(RSTRING(str)->ptr, FIX2INT(arg), RSTRING(str)->len))
+ if (memchr(RSTRING_PTR(str), FIX2INT(arg), RSTRING_LEN(str)))
return Qtrue;
return Qfalse;
}
@@ -2418,7 +2508,7 @@ rb_str_inspect(VALUE str)
VALUE result = rb_str_buf_new2("\"");
char s[5];
- p = RSTRING(str)->ptr; pend = p + RSTRING(str)->len;
+ p = RSTRING_PTR(str); pend = p + RSTRING_LEN(str);
while (p < pend) {
char c = *p++;
if (ismbchar(c) && p < pend) {
@@ -2495,7 +2585,7 @@ rb_str_dump(VALUE str)
VALUE result;
len = 2; /* "" */
- p = RSTRING(str)->ptr; pend = p + RSTRING(str)->len;
+ p = RSTRING_PTR(str); pend = p + RSTRING_LEN(str);
while (p < pend) {
char c = *p++;
switch (c) {
@@ -2522,8 +2612,8 @@ rb_str_dump(VALUE str)
}
result = rb_str_new5(str, 0, len);
- p = RSTRING(str)->ptr; pend = p + RSTRING(str)->len;
- q = RSTRING(result)->ptr; qend = q + len;
+ p = RSTRING_PTR(str); pend = p + RSTRING_LEN(str);
+ q = RSTRING_PTR(result); qend = q + len;
*q++ = '"';
while (p < pend) {
@@ -2600,7 +2690,7 @@ rb_str_upcase_bang(VALUE str)
int modify = 0;
rb_str_modify(str);
- s = RSTRING(str)->ptr; send = s + RSTRING(str)->len;
+ s = RSTRING_PTR(str); send = s + RSTRING_LEN(str);
while (s < send) {
if (ismbchar(*s)) {
s+=mbclen(*s) - 1;
@@ -2652,7 +2742,7 @@ rb_str_downcase_bang(VALUE str)
int modify = 0;
rb_str_modify(str);
- s = RSTRING(str)->ptr; send = s + RSTRING(str)->len;
+ s = RSTRING_PTR(str); send = s + RSTRING_LEN(str);
while (s < send) {
if (ismbchar(*s)) {
s+=mbclen(*s) - 1;
@@ -2709,8 +2799,8 @@ rb_str_capitalize_bang(VALUE str)
int modify = 0;
rb_str_modify(str);
- if (RSTRING(str)->len == 0 || !RSTRING(str)->ptr) return Qnil;
- s = RSTRING(str)->ptr; send = s + RSTRING(str)->len;
+ if (RSTRING_LEN(str) == 0 || !RSTRING_PTR(str)) return Qnil;
+ s = RSTRING_PTR(str); send = s + RSTRING_LEN(str);
if (ISLOWER(*s)) {
*s = toupper(*s);
modify = 1;
@@ -2765,7 +2855,7 @@ rb_str_swapcase_bang(VALUE str)
int modify = 0;
rb_str_modify(str);
- s = RSTRING(str)->ptr; send = s + RSTRING(str)->len;
+ s = RSTRING_PTR(str); send = s + RSTRING_LEN(str);
while (s < send) {
if (ismbchar(*s)) {
s+=mbclen(*s) - 1;
@@ -2858,17 +2948,17 @@ tr_trans(VALUE str, VALUE src, VALUE repl, int sflag)
StringValue(src);
StringValue(repl);
- if (RSTRING(str)->len == 0 || !RSTRING(str)->ptr) return Qnil;
- trsrc.p = RSTRING(src)->ptr; trsrc.pend = trsrc.p + RSTRING(src)->len;
- if (RSTRING(src)->len >= 2 && RSTRING(src)->ptr[0] == '^') {
+ if (RSTRING_LEN(str) == 0 || !RSTRING_PTR(str)) return Qnil;
+ trsrc.p = RSTRING_PTR(src); trsrc.pend = trsrc.p + RSTRING_LEN(src);
+ if (RSTRING_LEN(src) >= 2 && RSTRING_PTR(src)[0] == '^') {
cflag++;
trsrc.p++;
}
- if (RSTRING(repl)->len == 0) {
+ if (RSTRING_LEN(repl) == 0) {
return rb_str_delete_bang(1, &src, str);
}
- trrepl.p = RSTRING(repl)->ptr;
- trrepl.pend = trrepl.p + RSTRING(repl)->len;
+ trrepl.p = RSTRING_PTR(repl);
+ trrepl.pend = trrepl.p + RSTRING_LEN(repl);
trsrc.gen = trrepl.gen = 0;
trsrc.now = trrepl.now = 0;
trsrc.max = trrepl.max = 0;
@@ -2902,7 +2992,7 @@ tr_trans(VALUE str, VALUE src, VALUE repl, int sflag)
}
rb_str_modify(str);
- s = RSTRING(str)->ptr; send = s + RSTRING(str)->len;
+ s = RSTRING_PTR(str); send = s + RSTRING_LEN(str);
if (sflag) {
char *t = s;
int c0, last = -1;
@@ -2920,8 +3010,8 @@ tr_trans(VALUE str, VALUE src, VALUE repl, int sflag)
*t++ = c0;
}
}
- if (RSTRING(str)->len > (t - RSTRING(str)->ptr)) {
- RSTRING(str)->len = (t - RSTRING(str)->ptr);
+ if (RSTRING_LEN(str) > (t - RSTRING_PTR(str))) {
+ STR_SET_LEN(str, (t - RSTRING_PTR(str)));
modify = 1;
*t = '\0';
}
@@ -2990,9 +3080,9 @@ tr_setup_table(VALUE str, char table[256], int init)
int i, c;
int cflag = 0;
- tr.p = RSTRING(str)->ptr; tr.pend = tr.p + RSTRING(str)->len;
+ tr.p = RSTRING_PTR(str); tr.pend = tr.p + RSTRING_LEN(str);
tr.gen = tr.now = tr.max = 0;
- if (RSTRING(str)->len > 1 && RSTRING(str)->ptr[0] == '^') {
+ if (RSTRING_LEN(str) > 1 && RSTRING_PTR(str)[0] == '^') {
cflag = 1;
tr.p++;
}
@@ -3043,9 +3133,9 @@ rb_str_delete_bang(int argc, VALUE *argv, VALUE str)
}
rb_str_modify(str);
- s = t = RSTRING(str)->ptr;
- if (!s || RSTRING(str)->len == 0) return Qnil;
- send = s + RSTRING(str)->len;
+ s = t = RSTRING_PTR(str);
+ if (!s || RSTRING_LEN(str) == 0) return Qnil;
+ send = s + RSTRING_LEN(str);
while (s < send) {
if (squeez[*s & 0xff])
modify = 1;
@@ -3054,7 +3144,7 @@ rb_str_delete_bang(int argc, VALUE *argv, VALUE str)
s++;
}
*t = '\0';
- RSTRING(str)->len = t - RSTRING(str)->ptr;
+ STR_SET_LEN(str, t - RSTRING_PTR(str));
if (modify) return str;
return Qnil;
@@ -3117,9 +3207,9 @@ rb_str_squeeze_bang(int argc, VALUE *argv, VALUE str)
}
rb_str_modify(str);
- s = t = RSTRING(str)->ptr;
- if (!s || RSTRING(str)->len == 0) return Qnil;
- send = s + RSTRING(str)->len;
+ s = t = RSTRING_PTR(str);
+ if (!s || RSTRING_LEN(str) == 0) return Qnil;
+ send = s + RSTRING_LEN(str);
save = -1;
while (s < send) {
c = *s++ & 0xff;
@@ -3128,8 +3218,8 @@ rb_str_squeeze_bang(int argc, VALUE *argv, VALUE str)
}
}
*t = '\0';
- if (t - RSTRING(str)->ptr != RSTRING(str)->len) {
- RSTRING(str)->len = t - RSTRING(str)->ptr;
+ if (t - RSTRING_PTR(str) != RSTRING_LEN(str)) {
+ STR_SET_LEN(str, t - RSTRING_PTR(str));
modify = 1;
}
@@ -3234,9 +3324,9 @@ rb_str_count(int argc, VALUE *argv, VALUE str)
init = 0;
}
- s = RSTRING(str)->ptr;
- if (!s || RSTRING(str)->len == 0) return INT2FIX(0);
- send = s + RSTRING(str)->len;
+ s = RSTRING_PTR(str);
+ if (!s || RSTRING_LEN(str) == 0) return INT2FIX(0);
+ send = s + RSTRING_LEN(str);
i = 0;
while (s < send) {
if (table[*s++ & 0xff]) {
@@ -3303,7 +3393,7 @@ rb_str_split_m(int argc, VALUE *argv, VALUE str)
lim = NUM2INT(limit);
if (lim <= 0) limit = Qnil;
else if (lim == 1) {
- if (RSTRING(str)->len == 0)
+ if (RSTRING_LEN(str) == 0)
return rb_ary_new2(0);
return rb_ary_new3(1, str);
}
@@ -3319,8 +3409,8 @@ rb_str_split_m(int argc, VALUE *argv, VALUE str)
}
else {
fs_set:
- if (TYPE(spat) == T_STRING && RSTRING(spat)->len == 1) {
- if (RSTRING(spat)->ptr[0] == ' ') {
+ if (TYPE(spat) == T_STRING && RSTRING_LEN(spat) == 1) {
+ if (RSTRING_PTR(spat)[0] == ' ') {
awk_split = Qtrue;
}
else {
@@ -3335,8 +3425,8 @@ rb_str_split_m(int argc, VALUE *argv, VALUE str)
result = rb_ary_new();
beg = 0;
if (awk_split) {
- char *ptr = RSTRING(str)->ptr;
- long len = RSTRING(str)->len;
+ char *ptr = RSTRING_PTR(str);
+ long len = RSTRING_LEN(str);
char *eptr = ptr + len;
int skip = 1;
@@ -3373,16 +3463,16 @@ rb_str_split_m(int argc, VALUE *argv, VALUE str)
while ((end = rb_reg_search(spat, str, start, 0)) >= 0) {
regs = RMATCH(rb_backref_get())->regs;
if (start == end && BEG(0) == END(0)) {
- if (!RSTRING(str)->ptr) {
+ if (!RSTRING_PTR(str)) {
rb_ary_push(result, rb_str_new("", 0));
break;
}
else if (last_null == 1) {
- rb_ary_push(result, rb_str_substr(str, beg, mbclen2(RSTRING(str)->ptr[beg],spat)));
+ rb_ary_push(result, rb_str_substr(str, beg, mbclen2(RSTRING_PTR(str)[beg],spat)));
beg = start;
}
else {
- start += mbclen2(RSTRING(str)->ptr[start],spat);
+ start += mbclen2(RSTRING_PTR(str)[start],spat);
last_null = 1;
continue;
}
@@ -3404,16 +3494,16 @@ rb_str_split_m(int argc, VALUE *argv, VALUE str)
if (!NIL_P(limit) && lim <= ++i) break;
}
}
- if (RSTRING(str)->len > 0 && (!NIL_P(limit) || RSTRING(str)->len > beg || lim < 0)) {
- if (RSTRING(str)->len == beg)
+ if (RSTRING_LEN(str) > 0 && (!NIL_P(limit) || RSTRING_LEN(str) > beg || lim < 0)) {
+ if (RSTRING_LEN(str) == beg)
tmp = rb_str_new5(str, 0, 0);
else
- tmp = rb_str_substr(str, beg, RSTRING(str)->len-beg);
+ tmp = rb_str_substr(str, beg, RSTRING_LEN(str)-beg);
rb_ary_push(result, tmp);
}
if (NIL_P(limit) && lim == 0) {
while (RARRAY(result)->len > 0 &&
- RSTRING(RARRAY(result)->ptr[RARRAY(result)->len-1])->len == 0)
+ RSTRING_LEN(RARRAY(result)->ptr[RARRAY(result)->len-1]) == 0)
rb_ary_pop(result);
}
@@ -3468,9 +3558,9 @@ rb_str_each_line(int argc, VALUE *argv, VALUE str)
{
VALUE rs;
int newline;
- char *p = RSTRING(str)->ptr, *pend = p + RSTRING(str)->len, *s;
+ char *p = RSTRING_PTR(str), *pend = p + RSTRING_LEN(str), *s;
char *ptr = p;
- long len = RSTRING(str)->len, rslen;
+ long len = RSTRING_LEN(str), rslen;
VALUE line;
if (rb_scan_args(argc, argv, "01", &rs) == 0) {
@@ -3484,12 +3574,12 @@ rb_str_each_line(int argc, VALUE *argv, VALUE str)
return str;
}
StringValue(rs);
- rslen = RSTRING(rs)->len;
+ rslen = RSTRING_LEN(rs);
if (rslen == 0) {
newline = '\n';
}
else {
- newline = RSTRING(rs)->ptr[rslen-1];
+ newline = RSTRING_PTR(rs)[rslen-1];
}
for (s = p, p += rslen; p < pend; p++) {
@@ -3497,9 +3587,9 @@ rb_str_each_line(int argc, VALUE *argv, VALUE str)
if (*++p != '\n') continue;
while (*p == '\n') p++;
}
- if (RSTRING(str)->ptr < p && p[-1] == newline &&
+ if (RSTRING_PTR(str) < p && p[-1] == newline &&
(rslen <= 1 ||
- rb_memcmp(RSTRING(rs)->ptr, p-rslen, rslen) == 0)) {
+ rb_memcmp(RSTRING_PTR(rs), p-rslen, rslen) == 0)) {
line = rb_str_new5(str, s, p - s);
OBJ_INFECT(line, str);
rb_yield(line);
@@ -3538,8 +3628,8 @@ rb_str_each_byte(VALUE str)
long i;
RETURN_ENUMERATOR(str, 0, 0);
- for (i=0; i<RSTRING(str)->len; i++) {
- rb_yield(INT2FIX(RSTRING(str)->ptr[i] & 0xff));
+ for (i=0; i<RSTRING_LEN(str); i++) {
+ rb_yield(INT2FIX(RSTRING_PTR(str)[i] & 0xff));
}
return str;
}
@@ -3557,16 +3647,16 @@ rb_str_each_byte(VALUE str)
static VALUE
rb_str_chop_bang(VALUE str)
{
- if (RSTRING(str)->len > 0) {
+ if (RSTRING_LEN(str) > 0) {
rb_str_modify(str);
- RSTRING(str)->len--;
- if (RSTRING(str)->ptr[RSTRING(str)->len] == '\n') {
- if (RSTRING(str)->len > 0 &&
- RSTRING(str)->ptr[RSTRING(str)->len-1] == '\r') {
- RSTRING(str)->len--;
+ STR_DEC_LEN(str);
+ if (RSTRING_PTR(str)[RSTRING_LEN(str)] == '\n') {
+ if (RSTRING_LEN(str) > 0 &&
+ RSTRING_PTR(str)[RSTRING_LEN(str)-1] == '\r') {
+ STR_DEC_LEN(str);
}
}
- RSTRING(str)->ptr[RSTRING(str)->len] = '\0';
+ RSTRING_PTR(str)[RSTRING_LEN(str)] = '\0';
return str;
}
return Qnil;
@@ -3616,61 +3706,61 @@ rb_str_chomp_bang(int argc, VALUE *argv, VALUE str)
long len, rslen;
if (rb_scan_args(argc, argv, "01", &rs) == 0) {
- len = RSTRING(str)->len;
+ len = RSTRING_LEN(str);
if (len == 0) return Qnil;
- p = RSTRING(str)->ptr;
+ p = RSTRING_PTR(str);
rs = rb_rs;
if (rs == rb_default_rs) {
smart_chomp:
rb_str_modify(str);
- if (RSTRING(str)->ptr[len-1] == '\n') {
- RSTRING(str)->len--;
- if (RSTRING(str)->len > 0 &&
- RSTRING(str)->ptr[RSTRING(str)->len-1] == '\r') {
- RSTRING(str)->len--;
+ if (RSTRING_PTR(str)[len-1] == '\n') {
+ STR_DEC_LEN(str);
+ if (RSTRING_LEN(str) > 0 &&
+ RSTRING_PTR(str)[RSTRING_LEN(str)-1] == '\r') {
+ STR_DEC_LEN(str);
}
}
- else if (RSTRING(str)->ptr[len-1] == '\r') {
- RSTRING(str)->len--;
+ else if (RSTRING_PTR(str)[len-1] == '\r') {
+ STR_DEC_LEN(str);
}
else {
return Qnil;
}
- RSTRING(str)->ptr[RSTRING(str)->len] = '\0';
+ RSTRING_PTR(str)[RSTRING_LEN(str)] = '\0';
return str;
}
}
if (NIL_P(rs)) return Qnil;
StringValue(rs);
- len = RSTRING(str)->len;
+ len = RSTRING_LEN(str);
if (len == 0) return Qnil;
- p = RSTRING(str)->ptr;
- rslen = RSTRING(rs)->len;
+ p = RSTRING_PTR(str);
+ rslen = RSTRING_LEN(rs);
if (rslen == 0) {
while (len>0 && p[len-1] == '\n') {
len--;
if (len>0 && p[len-1] == '\r')
len--;
}
- if (len < RSTRING(str)->len) {
+ if (len < RSTRING_LEN(str)) {
rb_str_modify(str);
- RSTRING(str)->len = len;
- RSTRING(str)->ptr[len] = '\0';
+ STR_SET_LEN(str, len);
+ RSTRING_PTR(str)[len] = '\0';
return str;
}
return Qnil;
}
if (rslen > len) return Qnil;
- newline = RSTRING(rs)->ptr[rslen-1];
+ newline = RSTRING_PTR(rs)[rslen-1];
if (rslen == 1 && newline == '\n')
goto smart_chomp;
if (p[len-1] == newline &&
(rslen <= 1 ||
- rb_memcmp(RSTRING(rs)->ptr, p+len-rslen, rslen) == 0)) {
+ rb_memcmp(RSTRING_PTR(rs), p+len-rslen, rslen) == 0)) {
rb_str_modify(str);
- RSTRING(str)->len -= rslen;
- RSTRING(str)->ptr[RSTRING(str)->len] = '\0';
+ STR_SET_LEN(str, RSTRING_LEN(str) - rslen);
+ RSTRING_PTR(str)[RSTRING_LEN(str)] = '\0';
return str;
}
return Qnil;
@@ -3721,17 +3811,17 @@ rb_str_lstrip_bang(VALUE str)
{
char *s, *t, *e;
- s = RSTRING(str)->ptr;
- if (!s || RSTRING(str)->len == 0) return Qnil;
- e = t = s + RSTRING(str)->len;
+ s = RSTRING_PTR(str);
+ if (!s || RSTRING_LEN(str) == 0) return Qnil;
+ e = t = s + RSTRING_LEN(str);
/* remove spaces at head */
while (s < t && ISSPACE(*s)) s++;
- if (s > RSTRING(str)->ptr) {
+ if (s > RSTRING_PTR(str)) {
rb_str_modify(str);
- RSTRING(str)->len = t-s;
- memmove(RSTRING(str)->ptr, s, RSTRING(str)->len);
- RSTRING(str)->ptr[RSTRING(str)->len] = '\0';
+ STR_SET_LEN(str, t-s);
+ memmove(RSTRING_PTR(str), s, RSTRING_LEN(str));
+ RSTRING_PTR(str)[RSTRING_LEN(str)] = '\0';
return str;
}
return Qnil;
@@ -3775,9 +3865,9 @@ rb_str_rstrip_bang(VALUE str)
{
char *s, *t, *e;
- s = RSTRING(str)->ptr;
- if (!s || RSTRING(str)->len == 0) return Qnil;
- e = t = s + RSTRING(str)->len;
+ s = RSTRING_PTR(str);
+ if (!s || RSTRING_LEN(str) == 0) return Qnil;
+ e = t = s + RSTRING_LEN(str);
/* remove trailing '\0's */
while (s < t && t[-1] == '\0') t--;
@@ -3787,8 +3877,8 @@ rb_str_rstrip_bang(VALUE str)
if (t < e) {
rb_str_modify(str);
- RSTRING(str)->len = t-s;
- RSTRING(str)->ptr[RSTRING(str)->len] = '\0';
+ STR_SET_LEN(str, t-s);
+ RSTRING_PTR(str)[RSTRING_LEN(str)] = '\0';
return str;
}
return Qnil;
@@ -3866,8 +3956,8 @@ scan_once(VALUE str, VALUE pat, long *start)
/*
* Always consume at least one character of the input string
*/
- if (RSTRING(str)->len > END(0))
- *start = END(0)+mbclen2(RSTRING(str)->ptr[END(0)],pat);
+ if (RSTRING_LEN(str) > END(0))
+ *start = END(0)+mbclen2(RSTRING_PTR(str)[END(0)],pat);
else
*start = END(0)+1;
}
@@ -3925,7 +4015,7 @@ rb_str_scan(VALUE str, VALUE pat)
VALUE result;
long start = 0;
VALUE match = Qnil;
- char *p = RSTRING(str)->ptr; long len = RSTRING(str)->len;
+ char *p = RSTRING_PTR(str); long len = RSTRING_LEN(str);
pat = get_pat(pat, 1);
if (!rb_block_given_p()) {
@@ -4011,12 +4101,12 @@ rb_str_crypt(VALUE str, VALUE salt)
const char *s;
StringValue(salt);
- if (RSTRING(salt)->len < 2)
+ if (RSTRING_LEN(salt) < 2)
rb_raise(rb_eArgError, "salt too short (need >=2 bytes)");
- if (RSTRING(str)->ptr) s = RSTRING(str)->ptr;
+ if (RSTRING_PTR(str)) s = RSTRING_PTR(str);
else s = "";
- result = rb_str_new2(crypt(s, RSTRING(salt)->ptr));
+ result = rb_str_new2(crypt(s, RSTRING_PTR(salt)));
OBJ_INFECT(result, str);
OBJ_INFECT(result, salt);
return result;
@@ -4049,12 +4139,12 @@ rb_str_intern(VALUE s)
volatile VALUE str = s;
ID id;
- if (!RSTRING(str)->ptr || RSTRING(str)->len == 0) {
+ if (!RSTRING_PTR(str) || RSTRING_LEN(str) == 0) {
rb_raise(rb_eArgError, "interning empty string");
}
- if (strlen(RSTRING(str)->ptr) != RSTRING(str)->len)
+ if (strlen(RSTRING_PTR(str)) != RSTRING_LEN(str))
rb_raise(rb_eArgError, "symbol string may not contain `\\0'");
- id = rb_intern(RSTRING(str)->ptr);
+ id = rb_intern(RSTRING_PTR(str));
return ID2SYM(id);
}
@@ -4073,12 +4163,12 @@ rb_str_ord(VALUE s)
{
int c;
- if (RSTRING(s)->len != 1) {
+ if (RSTRING_LEN(s) != 1) {
rb_raise(rb_eTypeError,
"expacted a characer, but string of size %d given",
- RSTRING(s)->len);
+ RSTRING_LEN(s));
}
- c = RSTRING(s)->ptr[0] & 0xff;
+ c = RSTRING_PTR(s)[0] & 0xff;
return INT2NUM(c);
}
/*
@@ -4105,8 +4195,8 @@ rb_str_sum(int argc, VALUE *argv, VALUE str)
}
else bits = NUM2INT(vbits);
- ptr = p = RSTRING(str)->ptr;
- len = RSTRING(str)->len;
+ ptr = p = RSTRING_PTR(str);
+ len = RSTRING_LEN(str);
pend = p + len;
if (bits >= sizeof(long)*CHAR_BIT) {
VALUE sum = INT2FIX(0);
@@ -4154,17 +4244,17 @@ rb_str_justify(int argc, VALUE *argv, VALUE str, char jflag)
width = NUM2LONG(w);
if (argc == 2) {
StringValue(pad);
- f = RSTRING(pad)->ptr;
- flen = RSTRING(pad)->len;
+ f = RSTRING_PTR(pad);
+ flen = RSTRING_LEN(pad);
if (flen == 0) {
rb_raise(rb_eArgError, "zero width padding");
}
}
- if (width < 0 || RSTRING(str)->len >= width) return rb_str_dup(str);
+ if (width < 0 || RSTRING_LEN(str) >= width) return rb_str_dup(str);
res = rb_str_new5(str, 0, width);
- p = RSTRING(res)->ptr;
+ p = RSTRING_PTR(res);
if (jflag != 'l') {
- n = width - RSTRING(str)->len;
+ n = width - RSTRING_LEN(str);
pend = p + ((jflag == 'r') ? n : n/2);
if (flen <= 1) {
while (p < pend) {
@@ -4182,9 +4272,9 @@ rb_str_justify(int argc, VALUE *argv, VALUE str, char jflag)
}
}
}
- memcpy(p, RSTRING(str)->ptr, RSTRING(str)->len);
+ memcpy(p, RSTRING_PTR(str), RSTRING_LEN(str)+1);
if (jflag != 'r') {
- p += RSTRING(str)->len; pend = RSTRING(res)->ptr + width;
+ p += RSTRING_LEN(str); pend = RSTRING_PTR(res) + width;
if (flen <= 1) {
while (p < pend) {
*p++ = *f;
diff --git a/time.c b/time.c
index d8d01b1cf2..0f178a78eb 100644
--- a/time.c
+++ b/time.c
@@ -326,14 +326,14 @@ time_arg(int argc, VALUE *argv, struct tm *tm, time_t *usec)
if (!NIL_P(s)) {
tm->tm_mon = -1;
for (i=0; i<12; i++) {
- if (RSTRING(s)->len == 3 &&
- strcasecmp(months[i], RSTRING(v[1])->ptr) == 0) {
+ if (RSTRING_LEN(s) == 3 &&
+ strcasecmp(months[i], RSTRING_PTR(v[1])) == 0) {
tm->tm_mon = i;
break;
}
}
if (tm->tm_mon == -1) {
- char c = RSTRING(s)->ptr[0];
+ char c = RSTRING_PTR(s)[0];
if ('0' <= c && c <= '9') {
tm->tm_mon = obj2long(s)-1;
@@ -1873,8 +1873,8 @@ time_strftime(VALUE time, VALUE format)
}
StringValue(format);
format = rb_str_new4(format);
- fmt = RSTRING(format)->ptr;
- len = RSTRING(format)->len;
+ fmt = RSTRING_PTR(format);
+ len = RSTRING_LEN(format);
if (len == 0) {
rb_warning("strftime called with empty format string");
}
@@ -1897,7 +1897,7 @@ time_strftime(VALUE time, VALUE format)
return str;
}
else {
- len = rb_strftime(&buf, RSTRING(format)->ptr, &tobj->tm);
+ len = rb_strftime(&buf, RSTRING_PTR(format), &tobj->tm);
}
str = rb_str_new(buf, len);
if (buf != buffer) free(buf);
@@ -1997,8 +1997,8 @@ time_mload(VALUE time, VALUE str)
time_modify(time);
StringValue(str);
- buf = (unsigned char *)RSTRING(str)->ptr;
- if (RSTRING(str)->len != 8) {
+ buf = (unsigned char *)RSTRING_PTR(str);
+ if (RSTRING_LEN(str) != 8) {
rb_raise(rb_eTypeError, "marshaled time format differ");
}
diff --git a/variable.c b/variable.c
index 2374e3fe70..47ef4dd54a 100644
--- a/variable.c
+++ b/variable.c
@@ -235,7 +235,7 @@ rb_path2class(const char *path)
while (*p && *p != ':') p++;
str = rb_str_new(pbeg, p-pbeg);
- id = rb_intern(RSTRING(str)->ptr);
+ id = rb_intern(RSTRING_PTR(str));
if (p[0] == ':') {
if (p[1] != ':') goto undefined_class;
p += 2;
@@ -273,7 +273,7 @@ rb_class_name(VALUE klass)
char *
rb_class2name(VALUE klass)
{
- return RSTRING(rb_class_name(klass))->ptr;
+ return RSTRING_PTR(rb_class_name(klass));
}
char *
@@ -1155,7 +1155,7 @@ check_autoload_table(VALUE av)
Check_Type(av, T_DATA);
if (RDATA(av)->dmark != (RUBY_DATA_FUNC)rb_mark_tbl ||
RDATA(av)->dfree != (RUBY_DATA_FUNC)st_free_table) {
- rb_raise(rb_eTypeError, "wrong autoload table: %s", RSTRING(rb_inspect(av))->ptr);
+ rb_raise(rb_eTypeError, "wrong autoload table: %s", RSTRING_PTR(rb_inspect(av)));
}
return (struct st_table *)DATA_PTR(av);
}
@@ -1223,7 +1223,7 @@ rb_autoload_load(VALUE klass, ID id)
VALUE file;
NODE *load = autoload_delete(klass, id);
- if (!load || !(file = load->nd_lit) || rb_provided(RSTRING(file)->ptr)) {
+ if (!load || !(file = load->nd_lit) || rb_provided(RSTRING_PTR(file))) {
return Qfalse;
}
return rb_require_safe(file, load->nd_nth);
@@ -1242,10 +1242,10 @@ autoload_file(VALUE mod, ID id)
}
file = ((NODE *)load)->nd_lit;
Check_Type(file, T_STRING);
- if (!RSTRING(file)->ptr) {
+ if (!RSTRING_PTR(file)) {
rb_raise(rb_eArgError, "empty file name");
}
- if (!rb_provided(RSTRING(file)->ptr)) {
+ if (!rb_provided(RSTRING_PTR(file))) {
return file;
}