[macruby-changes] [3621] MacRuby/branches/icu/string.c
source_changes at macosforge.org
source_changes at macosforge.org
Thu Feb 25 13:13:31 PST 2010
Revision: 3621
http://trac.macosforge.org/projects/ruby/changeset/3621
Author: lsansonetti at apple.com
Date: 2010-02-25 13:13:29 -0800 (Thu, 25 Feb 2010)
Log Message:
-----------
added #rindex (string patterns only) + #strip family
Modified Paths:
--------------
MacRuby/branches/icu/string.c
Modified: MacRuby/branches/icu/string.c
===================================================================
--- MacRuby/branches/icu/string.c 2010-02-25 20:27:51 UTC (rev 3620)
+++ MacRuby/branches/icu/string.c 2010-02-25 21:13:29 UTC (rev 3621)
@@ -920,7 +920,7 @@
static long
str_offset_in_bytes_for_string(rb_str_t *self, rb_str_t *searched,
- long start_offset_in_bytes)
+ long start_offset_in_bytes, bool backward_search)
{
if (start_offset_in_bytes >= self->length_in_bytes) {
return -1;
@@ -936,6 +936,7 @@
if (searched->length_in_bytes > self->length_in_bytes) {
return -1;
}
+
long increment;
if (str_is_stored_in_uchars(self)) {
increment = 2;
@@ -943,22 +944,36 @@
else {
increment = self->encoding->min_char_size;
}
- long max_offset_in_bytes = self->length_in_bytes
- - searched->length_in_bytes + 1;
- for (long offset_in_bytes = start_offset_in_bytes;
- offset_in_bytes < max_offset_in_bytes;
- offset_in_bytes += increment) {
- if (memcmp(self->data.bytes+offset_in_bytes, searched->data.bytes,
- searched->length_in_bytes) == 0) {
- return offset_in_bytes;
+
+ if (backward_search) {
+ for (long offset_in_bytes = start_offset_in_bytes;
+ offset_in_bytes >= 0;
+ offset_in_bytes -= increment) {
+ if (memcmp(self->data.bytes+offset_in_bytes, searched->data.bytes,
+ searched->length_in_bytes) == 0) {
+ return offset_in_bytes;
+ }
}
}
+ else {
+ const long max_offset_in_bytes = self->length_in_bytes
+ - searched->length_in_bytes + 1;
+
+ for (long offset_in_bytes = start_offset_in_bytes;
+ offset_in_bytes < max_offset_in_bytes;
+ offset_in_bytes += increment) {
+ if (memcmp(self->data.bytes+offset_in_bytes, searched->data.bytes,
+ searched->length_in_bytes) == 0) {
+ return offset_in_bytes;
+ }
+ }
+ }
return -1;
}
static long
str_index_for_string(rb_str_t *self, rb_str_t *searched, long start_index,
- bool ucs2_mode)
+ bool backward_search, bool ucs2_mode)
{
str_must_have_compatible_encoding(self, searched);
str_make_same_format(self, searched);
@@ -983,7 +998,7 @@
}
const long offset_in_bytes = str_offset_in_bytes_for_string(RSTR(self),
- searched, start_offset_in_bytes);
+ searched, start_offset_in_bytes, backward_search);
if (offset_in_bytes == -1) {
return -1;
}
@@ -993,7 +1008,7 @@
static bool
str_include_string(rb_str_t *self, rb_str_t *searched)
{
- return (str_offset_in_bytes_for_string(self, searched, 0) != -1);
+ return (str_offset_in_bytes_for_string(self, searched, 0, false) != -1);
}
static rb_str_t *
@@ -1577,7 +1592,7 @@
// fall through
case T_STRING:
pos = str_index_for_string(RSTR(self), str_need_string(sub),
- pos, true);
+ pos, false, true);
break;
}
@@ -1607,7 +1622,44 @@
static VALUE
rstr_rindex(VALUE self, SEL sel, int argc, VALUE *argv)
{
-return Qnil;
+ const long len = str_length(RSTR(self), false);
+ VALUE sub, initpos;
+ long pos;
+
+ if (rb_scan_args(argc, argv, "11", &sub, &initpos) == 2) {
+ pos = NUM2LONG(initpos);
+ if (pos < 0) {
+ pos += len;
+ if (pos < 0) {
+ if (TYPE(sub) == T_REGEXP) {
+ rb_backref_set(Qnil);
+ }
+ return Qnil;
+ }
+ }
+ if (pos >= len) {
+ pos = len - 1;
+ }
+ }
+ else {
+ pos = len - 1;
+ }
+
+ switch (TYPE(sub)) {
+ case T_REGEXP:
+ pos = rb_reg_search(sub, self, pos, true);
+ break;
+
+ default:
+ StringValue(sub);
+ // fall through
+ case T_STRING:
+ pos = str_index_for_string(RSTR(self), str_need_string(sub),
+ pos, true, true);
+ break;
+ }
+
+ return pos >= 0 ? LONG2NUM(pos) : Qnil;
}
static VALUE
@@ -2228,7 +2280,7 @@
rb_str_t *spat_str = str_need_string(spat);
do {
const long pos = str_index_for_string(RSTR(str), spat_str,
- beg, false);
+ beg, false, false);
if (pos == -1) {
break;
}
@@ -2431,7 +2483,7 @@
}
else if (rslen <= len) {
if (str_index_for_string(RSTR(str), str_need_string(rs),
- len - rslen, false) >= 0) {
+ len - rslen, false, false) >= 0) {
to_del += rslen;
}
}
@@ -2834,6 +2886,7 @@
}
while (width > 0);
}
+
static VALUE
rstr_justify(int argc, VALUE *argv, VALUE str, char mode)
{
@@ -2926,6 +2979,160 @@
return rstr_justify(argc, argv, str, 'c');
}
+/*
+ * call-seq:
+ * str.strip! => str or nil
+ *
+ * Removes leading and trailing whitespace from <i>str</i>. Returns
+ * <code>nil</code> if <i>str</i> was not altered.
+ */
+
+static VALUE
+str_strip(VALUE str, int direction)
+{
+ rstr_modify(str);
+
+ long len = str_length(RSTR(str), false);
+ if (len == 0) {
+ return Qnil;
+ }
+
+ bool changed = false;
+
+ if (direction <= 0) {
+ // Strip left side.
+ long pos = 0;
+ while (pos < len) {
+ if (!iswspace(rb_str_get_uchar(str, pos))) {
+ break;
+ }
+ pos++;
+ }
+
+ if (pos > 0) {
+ str_delete(RSTR(str), 0, pos, false);
+ len -= pos;
+ changed = true;
+ }
+ }
+
+ if (direction >= 0) {
+ // Strip right side.
+ long pos = len - 1;
+ while (pos >= 0) {
+ if (!iswspace(rb_str_get_uchar(str, pos))) {
+ break;
+ }
+ pos--;
+ }
+
+ if (pos < len - 1 && pos >= 0) {
+ str_delete(RSTR(str), pos + 1, len - pos - 1, false);
+ changed = true;
+ }
+ }
+
+ return changed ? str : Qnil;
+}
+
+static VALUE
+rstr_strip_bang(VALUE str, SEL sel)
+{
+ return str_strip(str, 0);
+}
+
+/*
+ * call-seq:
+ * str.strip => new_str
+ *
+ * Returns a copy of <i>str</i> with leading and trailing whitespace removed.
+ *
+ * " hello ".strip #=> "hello"
+ * "\tgoodbye\r\n".strip #=> "goodbye"
+ */
+
+static VALUE
+rstr_strip(VALUE str, SEL sel)
+{
+ str = rstr_dup(str, 0);
+ rstr_strip_bang(str, 0);
+ return str;
+}
+
+/*
+ * call-seq:
+ * str.lstrip! => self or nil
+ *
+ * Removes leading whitespace from <i>str</i>, returning <code>nil</code> if no
+ * change was made. See also <code>String#rstrip!</code> and
+ * <code>String#strip!</code>.
+ *
+ * " hello ".lstrip #=> "hello "
+ * "hello".lstrip! #=> nil
+ */
+
+static VALUE
+rstr_lstrip_bang(VALUE str, SEL sel)
+{
+ return str_strip(str, -1);
+}
+
+/*
+ * call-seq:
+ * str.lstrip => new_str
+ *
+ * Returns a copy of <i>str</i> with leading whitespace removed. See also
+ * <code>String#rstrip</code> and <code>String#strip</code>.
+ *
+ * " hello ".lstrip #=> "hello "
+ * "hello".lstrip #=> "hello"
+ */
+
+static VALUE
+rstr_lstrip(VALUE str)
+{
+ str = rstr_dup(str, 0);
+ rstr_lstrip_bang(str, 0);
+ return str;
+}
+
+/*
+ * call-seq:
+ * str.rstrip! => self or nil
+ *
+ * Removes trailing whitespace from <i>str</i>, returning <code>nil</code> if
+ * no change was made. See also <code>String#lstrip!</code> and
+ * <code>String#strip!</code>.
+ *
+ * " hello ".rstrip #=> " hello"
+ * "hello".rstrip! #=> nil
+ */
+
+static VALUE
+rstr_rstrip_bang(VALUE str, SEL sel)
+{
+ return str_strip(str, 1);
+}
+
+/*
+ * call-seq:
+ * str.rstrip => new_str
+ *
+ * Returns a copy of <i>str</i> with trailing whitespace removed. See also
+ * <code>String#lstrip</code> and <code>String#strip</code>.
+ *
+ * " hello ".rstrip #=> " hello"
+ * "hello".rstrip #=> "hello"
+ */
+
+static VALUE
+rstr_rstrip(VALUE str)
+{
+ str = rstr_dup(str, 0);
+ rstr_rstrip_bang(str, 0);
+ return str;
+}
+
// NSString primitives.
static CFIndex
@@ -3008,6 +3215,12 @@
rb_objc_define_method(rb_cRubyString, "ljust", rstr_ljust, -1);
rb_objc_define_method(rb_cRubyString, "rjust", rstr_rjust, -1);
rb_objc_define_method(rb_cRubyString, "center", rstr_center, -1);
+ rb_objc_define_method(rb_cRubyString, "strip", rstr_strip, 0);
+ rb_objc_define_method(rb_cRubyString, "lstrip", rstr_lstrip, 0);
+ rb_objc_define_method(rb_cRubyString, "rstrip", rstr_rstrip, 0);
+ rb_objc_define_method(rb_cRubyString, "strip!", rstr_strip_bang, 0);
+ rb_objc_define_method(rb_cRubyString, "lstrip!", rstr_lstrip_bang, 0);
+ rb_objc_define_method(rb_cRubyString, "rstrip!", rstr_rstrip_bang, 0);
// Added for MacRuby (debugging).
rb_objc_define_method(rb_cRubyString, "__chars_count__",
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20100225/f89131d0/attachment-0001.html>
More information about the macruby-changes
mailing list