[macruby-changes] [3584] MacRuby/branches/icu
source_changes at macosforge.org
source_changes at macosforge.org
Sat Feb 20 01:34:38 PST 2010
Revision: 3584
http://trac.macosforge.org/projects/ruby/changeset/3584
Author: lsansonetti at apple.com
Date: 2010-02-20 01:34:37 -0800 (Sat, 20 Feb 2010)
Log Message:
-----------
added String#match and String#=~
Modified Paths:
--------------
MacRuby/branches/icu/re.cpp
MacRuby/branches/icu/re.h
MacRuby/branches/icu/string.c
Modified: MacRuby/branches/icu/re.cpp
===================================================================
--- MacRuby/branches/icu/re.cpp 2010-02-20 06:42:42 UTC (rev 3583)
+++ MacRuby/branches/icu/re.cpp 2010-02-20 09:34:37 UTC (rev 3584)
@@ -451,7 +451,7 @@
return rb_reg_search(re, str, pos, 0);
}
-static VALUE
+VALUE
regexp_match(VALUE rcv, SEL sel, VALUE str)
{
const long pos = reg_match_pos(rcv, &str, 0);
@@ -489,7 +489,7 @@
* The return value is a value from block execution in this case.
*/
-static VALUE
+VALUE
regexp_match2(VALUE rcv, SEL sel, int argc, VALUE *argv)
{
VALUE result, str, initpos;
@@ -1337,11 +1337,25 @@
}
VALUE
+rb_reg_regcomp(VALUE str)
+{
+ // XXX MRI caches the regexp here, maybe we should do the same...
+ return rb_reg_new_str(str, 0);
+}
+
+VALUE
rb_reg_new(const char *cstr, long len, int options)
{
return rb_reg_new_str(rb_usascii_str_new(cstr, len), options);
}
+VALUE
+rb_reg_quote(VALUE pat)
+{
+ // TODO
+ return pat;
+}
+
void
rb_match_busy(VALUE match)
{
Modified: MacRuby/branches/icu/re.h
===================================================================
--- MacRuby/branches/icu/re.h 2010-02-20 06:42:42 UTC (rev 3583)
+++ MacRuby/branches/icu/re.h 2010-02-20 09:34:37 UTC (rev 3584)
@@ -14,7 +14,13 @@
#endif
bool rb_char_to_icu_option(int c, int *option);
+
VALUE regexp_eqq(VALUE rcv, SEL sel, VALUE str);
+VALUE regexp_match(VALUE rcv, SEL sel, VALUE str);
+VALUE regexp_match2(VALUE rcv, SEL sel, int argc, VALUE *argv);
+
+VALUE rb_reg_quote(VALUE pat);
+VALUE rb_reg_regcomp(VALUE str);
int rb_reg_search(VALUE re, VALUE str, int pos, bool reverse);
static inline int
Modified: MacRuby/branches/icu/string.c
===================================================================
--- MacRuby/branches/icu/string.c 2010-02-20 06:42:42 UTC (rev 3583)
+++ MacRuby/branches/icu/string.c 2010-02-20 09:34:37 UTC (rev 3584)
@@ -1759,6 +1759,104 @@
return str_inspect(self, true);
}
+/*
+ * call-seq:
+ * str.match(pattern) => matchdata or nil
+ *
+ * Converts <i>pattern</i> to a <code>Regexp</code> (if it isn't already one),
+ * then invokes its <code>match</code> method on <i>str</i>. If the second
+ * parameter is present, it specifies the position in the string to begin the
+ * search.
+ *
+ * 'hello'.match('(.)\1') #=> #<MatchData "ll" 1:"l">
+ * 'hello'.match('(.)\1')[0] #=> "ll"
+ * 'hello'.match(/(.)\1/)[0] #=> "ll"
+ * 'hello'.match('xx') #=> nil
+ *
+ * If a block is given, invoke the block with MatchData if match succeed, so
+ * that you can write
+ *
+ * str.match(pat) {|m| ...}
+ *
+ * instead of
+ *
+ * if m = str.match(pat)
+ * ...
+ * end
+ *
+ * The return value is a value from block execution in this case.
+ */
+
+static VALUE
+get_pat(VALUE pat, bool quote)
+{
+ switch (TYPE(pat)) {
+ case T_REGEXP:
+ return pat;
+
+ case T_STRING:
+ break;
+
+ default:
+ {
+ VALUE val = rb_check_string_type(pat);
+ if (NIL_P(val)) {
+ Check_Type(pat, T_REGEXP);
+ }
+ pat = val;
+ }
+ }
+
+ if (quote) {
+ pat = rb_reg_quote(pat);
+ }
+ return rb_reg_regcomp(pat);
+}
+
+static VALUE
+rstr_match2(VALUE self, SEL sel, int argc, VALUE *argv)
+{
+ if (argc < 1) {
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", argc);
+ }
+ VALUE re = get_pat(argv[0], false);
+ argv[0] = self;
+ VALUE result = regexp_match2(re, 0, argc, argv);
+ if (!NIL_P(result) && rb_block_given_p()) {
+ return rb_yield(result);
+ }
+ return result;
+}
+
+/*
+ * call-seq:
+ * str =~ obj => fixnum or nil
+ *
+ * Match---If <i>obj</i> is a <code>Regexp</code>, use it as a pattern to match
+ * against <i>str</i>,and returns the position the match starts, or
+ * <code>nil</code> if there is no match. Otherwise, invokes
+ * <i>obj.=~</i>, passing <i>str</i> as an argument. The default
+ * <code>=~</code> in <code>Object</code> returns <code>false</code>.
+ *
+ * "cat o' 9 tails" =~ /\d/ #=> 7
+ * "cat o' 9 tails" =~ 9 #=> nil
+ */
+
+static VALUE
+rstr_match(VALUE self, SEL sel, VALUE other)
+{
+ switch (TYPE(other)) {
+ case T_STRING:
+ rb_raise(rb_eTypeError, "type mismatch: String given");
+
+ case T_REGEXP:
+ return regexp_match(other, 0, self);
+
+ default:
+ return rb_funcall(other, rb_intern("=~"), 1, self);
+ }
+}
+
// NSString primitives.
static CFIndex
@@ -1825,6 +1923,8 @@
rb_objc_define_method(rb_cRubyString, "intern", rstr_intern, 0);
rb_objc_define_method(rb_cRubyString, "inspect", rstr_inspect, 0);
rb_objc_define_method(rb_cRubyString, "dump", rstr_dump, 0);
+ rb_objc_define_method(rb_cRubyString, "match", rstr_match2, -1);
+ rb_objc_define_method(rb_cRubyString, "=~", rstr_match, 1);
// 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/20100220/34a53ab7/attachment-0001.html>
More information about the macruby-changes
mailing list