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 + + * 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 * 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; ilen; 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; ilen; 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; ilen; 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;ilen;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; ilen == 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>= 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; iptr; + t = RSTRING_PTR(bitstr); for (i=0; i>= 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; iptr; + 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; iptr; + 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), ®s, 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 RESIZE_CAPA(str,capacity) do {\ - REALLOC_N(RSTRING(str)->ptr, char, (capacity)+1);\ - if (!FL_TEST(str, STR_NOCAPA))\ - RSTRING(str)->aux.capa = (capacity);\ +#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 {\ + 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 (ptr) { - memcpy(RSTRING(str)->ptr, ptr, len); + 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); } - RSTRING(str)->ptr[len] = '\0'; + if (ptr) { + memcpy(RSTRING_PTR(str), ptr, len); + } + 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); } - RSTRING(str)->len = len; - RSTRING(str)->ptr[len] = '\0'; /* sentinel */ + 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)->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 (;poslen; + 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; ilen; i++) { - rb_yield(INT2FIX(RSTRING(str)->ptr[i] & 0xff)); + for (i=0; ilen > 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; }