summaryrefslogtreecommitdiff
path: root/string.c
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2002-07-26 06:12:39 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2002-07-26 06:12:39 +0000
commit7194b66fb24db63dc2a23d3141ce25ad85d89777 (patch)
tree6e4a442522711c87eb3fc61bf81efc90af356394 /string.c
parent1d132e648dff057f0a5b42ddbc3704e7816213fc (diff)
* random.c: replace with Mersenne Twister RNG.
* eval.c (jump_tag_but_local_jump): preserve retval in LocalJumpError exceptions. * parse.y (command): no more check for "super outside of method". * eval.c (rb_mod_define_method): should set last_class and last_func in the block->frame. * eval.c (error_handle): should handle TAG_THROW as well. * parse.y (yylex): new decimal notation '0d4567'. * parse.y (yylex): new octal notation '0o777'. * parse.y (string_content): every string_content node should return string only. use NODE_EVSTR to coercing. * eval.c (rb_eval): NODE_EVSTR support. * re.c (rb_reg_quote): avoid unnecessary string allocation. * string.c (get_pat): quote metachracters before compiling a string into a regex. * string.c (rb_str_split_m): special treatment of strings of size 1, but AWK emulation. now uses get_pat(). * string.c (rb_str_match_m): quote metacharacters. * string.c (rb_str_match2): ditto. * ext/socket/socket.c (sock_addrinfo): make all 3 versions of getaddrinfo happy. [ruby-core:00184] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2654 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'string.c')
-rw-r--r--string.c144
1 files changed, 74 insertions, 70 deletions
diff --git a/string.c b/string.c
index cba8d340c5..e687fcc533 100644
--- a/string.c
+++ b/string.c
@@ -889,16 +889,44 @@ rb_str_index_m(argc, argv, str)
return INT2NUM(pos);
}
+static long
+rb_str_rindex(str, sub, pos)
+ VALUE str, sub;
+ long pos;
+{
+ long len = RSTRING(sub)->len;
+ 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;
+ }
+ sbeg = RSTRING(str)->ptr;
+ s = RSTRING(str)->ptr + pos;
+ t = RSTRING(sub)->ptr;
+ if (len) {
+ while (sbeg <= s) {
+ if (rb_memcmp(s, t, len) == 0) {
+ return s - RSTRING(str)->ptr;
+ }
+ s--;
+ }
+ }
+ else {
+ return pos;
+ }
+}
+
static VALUE
-rb_str_rindex(argc, argv, str)
+rb_str_rindex_m(argc, argv, str)
int argc;
VALUE *argv;
VALUE str;
{
VALUE sub;
VALUE position;
- int pos, len;
- char *s, *sbeg, *t;
+ int pos;
if (rb_scan_args(argc, argv, "11", &sub, &position) == 2) {
pos = NUM2INT(position);
@@ -927,26 +955,8 @@ rb_str_rindex(argc, argv, str)
break;
case T_STRING:
- len = RSTRING(sub)->len;
- /* substring longer than string */
- if (RSTRING(str)->len < len) return Qnil;
- if (RSTRING(str)->len - pos < len) {
- pos = RSTRING(str)->len - len;
- }
- sbeg = RSTRING(str)->ptr;
- s = RSTRING(str)->ptr + pos;
- t = RSTRING(sub)->ptr;
- if (len) {
- while (sbeg <= s) {
- if (rb_memcmp(s, t, len) == 0) {
- return INT2NUM(s - RSTRING(str)->ptr);
- }
- s--;
- }
- }
- else {
- return INT2NUM(pos);
- }
+ pos = rb_str_rindex(str, sub, pos);
+ if (pos >= 0) return INT2NUM(pos);
break;
case T_FIXNUM:
@@ -996,7 +1006,7 @@ rb_str_match2(str)
VALUE str;
{
StringValue(str);
- return rb_reg_match2(rb_reg_regcomp(str));
+ return rb_reg_match2(rb_reg_regcomp(rb_reg_quote(str)));
}
static VALUE
@@ -1007,7 +1017,7 @@ rb_str_match_m(str, re)
if (!NIL_P(str2)) {
StringValue(re);
- re = rb_reg_regcomp(re);
+ re = rb_reg_regcomp(rb_reg_quote(re));
}
return rb_funcall(re, rb_intern("match"), 1, str);
}
@@ -1397,19 +1407,29 @@ static VALUE
get_pat(pat)
VALUE pat;
{
+ VALUE val;
+
switch (TYPE(pat)) {
case T_REGEXP:
- break;
+ return pat;
case T_STRING:
- pat = rb_reg_regcomp(pat);
break;
default:
- /* type failed */
- Check_Type(pat, T_REGEXP);
+ val = rb_check_convert_type(pat, T_STRING, "String", "to_str");
+ if (NIL_P(val)) {
+ Check_Type(pat, T_REGEXP);
+ }
+ pat = val;
+ }
+ val = rb_reg_quote(pat);
+#if RUBY_VERSION_CODE < 180
+ if (val != pat) {
+ rb_warn("string pattern instead of regexp; metacharacters no longer effective");
}
- return pat;
+#endif
+ return rb_reg_regcomp(val);
}
static VALUE
@@ -2449,7 +2469,7 @@ rb_str_split_m(argc, argv, str)
{
VALUE spat;
VALUE limit;
- int char_sep = -1;
+ int awk_split = Qfalse;
long beg, end, i = 0;
int lim = 0;
VALUE result, tmp;
@@ -2466,67 +2486,51 @@ rb_str_split_m(argc, argv, str)
spat = rb_fs;
goto fs_set;
}
- char_sep = ' ';
+ awk_split = Qtrue;
}
else {
fs_set:
- switch (TYPE(spat)) {
- case T_STRING:
- if (RSTRING(spat)->len == 1) {
- char_sep = (unsigned char)RSTRING(spat)->ptr[0];
+ if (TYPE(spat) == T_STRING && RSTRING(spat)->len == 1) {
+ if (RSTRING(spat)->ptr[0] == ' ') {
+ awk_split = Qtrue;
}
else {
- spat = rb_reg_regcomp(spat);
+ spat = rb_reg_regcomp(rb_reg_quote(spat));
}
- break;
- case T_REGEXP:
- break;
- default:
- rb_raise(rb_eArgError, "bad separator");
+ }
+ else {
+ spat = get_pat(spat);
}
}
result = rb_ary_new();
beg = 0;
- if (char_sep >= 0) {
+ if (awk_split) {
char *ptr = RSTRING(str)->ptr;
long len = RSTRING(str)->len;
char *eptr = ptr + len;
+ int skip = 1;
- if (char_sep == ' ') { /* AWK emulation */
- int skip = 1;
-
- for (end = beg = 0; ptr<eptr; ptr++) {
- if (skip) {
- if (ISSPACE(*ptr)) {
- beg++;
- }
- else {
- end = beg+1;
- skip = 0;
- }
+ for (end = beg = 0; ptr<eptr; ptr++) {
+ if (skip) {
+ if (ISSPACE(*ptr)) {
+ beg++;
}
else {
- if (ISSPACE(*ptr)) {
- rb_ary_push(result, rb_str_substr(str, beg, end-beg));
- skip = 1;
- beg = end + 1;
- if (!NIL_P(limit) && lim <= ++i) break;
- }
- else {
- end++;
- }
+ end = beg+1;
+ skip = 0;
}
}
- }
- else {
- for (end = beg = 0; ptr<eptr; ptr++) {
- if (*ptr == (char)char_sep) {
+ else {
+ if (ISSPACE(*ptr)) {
rb_ary_push(result, rb_str_substr(str, beg, end-beg));
+ skip = 1;
beg = end + 1;
if (!NIL_P(limit) && lim <= ++i) break;
}
- end++;
+ else {
+ end++;
+ }
}
}
}
@@ -3178,7 +3182,7 @@ Init_String()
rb_define_method(rb_cString, "next!", rb_str_succ_bang, 0);
rb_define_method(rb_cString, "upto", rb_str_upto_m, 1);
rb_define_method(rb_cString, "index", rb_str_index_m, -1);
- rb_define_method(rb_cString, "rindex", rb_str_rindex, -1);
+ rb_define_method(rb_cString, "rindex", rb_str_rindex_m, -1);
rb_define_method(rb_cString, "replace", rb_str_replace, 1);
rb_define_method(rb_cString, "to_i", rb_str_to_i, -1);