Reorganize `mrb_string_value_cstr` and related functions.
`mrb_string_value_cstr` and `mrb_string_value_len`: obsolete
`mrb_string_cstr`: new function to retrieve NULL terminated C string
`RSTRING_CSTR`: wrapper macro of `mrb_string_cstr`
MODIFY
include/mruby/string.h
include/mruby/string.h
@@ -96,6 +96,7 @@ struct RString {
#define RSTRING_CAPA(s) RSTR_CAPA(RSTRING(s))
#define RSTRING_END(s) (RSTRING_PTR(s) + RSTRING_LEN(s))
MRB_API mrb_int mrb_str_strlen(mrb_state*, struct RString*);
+#define RSTRING_CSTR(mrb,s) mrb_string_cstr(mrb, s)
#define MRB_STR_SHARED 1
#define MRB_STR_FSHARED 2
@@ -337,16 +338,13 @@ MRB_API mrb_value mrb_string_type(mrb_state *mrb, mrb_value str);
MRB_API mrb_value mrb_str_new_capa(mrb_state *mrb, size_t capa);
MRB_API mrb_value mrb_str_buf_new(mrb_state *mrb, size_t capa);
-MRB_API const char *mrb_string_value_cstr(mrb_state *mrb, mrb_value *ptr);
+/* NULL terminated C string from mrb_value */
+MRB_API const char *mrb_string_cstr(mrb_state *mrb, mrb_value str);
+/* NULL terminated C string from mrb_value; `str` will be updated */
+MRB_API const char *mrb_string_value_cstr(mrb_state *mrb, mrb_value *str);
+/* obslete: use RSTRING_PTR() */
MRB_API const char *mrb_string_value_ptr(mrb_state *mrb, mrb_value str);
-/*
- * Returns the length of the Ruby string.
- *
- *
- * @param [mrb_state] mrb The current mruby state.
- * @param [mrb_value] str Ruby string.
- * @return [mrb_int] The length of the passed in Ruby string.
- */
+/* obslete: use RSTRING_LEN() */
MRB_API mrb_int mrb_string_value_len(mrb_state *mrb, mrb_value str);
/*

MODIFY
mrbgems/mruby-io/src/file.c
mrbgems/mruby-io/src/file.c
@@ -116,7 +116,7 @@ mrb_file_s_unlink(mrb_state *mrb, mrb_value obj)
for (i = 0; i < argc; i++) {
const char *utf8_path;
pathv = mrb_ensure_string_type(mrb, argv[i]);
- utf8_path = mrb_string_value_cstr(mrb, &pathv);
+ utf8_path = RSTRING_CSTR(mrb, pathv);
path = mrb_locale_from_utf8(utf8_path, -1);
if (UNLINK(path) < 0) {
mrb_locale_free(path);
@@ -134,8 +134,8 @@ mrb_file_s_rename(mrb_state *mrb, mrb_value obj)
char *src, *dst;
mrb_get_args(mrb, "SS", &from, &to);
- src = mrb_locale_from_utf8(mrb_string_value_cstr(mrb, &from), -1);
- dst = mrb_locale_from_utf8(mrb_string_value_cstr(mrb, &to), -1);
+ src = mrb_locale_from_utf8(RSTRING_CSTR(mrb, from), -1);
+ dst = mrb_locale_from_utf8(RSTRING_CSTR(mrb, to), -1);
if (rename(src, dst) < 0) {
#if defined(_WIN32) || defined(_WIN64)
if (CHMOD(dst, 0666) == 0 && UNLINK(dst) == 0 && rename(src, dst) == 0) {
@@ -146,7 +146,7 @@ mrb_file_s_rename(mrb_state *mrb, mrb_value obj)
#endif
mrb_locale_free(src);
mrb_locale_free(dst);
- mrb_sys_fail(mrb, RSTRING_PTR(mrb_format(mrb, "(%v, %v)", from, to)));
+ mrb_sys_fail(mrb, RSTRING_CSTR(mrb, mrb_format(mrb, "(%v, %v)", from, to)));
}
mrb_locale_free(src);
mrb_locale_free(dst);
@@ -248,7 +248,7 @@ mrb_file_realpath(mrb_state *mrb, mrb_value klass)
s = mrb_str_append(mrb, s, pathname);
pathname = s;
}
- cpath = mrb_locale_from_utf8(mrb_string_value_cstr(mrb, &pathname), -1);
+ cpath = mrb_locale_from_utf8(RSTRING_CSTR(mrb, pathname), -1);
result = mrb_str_buf_new(mrb, PATH_MAX);
if (realpath(cpath, RSTRING_PTR(result)) == NULL) {
mrb_locale_free(cpath);
@@ -300,7 +300,7 @@ mrb_file__gethome(mrb_state *mrb, mrb_value klass)
mrb_raise(mrb, E_ARGUMENT_ERROR, "non-absolute home");
}
} else {
- const char *cuser = mrb_string_value_cstr(mrb, &username);
+ const char *cuser = RSTRING_CSTR(mrb, username);
struct passwd *pwd = getpwnam(cuser);
if (pwd == NULL) {
return mrb_nil_value();
@@ -393,12 +393,12 @@ mrb_file_s_symlink(mrb_state *mrb, mrb_value klass)
int ai = mrb_gc_arena_save(mrb);
mrb_get_args(mrb, "SS", &from, &to);
- src = mrb_locale_from_utf8(mrb_string_value_cstr(mrb, &from), -1);
- dst = mrb_locale_from_utf8(mrb_string_value_cstr(mrb, &to), -1);
+ src = mrb_locale_from_utf8(RSTRING_CSTR(mrb, from), -1);
+ dst = mrb_locale_from_utf8(RSTRING_CSTR(mrb, to), -1);
if (symlink(src, dst) == -1) {
mrb_locale_free(src);
mrb_locale_free(dst);
- mrb_sys_fail(mrb, RSTRING_PTR(mrb_format(mrb, "(%v, %v)", from, to)));
+ mrb_sys_fail(mrb, RSTRING_CSTR(mrb, mrb_format(mrb, "(%v, %v)", from, to)));
}
mrb_locale_free(src);
mrb_locale_free(dst);
@@ -416,7 +416,7 @@ mrb_file_s_chmod(mrb_state *mrb, mrb_value klass) {
mrb_get_args(mrb, "i*", &mode, &filenames, &argc);
for (i = 0; i < argc; i++) {
- const char *utf8_path = mrb_string_value_cstr(mrb, &filenames[i]);
+ const char *utf8_path = RSTRING_CSTR(mrb, filenames[i]);
char *path = mrb_locale_from_utf8(utf8_path, -1);
if (CHMOD(path, mode) == -1) {
mrb_locale_free(path);

MODIFY
mrbgems/mruby-io/src/file_test.c
mrbgems/mruby-io/src/file_test.c
@@ -54,7 +54,7 @@ mrb_stat0(mrb_state *mrb, mrb_value obj, struct stat *st, int do_lstat)
return -1;
}
else {
- char *path = mrb_locale_from_utf8(mrb_string_value_cstr(mrb, &obj), -1);
+ char *path = mrb_locale_from_utf8(RSTRING_CSTR(mrb, obj), -1);
int ret;
if (do_lstat) {
ret = LSTAT(path, st);

MODIFY
mrbgems/mruby-io/src/io.c
mrbgems/mruby-io/src/io.c
@@ -332,8 +332,8 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
mrb_get_args(mrb, "S|SH", &cmd, &mode, &opt);
io = mrb_obj_value(mrb_data_object_alloc(mrb, mrb_class_ptr(klass), NULL, &mrb_io_type));
- pname = mrb_string_value_cstr(mrb, &cmd);
- flags = mrb_io_modestr_to_flags(mrb, mrb_string_value_cstr(mrb, &mode));
+ pname = RSTRING_CSTR(mrb, cmd);
+ flags = mrb_io_modestr_to_flags(mrb, RSTRING_CSTR(mrb, mode));
doexec = (strcmp("-", pname) != 0);
opt_in = option_to_fd(mrb, opt, "in");
@@ -428,8 +428,8 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
mrb_get_args(mrb, "S|SH", &cmd, &mode, &opt);
io = mrb_obj_value(mrb_data_object_alloc(mrb, mrb_class_ptr(klass), NULL, &mrb_io_type));
- pname = mrb_string_value_cstr(mrb, &cmd);
- flags = mrb_io_modestr_to_flags(mrb, mrb_string_value_cstr(mrb, &mode));
+ pname = RSTRING_CSTR(mrb, cmd);
+ flags = mrb_io_modestr_to_flags(mrb, RSTRING_CSTR(mrb, mode));
doexec = (strcmp("-", pname) != 0);
opt_in = option_to_fd(mrb, opt, "in");
@@ -626,7 +626,7 @@ mrb_io_initialize(mrb_state *mrb, mrb_value io)
opt = mrb_hash_new(mrb);
}
- flags = mrb_io_modestr_to_flags(mrb, mrb_string_value_cstr(mrb, &mode));
+ flags = mrb_io_modestr_to_flags(mrb, RSTRING_CSTR(mrb, mode));
mrb_iv_set(mrb, io, mrb_intern_cstr(mrb, "@buf"), mrb_str_new_cstr(mrb, ""));
@@ -780,7 +780,7 @@ reopen:
}
}
- mrb_sys_fail(mrb, RSTRING_PTR(mrb_format(mrb, "open %s", pathname)));
+ mrb_sys_fail(mrb, RSTRING_CSTR(mrb, mrb_format(mrb, "open %s", pathname)));
}
mrb_locale_free(fname);
@@ -807,8 +807,8 @@ mrb_io_s_sysopen(mrb_state *mrb, mrb_value klass)
perm = 0666;
}
- pat = mrb_string_value_cstr(mrb, &path);
- flags = mrb_io_modestr_to_flags(mrb, mrb_string_value_cstr(mrb, &mode));
+ pat = RSTRING_CSTR(mrb, path);
+ flags = mrb_io_modestr_to_flags(mrb, RSTRING_CSTR(mrb, mode));
modenum = mrb_io_flags_to_modenum(mrb, flags);
fd = mrb_cloexec_open(mrb, pat, modenum, perm);
return mrb_fixnum_value(fd);

MODIFY
mrbgems/mruby-socket/src/socket.c
mrbgems/mruby-socket/src/socket.c
@@ -131,7 +131,7 @@ mrb_addrinfo_getaddrinfo(mrb_state *mrb, mrb_value klass)
mrb_get_args(mrb, "oo|oooi", &nodename, &service, &family, &socktype, &protocol, &flags);
if (mrb_string_p(nodename)) {
- hostname = mrb_string_value_cstr(mrb, &nodename);
+ hostname = RSTRING_CSTR(mrb, nodename);
} else if (mrb_nil_p(nodename)) {
hostname = NULL;
} else {
@@ -139,7 +139,7 @@ mrb_addrinfo_getaddrinfo(mrb_state *mrb, mrb_value klass)
}
if (mrb_string_p(service)) {
- servname = mrb_string_value_cstr(mrb, &service);
+ servname = RSTRING_CSTR(mrb, service);
} else if (mrb_fixnum_p(service)) {
servname = RSTRING_PTR(mrb_fixnum_to_str(mrb, service, 10));
} else if (mrb_nil_p(service)) {

MODIFY
mrbgems/mruby-test/vformat.c
mrbgems/mruby-test/vformat.c
@@ -166,7 +166,7 @@ vf_s_format(mrb_state *mrb, mrb_value klass)
{
mrb_value fmt_str, args[2];
mrb_int argc = mrb_get_args(mrb, "S|oo", &fmt_str, args, args+1);
- const char *fmt = mrb_string_value_cstr(mrb, &fmt_str);
+ const char *fmt = RSTRING_CSTR(mrb, fmt_str);
VF_FORMAT_INIT(klass);

MODIFY
src/class.c
src/class.c
@@ -770,7 +770,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
}
if (i < argc) {
ss = to_str(mrb, ARGV[arg_i++]);
- *ps = mrb_string_value_cstr(mrb, &ss);
+ *ps = RSTRING_CSTR(mrb, ss);
i++;
}
}

MODIFY
src/string.c
src/string.c
@@ -1060,6 +1060,7 @@ mrb_str_to_str(mrb_state *mrb, mrb_value str)
}
}
+/* obslete: use RSTRING_PTR() */
MRB_API const char*
mrb_string_value_ptr(mrb_state *mrb, mrb_value str)
{
@@ -1067,6 +1068,7 @@ mrb_string_value_ptr(mrb_state *mrb, mrb_value str)
return RSTRING_PTR(str);
}
+/* obslete: use RSTRING_LEN() */
MRB_API mrb_int
mrb_string_value_len(mrb_state *mrb, mrb_value ptr)
{
@@ -2352,6 +2354,7 @@ mrb_cstr_to_inum(mrb_state *mrb, const char *str, mrb_int base, mrb_bool badchec
return mrb_str_len_to_inum(mrb, str, strlen(str), base, badcheck);
}
+/* obslete: use RSTRING_CSTR() or mrb_string_cstr() */
MRB_API const char*
mrb_string_value_cstr(mrb_state *mrb, mrb_value *ptr)
{
@@ -2366,16 +2369,23 @@ mrb_string_value_cstr(mrb_state *mrb, mrb_value *ptr)
if (p[len] == '\0') {
return p;
}
- else {
- if (MRB_FROZEN_P(ps)) {
- ps = str_new(mrb, p, len);
+ if (MRB_FROZEN_P(ps) || RSTR_CAPA(ps) == len) {
+ ps = str_new(mrb, NULL, len+1);
+ memcpy(RSTR_PTR(ps), p, len);
+ RSTR_SET_LEN(ps, len);
*ptr = mrb_obj_value(ps);
}
else {
mrb_str_modify(mrb, ps);
}
+ RSTR_PTR(ps)[len] = '\0';
return RSTR_PTR(ps);
}
+
+MRB_API const char*
+mrb_string_cstr(mrb_state *mrb, mrb_value str)
+{
+ return mrb_string_value_cstr(mrb, &str);
}
MRB_API mrb_value
@@ -2489,7 +2499,7 @@ bad:
MRB_API double
mrb_str_to_dbl(mrb_state *mrb, mrb_value str, mrb_bool badcheck)
{
- return mrb_cstr_to_dbl(mrb, mrb_string_value_cstr(mrb, &str), badcheck);
+ return mrb_cstr_to_dbl(mrb, RSTRING_CSTR(mrb, str), badcheck);
}
/* 15.2.10.5.39 */

Reorganize `mrb_string_value_cstr` and related functions.

`mrb_string_value_cstr` and `mrb_string_value_len`: obsolete
`mrb_string_cstr`: new function to retrieve NULL terminated C string
`RSTRING_CSTR`: wrapper macro of `mrb_string_cstr`