[macruby-changes] [158] MacRuby/trunk/string.c

source_changes at macosforge.org source_changes at macosforge.org
Sat Apr 19 02:01:14 PDT 2008


Revision: 158
          http://trac.macosforge.org/projects/ruby/changeset/158
Author:   lsansonetti at apple.com
Date:     2008-04-19 02:01:14 -0700 (Sat, 19 Apr 2008)

Log Message:
-----------
implementing #squeeze

Modified Paths:
--------------
    MacRuby/trunk/string.c

Modified: MacRuby/trunk/string.c
===================================================================
--- MacRuby/trunk/string.c	2008-04-19 06:22:34 UTC (rev 157)
+++ MacRuby/trunk/string.c	2008-04-19 09:01:14 UTC (rev 158)
@@ -5217,7 +5217,7 @@
 
 static void
 str_charset_find(CFStringRef str, VALUE *charsets, int charset_count,
-		 str_charset_find_cb *cb, void *ctx)
+		 bool squeeze_mode, str_charset_find_cb *cb, void *ctx)
 {
     int i;
     long n;
@@ -5318,9 +5318,11 @@
     }
 #else
     CFStringInlineBuffer buf;
+    UniChar previous_char = 0;
     CFStringInitInlineBuffer((CFStringRef)str, &buf, search_range);
     do {
         long i;
+	bool mutated = false;
 
 	if (search_range.location + search_range.length < n) {
 	    n = search_range.location + search_range.length;
@@ -5341,28 +5343,36 @@
 		if (result_range.length == 0) {
 		    result_range.location = i;
 		    result_range.length = 1;
+		    previous_char = c;
 		}
 		else {
-		    if (result_range.location + result_range.length == i) {
+		    if (result_range.location + result_range.length == i
+			&& (!squeeze_mode || previous_char == c)) {
 			result_range.length++;
 		    }
 		    else {
-			(*cb)(&search_range, (const CFRange *)&result_range, str, 
-				ctx);
+			(*cb)(&search_range, (const CFRange *)&result_range, 
+			    str, ctx);
 			result_range.location = i;
 			result_range.length = 1;
+			previous_char = c;
 			if (search_range.location + search_range.length < n) {
 			    result_range.location -= n 
 				- (search_range.location + search_range.length);
+			    mutated = true;
+			    break;
 			}
-			break;
 		    }
 		}
-	    }	    
+	    }
 	}
-	if (result_range.length != 0) {
-	    (*cb)(&search_range, (const CFRange *)&result_range, str, 
-		    ctx);
+	if (!mutated) {
+	    if (result_range.length != 0) {
+		(*cb)(&search_range, (const CFRange *)&result_range, str, 
+			ctx);
+		result_range.length = 0;
+		previous_char = 0;
+	    }
 	}
     }
     while (search_range.length != 0 && result_range.length != 0); 
@@ -5403,8 +5413,8 @@
 	rb_raise(rb_eArgError, "wrong number of arguments");
     rb_str_modify(str);
     changed = false;
-    str_charset_find((CFStringRef)str, argv, argc, rb_str_delete_bang_cb, 
-	&changed);
+    str_charset_find((CFStringRef)str, argv, argc, false,
+	rb_str_delete_bang_cb, &changed);
     if (!changed)
     	return Qnil;
     return str;
@@ -5485,11 +5495,41 @@
  *  <code>nil</code> if no changes were made.
  */
 
+#if WITH_OBJC
+static void
+rb_str_squeeze_bang_cb(CFRange *search_range, const CFRange *result_range, 
+    CFStringRef str, void *ctx)
+{
+    if (result_range->length > 1) {
+	CFRange to_delete = *result_range;
+	to_delete.length--;
+	CFStringDelete((CFMutableStringRef)str, to_delete);
+	search_range->length -= result_range->length 
+	    + (result_range->location - search_range->location);
+	search_range->location = result_range->location + 1;
+	*(bool *)ctx = true;
+    }
+}
+#endif
+
 static VALUE
 rb_str_squeeze_bang(int argc, VALUE *argv, VALUE str)
 {
 #if WITH_OBJC
-    rb_notimplement();
+    bool changed;
+    VALUE all_chars;
+    if (argc == 0) {
+	argc = 1;
+	all_chars = (VALUE)CFSTR("a-z");
+	argv = &all_chars;
+    }
+    rb_str_modify(str);
+    changed = false;
+    str_charset_find((CFStringRef)str, argv, argc, true,
+	rb_str_squeeze_bang_cb, &changed);
+    if (!changed)
+    	return Qnil;
+    return str;
 #else
     char squeez[256];
     rb_encoding *enc = 0;
@@ -5625,9 +5665,6 @@
 rb_str_count_cb(CFRange *search_range, const CFRange *result_range, 
     CFStringRef str, void *ctx)
 {
-    search_range->length -= result_range->length 
-	+ (result_range->location - search_range->location);
-    search_range->location = result_range->location + result_range->length;
     (*(int *)ctx) += result_range->length;
 }
 #endif
@@ -5640,7 +5677,8 @@
     if (argc < 1)
 	rb_raise(rb_eArgError, "wrong number of arguments");
     count = 0;
-    str_charset_find((CFStringRef)str, argv, argc, rb_str_count_cb, &count); 
+    str_charset_find((CFStringRef)str, argv, argc, false,
+	rb_str_count_cb, &count); 
     return INT2NUM(count);
 #else
     char table[256];

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/macruby-changes/attachments/20080419/4f83a90d/attachment.html


More information about the macruby-changes mailing list