*/
#include <ctype.h>
-#ifndef SIZE_MAX
- /* Some versions of VC++
- * has SIZE_MAX in stdint.h
- */
-# include <limits.h>
-#endif
+#include <limits.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
@@ -30,9 +25,6 @@ typedef struct mrb_shared_string {
mrb_int len;
} mrb_shared_string;
-#define MRB_STR_SHARED 1
-#define MRB_STR_NOFREE 2
-
static mrb_value str_replace(mrb_state *mrb, struct RString *s1, struct RString *s2);
static mrb_value mrb_str_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len);
@@ -62,6 +54,7 @@ mrb_str_modify(mrb_state *mrb, struct RString *s)
if (shared->refcnt == 1 && s->ptr == shared->ptr) {
s->ptr = shared->ptr;
s->aux.capa = shared->len;
+ s->ptr[s->len] = '\0';
mrb_free(mrb, shared);
}
else {
@@ -74,7 +67,7 @@ mrb_str_modify(mrb_state *mrb, struct RString *s)
if (p) {
memcpy(ptr, p, len);
}
- ptr[len] = 0;
+ ptr[len] = '\0';
s->ptr = ptr;
s->aux.capa = len;
str_decref(mrb, shared);
@@ -91,6 +84,7 @@ mrb_str_modify(mrb_state *mrb, struct RString *s)
}
s->ptr[s->len] = '\0';
s->aux.capa = s->len;
+ s->flags &= ~MRB_STR_NOFREE;
return;
}
}
@@ -113,16 +107,6 @@ mrb_str_resize(mrb_state *mrb, mrb_value str, mrb_int len)
return str;
}
-static inline void
-str_mod_check(mrb_state *mrb, mrb_value str, char *p, mrb_int len)
-{
- struct RString *s = mrb_str_ptr(str);
-
- if (s->ptr != p || s->len != len) {
- mrb_raise(mrb, E_RUNTIME_ERROR, "string modified");
- }
-}
-
#define mrb_obj_alloc_string(mrb) ((struct RString*)mrb_obj_alloc((mrb), MRB_TT_STRING, (mrb)->string_class))
/* char offset to byte offset */
@@ -331,34 +315,6 @@ str_make_shared(mrb_state *mrb, struct RString *s)
}
/*
- * call-seq: (Caution! string literal)
- * String.new(str="") => new_str
- *
- * Returns a new string object containing a copy of <i>str</i>.
- */
-
-mrb_value
-mrb_str_literal(mrb_state *mrb, mrb_value str)
-{
- struct RString *s, *orig;
- mrb_shared_string *shared;
-
- s = mrb_obj_alloc_string(mrb);
- orig = mrb_str_ptr(str);
- if (!(orig->flags & MRB_STR_SHARED)) {
- str_make_shared(mrb, orig);
- }
- shared = orig->aux.shared;
- shared->refcnt++;
- s->ptr = shared->ptr;
- s->len = shared->len;
- s->aux.shared = shared;
- s->flags |= MRB_STR_SHARED;
-
- return mrb_obj_value(s);
-}
-
-/*
* call-seq:
* char* str = String("abcd"), len=strlen("abcd")
*
@@ -398,7 +354,7 @@ mrb_str_concat(mrb_state *mrb, mrb_value self, mrb_value other)
}
memcpy(s1->ptr+s1->len, s2->ptr, s2->len);
s1->len = len;
- s1->ptr[len] = 0;
+ s1->ptr[len] = '\0';
}
/*
@@ -573,10 +529,10 @@ mrb_str_cmp_m(mrb_state *mrb, mrb_value str1)
mrb_get_args(mrb, "o", &str2);
if (!mrb_string_p(str2)) {
- if (!mrb_respond_to(mrb, str2, mrb_intern2(mrb, "to_s", 4))) {
+ if (!mrb_respond_to(mrb, str2, mrb_intern_lit(mrb, "to_s"))) {
return mrb_nil_value();
}
- else if (!mrb_respond_to(mrb, str2, mrb_intern2(mrb, "<=>", 3))) {
+ else if (!mrb_respond_to(mrb, str2, mrb_intern_lit(mrb, "<=>"))) {
return mrb_nil_value();
}
else {
@@ -595,7 +551,7 @@ mrb_str_cmp_m(mrb_state *mrb, mrb_value str1)
return mrb_fixnum_value(result);
}
-static int
+static mrb_bool
str_eql(mrb_state *mrb, const mrb_value str1, const mrb_value str2)
{
const mrb_int len = RSTRING_LEN(str1);
@@ -606,13 +562,13 @@ str_eql(mrb_state *mrb, const mrb_value str1, const mrb_value str2)
return FALSE;
}
-int
+mrb_bool
mrb_str_equal(mrb_state *mrb, mrb_value str1, mrb_value str2)
{
if (mrb_obj_equal(mrb, str1, str2)) return TRUE;
if (!mrb_string_p(str2)) {
if (mrb_nil_p(str2)) return FALSE;
- if (!mrb_respond_to(mrb, str2, mrb_intern2(mrb, "to_str", 6))) {
+ if (!mrb_respond_to(mrb, str2, mrb_intern_lit(mrb, "to_str"))) {
return FALSE;
}
str2 = mrb_funcall(mrb, str2, "to_str", 0);
@@ -785,12 +741,10 @@ num_index:
/* check if indx is Range */
{
mrb_int beg, len;
- mrb_value tmp;
len = RSTRING_LEN(str);
if (mrb_range_beg_len(mrb, indx, &beg, &len, len)) {
- tmp = mrb_str_subseq(mrb, str, beg, len);
- return tmp;
+ return mrb_str_subseq(mrb, str, beg, len);
}
else {
return mrb_nil_value();
@@ -1277,7 +1231,7 @@ mrb_str_include(mrb_state *mrb, mrb_value self)
mrb_bool include_p;
mrb_get_args(mrb, "o", &str2);
- if (mrb_type(str2) == MRB_TT_FIXNUM) {
+ if (mrb_fixnum_p(str2)) {
include_p = (memchr(RSTRING_PTR(self), mrb_fixnum(str2), RSTRING_LEN(self)) != NULL);
}
else {
@@ -1499,7 +1453,7 @@ mrb_ptr_to_str(mrb_state *mrb, void *p)
struct RString *p_str;
char *p1;
char *p2;
- intptr_t n = (intptr_t)p;
+ uintptr_t n = (uintptr_t)p;
p_str = str_new(mrb, NULL, 2 + sizeof(uintptr_t) * CHAR_BIT / 4);
p1 = p_str->ptr;
@@ -1524,6 +1478,12 @@ mrb_ptr_to_str(mrb_state *mrb, void *p)
}
mrb_value
+mrb_string_type(mrb_state *mrb, mrb_value str)
+{
+ return mrb_convert_type(mrb, str, MRB_TT_STRING, "String", "to_str");
+}
+
+mrb_value
mrb_check_string_type(mrb_state *mrb, mrb_value str)
{
return mrb_check_convert_type(mrb, str, MRB_TT_STRING, "String", "to_str");
@@ -2347,47 +2307,47 @@ mrb_str_dump(mrb_state *mrb, mrb_value str)
*q++ = '\\';
*q++ = 'n';
break;
-
+
case '\r':
*q++ = '\\';
*q++ = 'r';
break;
-
+
case '\t':
*q++ = '\\';
*q++ = 't';
break;
-
+
case '\f':
*q++ = '\\';
*q++ = 'f';
break;
-
+
case '\013':
*q++ = '\\';
*q++ = 'v';
break;
-
+
case '\010':
*q++ = '\\';
*q++ = 'b';
break;
-
+
case '\007':
*q++ = '\\';
*q++ = 'a';
break;
-
+
case '\033':
*q++ = '\\';
*q++ = 'e';
break;
-
+
case '#':
if (IS_EVSTR(p, pend)) *q++ = '\\';
*q++ = '#';
break;
-
+
default:
if (ISPRINT(c)) {
*q++ = c;
@@ -2450,7 +2410,7 @@ mrb_str_inspect(mrb_state *mrb, mrb_value str)
p = RSTRING_PTR(str); pend = RSTRING_END(str);
for (;p < pend; p++) {
- unsigned int c, cc;
+ unsigned char c, cc;
c = *p;
if (c == '"'|| c == '\\' || (c == '#' && IS_EVSTR(p, pend))) {
@@ -2527,14 +2487,13 @@ mrb_init_string(mrb_state *mrb)
MRB_SET_INSTANCE_TT(s, MRB_TT_STRING);
mrb_include_module(mrb, s, mrb_class_get(mrb, "Comparable"));
- mrb_define_method(mrb, s, "+", mrb_str_plus_m, MRB_ARGS_REQ(1)); /* 15.2.10.5.2 */
+
mrb_define_method(mrb, s, "bytesize", mrb_str_bytesize, MRB_ARGS_NONE());
- mrb_define_method(mrb, s, "size", mrb_str_size, MRB_ARGS_NONE()); /* 15.2.10.5.33 */
- mrb_define_method(mrb, s, "length", mrb_str_size, MRB_ARGS_NONE()); /* 15.2.10.5.26 */
- mrb_define_method(mrb, s, "*", mrb_str_times, MRB_ARGS_REQ(1)); /* 15.2.10.5.1 */
- mrb_define_method(mrb, s, "<=>", mrb_str_cmp_m, MRB_ARGS_REQ(1)); /* 15.2.10.5.3 */
- mrb_define_method(mrb, s, "==", mrb_str_equal_m, MRB_ARGS_REQ(1)); /* 15.2.10.5.4 */
- mrb_define_method(mrb, s, "=~", noregexp, MRB_ARGS_REQ(1)); /* 15.2.10.5.5 */
+
+ mrb_define_method(mrb, s, "<=>", mrb_str_cmp_m, MRB_ARGS_REQ(1)); /* 15.2.10.5.1 */
+ mrb_define_method(mrb, s, "==", mrb_str_equal_m, MRB_ARGS_REQ(1)); /* 15.2.10.5.2 */
+ mrb_define_method(mrb, s, "+", mrb_str_plus_m, MRB_ARGS_REQ(1)); /* 15.2.10.5.4 */
+ mrb_define_method(mrb, s, "*", mrb_str_times, MRB_ARGS_REQ(1)); /* 15.2.10.5.5 */
mrb_define_method(mrb, s, "[]", mrb_str_aref_m, MRB_ARGS_ANY()); /* 15.2.10.5.6 */
mrb_define_method(mrb, s, "capitalize", mrb_str_capitalize, MRB_ARGS_NONE()); /* 15.2.10.5.7 */
mrb_define_method(mrb, s, "capitalize!", mrb_str_capitalize_bang, MRB_ARGS_REQ(1)); /* 15.2.10.5.8 */
@@ -2547,31 +2506,25 @@ mrb_init_string(mrb_state *mrb)
mrb_define_method(mrb, s, "empty?", mrb_str_empty_p, MRB_ARGS_NONE()); /* 15.2.10.5.16 */
mrb_define_method(mrb, s, "eql?", mrb_str_eql, MRB_ARGS_REQ(1)); /* 15.2.10.5.17 */
- // NOTE: Regexp not implemented
- mrb_define_method(mrb, s, "gsub", noregexp, MRB_ARGS_REQ(1)); /* 15.2.10.5.18 */
- mrb_define_method(mrb, s, "gsub!", noregexp, MRB_ARGS_REQ(1)); /* 15.2.10.5.19 */
-
mrb_define_method(mrb, s, "hash", mrb_str_hash_m, MRB_ARGS_REQ(1)); /* 15.2.10.5.20 */
mrb_define_method(mrb, s, "include?", mrb_str_include, MRB_ARGS_REQ(1)); /* 15.2.10.5.21 */
mrb_define_method(mrb, s, "index", mrb_str_index_m, MRB_ARGS_ANY()); /* 15.2.10.5.22 */
mrb_define_method(mrb, s, "initialize", mrb_str_init, MRB_ARGS_REQ(1)); /* 15.2.10.5.23 */
mrb_define_method(mrb, s, "initialize_copy", mrb_str_replace, MRB_ARGS_REQ(1)); /* 15.2.10.5.24 */
mrb_define_method(mrb, s, "intern", mrb_str_intern, MRB_ARGS_NONE()); /* 15.2.10.5.25 */
- mrb_define_method(mrb, s, "match", noregexp, MRB_ARGS_REQ(1)); /* 15.2.10.5.27 */
+ mrb_define_method(mrb, s, "length", mrb_str_size, MRB_ARGS_NONE()); /* 15.2.10.5.26 */
mrb_define_method(mrb, s, "replace", mrb_str_replace, MRB_ARGS_REQ(1)); /* 15.2.10.5.28 */
mrb_define_method(mrb, s, "reverse", mrb_str_reverse, MRB_ARGS_NONE()); /* 15.2.10.5.29 */
mrb_define_method(mrb, s, "reverse!", mrb_str_reverse_bang, MRB_ARGS_NONE()); /* 15.2.10.5.30 */
mrb_define_method(mrb, s, "rindex", mrb_str_rindex_m, MRB_ARGS_ANY()); /* 15.2.10.5.31 */
- mrb_define_method(mrb, s, "scan", noregexp, MRB_ARGS_REQ(1)); /* 15.2.10.5.32 */
+ mrb_define_method(mrb, s, "size", mrb_str_size, MRB_ARGS_NONE()); /* 15.2.10.5.33 */
mrb_define_method(mrb, s, "slice", mrb_str_aref_m, MRB_ARGS_ANY()); /* 15.2.10.5.34 */
mrb_define_method(mrb, s, "split", mrb_str_split_m, MRB_ARGS_ANY()); /* 15.2.10.5.35 */
- mrb_define_method(mrb, s, "sub", noregexp, MRB_ARGS_REQ(1)); /* 15.2.10.5.36 */
- mrb_define_method(mrb, s, "sub!", noregexp, MRB_ARGS_REQ(1)); /* 15.2.10.5.37 */
- mrb_define_method(mrb, s, "to_i", mrb_str_to_i, MRB_ARGS_ANY()); /* 15.2.10.5.38 */
- mrb_define_method(mrb, s, "to_f", mrb_str_to_f, MRB_ARGS_NONE()); /* 15.2.10.5.39 */
+ mrb_define_method(mrb, s, "to_f", mrb_str_to_f, MRB_ARGS_NONE()); /* 15.2.10.5.38 */
+ mrb_define_method(mrb, s, "to_i", mrb_str_to_i, MRB_ARGS_ANY()); /* 15.2.10.5.39 */
mrb_define_method(mrb, s, "to_s", mrb_str_to_s, MRB_ARGS_NONE()); /* 15.2.10.5.40 */
- mrb_define_method(mrb, s, "to_str", mrb_str_to_s, MRB_ARGS_NONE()); /* 15.2.10.5.40 */
+ mrb_define_method(mrb, s, "to_str", mrb_str_to_s, MRB_ARGS_NONE());
mrb_define_method(mrb, s, "to_sym", mrb_str_intern, MRB_ARGS_NONE()); /* 15.2.10.5.41 */
mrb_define_method(mrb, s, "upcase", mrb_str_upcase, MRB_ARGS_REQ(1)); /* 15.2.10.5.42 */
mrb_define_method(mrb, s, "upcase!", mrb_str_upcase_bang, MRB_ARGS_REQ(1)); /* 15.2.10.5.43 */