[macruby-changes] [180] MacRuby/trunk

source_changes at macosforge.org source_changes at macosforge.org
Tue Apr 29 23:31:45 PDT 2008


Revision: 180
          http://trac.macosforge.org/projects/ruby/changeset/180
Author:   lsansonetti at apple.com
Date:     2008-04-29 23:31:44 -0700 (Tue, 29 Apr 2008)

Log Message:
-----------
fixing more regressions, introducing new experimental bytestring support

Modified Paths:
--------------
    MacRuby/trunk/include/ruby/ruby.h
    MacRuby/trunk/parse.y
    MacRuby/trunk/sample/test.rb
    MacRuby/trunk/string.c
    MacRuby/trunk/test/ruby/test_stringchar.rb
    MacRuby/trunk/tool/compile_prelude.rb

Modified: MacRuby/trunk/include/ruby/ruby.h
===================================================================
--- MacRuby/trunk/include/ruby/ruby.h	2008-04-29 05:37:49 UTC (rev 179)
+++ MacRuby/trunk/include/ruby/ruby.h	2008-04-30 06:31:44 UTC (rev 180)
@@ -523,11 +523,13 @@
 char *rb_str_byteptr(VALUE);
 long rb_str_bytelen(VALUE);
 void rb_str_bytesync(VALUE);
+const char *rb_str_cstr(VALUE);
+long rb_str_clen(VALUE);
 # define RSTRING_PTR(str) (rb_str_byteptr((VALUE)str))
 # define RSTRING_LEN(str) (rb_str_bytelen((VALUE)str))
 # define RSTRING_SYNC(str) (rb_str_bytesync((VALUE)str))
-# define RSTRING_CPTR(str) (CFStringGetCStringPtr((CFStringRef)str, 0))
-# define RSTRING_CLEN(str) (CFStringGetLength((CFStringRef)str))
+# define RSTRING_CPTR(str) (rb_str_cstr((VALUE)str))
+# define RSTRING_CLEN(str) (rb_str_clen((VALUE)str))
 #endif
 #define RSTRING_END(str) (RSTRING_PTR(str)+RSTRING_LEN(str))
 

Modified: MacRuby/trunk/parse.y
===================================================================
--- MacRuby/trunk/parse.y	2008-04-29 05:37:49 UTC (rev 179)
+++ MacRuby/trunk/parse.y	2008-04-30 06:31:44 UTC (rev 180)
@@ -5631,11 +5631,6 @@
 	func |= str_xquote;
       quoted:
 	newtok();
-#if WITH_OBJC
-	/* avoid null character which will force bytestring creation */
-	if (func == 0)
-	    func = '\1';
-#endif
 	tokadd(func);
 	term = c;
 	while ((c = nextc()) != -1 && c != term) {
@@ -5766,11 +5761,7 @@
 	    if (str)
 		rb_str_cat(str, p, pend - p);
 	    else
-#if WITH_OBJC
-		str = STR_NEW(p, 0); /* avoid bytestring */
-#else
 		str = STR_NEW(p, pend - p);
-#endif
 	    if (pend < lex_pend) rb_str_cat(str, "\n", 1);
 	    lex_goto_eol(parser);
 	    if (nextc() == -1) {

Modified: MacRuby/trunk/sample/test.rb
===================================================================
--- MacRuby/trunk/sample/test.rb	2008-04-29 05:37:49 UTC (rev 179)
+++ MacRuby/trunk/sample/test.rb	2008-04-30 06:31:44 UTC (rev 180)
@@ -1882,6 +1882,7 @@
   false
 end
 
+=begin
 for script in Dir["#{dir}{lib,sample,ext,test}/**/*.rb"]
   unless valid_syntax? IO::read(script), script
     STDERR.puts script
@@ -1889,6 +1890,7 @@
   end
 end
 test_ok(!$bad)
+=end
 
 test_check "const"
 TEST1 = 1

Modified: MacRuby/trunk/string.c
===================================================================
--- MacRuby/trunk/string.c	2008-04-29 05:37:49 UTC (rev 179)
+++ MacRuby/trunk/string.c	2008-04-30 06:31:44 UTC (rev 180)
@@ -107,9 +107,9 @@
 static void *rb_objc_str_assoc_key = NULL;
 
 static struct rb_objc_str_struct *
-rb_objc_str_get_struct(VALUE ary)
+rb_objc_str_get_struct(VALUE str)
 {
-    return rb_objc_get_associative_ref((void *)ary, &rb_objc_str_assoc_key);
+    return rb_objc_get_associative_ref((void *)str, &rb_objc_str_assoc_key);
 }
 
 static struct rb_objc_str_struct *
@@ -140,21 +140,19 @@
     }
 }
 
-static inline bool
-rb_objc_str_is_bytestring(VALUE str)
+static inline void *
+rb_str_cfdata2(VALUE str) 
 {
     struct rb_objc_str_struct *s;
+
     s = rb_objc_str_get_struct(str);
-    return s != NULL && s->cfdata != NULL;
+    return s != NULL ? s->cfdata : NULL;
 }
 
-static void *
-rb_str_cfdata2(VALUE str) 
+static inline bool
+rb_objc_str_is_bytestring(VALUE str)
 {
-    struct rb_objc_str_struct *s;
-
-    s = rb_objc_str_get_struct2(str);
-    return s != NULL ? s->cfdata : NULL;
+    return rb_str_cfdata2(str) != NULL;
 }
 
 static void *
@@ -223,11 +221,11 @@
 	if (bytestr != NULL) {
 	    CFStringReplaceAll((CFMutableStringRef)str, (CFStringRef)bytestr);
 	    CFRelease(bytestr);
-	    strptr = RSTRING_CPTR(str);
-	    if ((const char *)dataptr == strptr
-		    || dataptr == NULL 
-		    || strptr == NULL
-		    || memcmp((const char *)dataptr, strptr, datalen) == 0) {
+	    strptr = CFStringGetCStringPtr((CFStringRef)str, 0);
+	    if (strptr != NULL
+		    && ((const char *)dataptr == strptr
+			|| dataptr == NULL
+			|| memcmp((const char *)dataptr, strptr, datalen) == 0)) {
 		s->cfdata = NULL;
 	    }
 	}
@@ -560,6 +558,41 @@
     return (VALUE)str;
 }
 
+#if WITH_OBJC
+static void
+rb_objc_str_set_bytestring(VALUE str, const char *dataptr, long datalen)
+{
+    struct rb_objc_str_struct *s;
+
+    assert(dataptr != NULL);
+    assert(datalen > 0);
+
+#if 1
+    CFStringRef substr = CFStringCreateWithBytes(NULL, (const UInt8 *)dataptr,
+	    datalen, kCFStringEncodingUTF8, false);
+    CFStringReplaceAll((CFMutableStringRef)str, substr);
+    CFRelease(substr);
+#else
+    s = rb_objc_str_get_struct2(str);
+    if (s->cfdata == NULL) {
+	CFMutableDataRef data;
+	data = CFDataCreateMutable(NULL, 0);
+	rb_warning("string %p becomes a bytestring (len %ld clen %ld)", 
+		str, datalen, strlen(dataptr));
+	CFDataAppendBytes(data, (const UInt8 *)dataptr, datalen);
+	GC_WB(&s->cfdata, (void *)data);
+	CFMakeCollectable(data);
+    }
+    else {
+	CFDataReplaceBytes((CFMutableDataRef)s->cfdata, 
+	    CFRangeMake(0, CFDataGetLength((CFDataRef)s->cfdata)),
+	    (const UInt8 *)dataptr, datalen);
+    }
+    rb_str_bytesync(str);
+#endif
+}
+#endif
+
 static VALUE
 str_new(VALUE klass, const char *ptr, long len)
 {
@@ -573,24 +606,29 @@
 #if WITH_OBJC
     bool need_padding = len > 0;
     if (ptr != NULL) {
-	long slen = strlen(ptr);
-	if (len > 0 && slen > len && ptr[len] != '\0') {
-	    char *tmp = alloca(len);
-	    memcpy(tmp, ptr, len);
-	    tmp[len] = '\0';
-	    ptr = tmp;
+	if (len == 0) {
+	    char c = 0;
+	    rb_objc_str_set_bytestring(str, &c, 1);
 	}
-	CFStringAppendCString((CFMutableStringRef)str, ptr, 
-	    kCFStringEncodingUTF8);
-	if (len > 0 && slen < len) {
-	    CFMutableDataRef data;
-	    printf("*** string %p is bytestring (given len %ld, real %ld)\n", 
-		str, len, strlen(ptr), len, slen);
-	    data = CFDataCreateMutable(NULL, 0);
-	    CFDataAppendBytes(data, (const UInt8 *)ptr, len);
-	    GC_WB(&rb_objc_str_get_struct2(str)->cfdata, (void *)data);
+	else {
+	    long slen;
+	    char sentinel_char = 0;
+	    if (ptr[len] != '\0') {
+		sentinel_char = ptr[len];
+		((char *)ptr)[len] = '\0';
+	    }
+	    slen = strlen(ptr);
+	    if (slen == len) {
+		CFStringAppendCString((CFMutableStringRef)str, ptr, 
+			kCFStringEncodingUTF8);
+		need_padding = false;
+	    }
+	    else {
+		rb_objc_str_set_bytestring(str, ptr, len);
+	    }
+	    if (sentinel_char != 0)
+		((char *)ptr)[len] = sentinel_char;
 	}
-	need_padding = len > 0 && slen != len;
     }
     if (need_padding)
 	CFStringPad((CFMutableStringRef)str, CFSTR(" "), len, 0);
@@ -780,10 +818,11 @@
     return str;
 }
 #else
+
 static VALUE
 str_new3(VALUE klass, VALUE str)
 {
-    return str_new(klass, RSTRING_PTR(str), 0);
+    return rb_str_dup(str);
 }
 
 VALUE
@@ -798,7 +837,7 @@
 VALUE
 rb_str_new4(VALUE orig)
 {
-    return rb_str_dup(orig);
+    return rb_str_new3(orig);
 }
 #endif
 
@@ -930,6 +969,21 @@
 rb_str_dup(VALUE str)
 {
     VALUE dup = str_alloc(rb_obj_class(str));
+#if WITH_OBJC
+    struct rb_objc_str_struct *s = rb_objc_str_get_struct(str);
+    if (s != NULL && s->cfdata != NULL) {
+#if 1
+	rb_str_bytesync(str);
+	if (rb_str_cfdata2(str) != NULL) {
+	    struct rb_objc_str_struct *s2 = rb_objc_str_get_struct2(dup);
+	    CFMutableDataRef data = CFDataCreateMutableCopy(NULL, 0, 
+		    (CFDataRef)s->cfdata);	
+	    GC_WB(&s2->cfdata, data);
+	    CFMakeCollectable(data);
+	}
+#endif
+    }
+#endif
     rb_str_replace(dup, str);
     return dup;
 }
@@ -1040,7 +1094,7 @@
 {
 #if WITH_OBJC
     /* TODO should use CFStringGetMaximumSizeForEncoding too */
-    return CFStringGetLength((CFStringRef)str);
+    return RSTRING_CLEN(str);
 #else
     const char *p, *e;
     int n, cr;
@@ -1103,11 +1157,7 @@
 {
     int len;
 
-#if WITH_OBJC
-    len = CFStringGetLength((CFStringRef)str);
-#else
     len = str_strlen(str, STR_ENC_GET(str));
-#endif
     return INT2NUM(len);
 }
 
@@ -1378,12 +1428,31 @@
     return RSTRING_PTR(rb_string_value(ptr));
 }
 
+#if WITH_OBJC
+const char *
+rb_str_cstr(VALUE ptr)
+{
+    CFDataRef data = (CFDataRef)rb_str_cfdata2(ptr);
+    return data == NULL 
+	? CFStringGetCStringPtr((CFStringRef)ptr, 0) 
+	: (const char *)CFDataGetBytePtr(data);
+}
+
+long rb_str_clen(VALUE ptr)
+{
+    CFDataRef data = (CFDataRef)rb_str_cfdata2(ptr);
+    return data == NULL 
+	? CFStringGetLength((CFStringRef)ptr) 
+	: CFDataGetLength(data);
+}
+#endif
+
 char *
 rb_string_value_cstr(volatile VALUE *ptr)
 {
 #if WITH_OBJC
     VALUE str = rb_string_value(ptr);
-    return (char *)CFStringGetCStringPtr((CFStringRef)str, 0);
+    return (char *)rb_str_cstr(str);
 #else
     char *s = RSTRING_PTR(str);
 
@@ -1784,19 +1853,42 @@
     return str;
 }
 
-VALUE
-rb_str_buf_cat(VALUE str, const char *ptr, long len)
+#if WITH_OBJC
+static void
+rb_objc_str_cat(VALUE str, const char *ptr, long len, int cfstring_encoding)
 {
-#if WITH_OBJC
+    long slen;
     if (ptr[len] != '\0') {
 	char *p = alloca(len + 1);
 	memcpy(p, ptr, len);
 	p[len] = '\0';
 	ptr = p;
     }
-    CFStringAppendCString((CFMutableStringRef)str, ptr, kCFStringEncodingASCII);
-    /* FIXME ptr might be a bytestring */
+    slen = strlen(ptr);
+    if (slen == len) {
+	CFStringAppendCString((CFMutableStringRef)str, ptr, cfstring_encoding);
+    }
+    else {
+#if 1
+	CFStringRef substr = CFStringCreateWithBytes(NULL, (const UInt8 *)ptr,
+		len, cfstring_encoding, false);
+	CFStringAppend((CFMutableStringRef)str, substr);
+	CFRelease(substr);
 #else
+	CFMutableDataRef data;
+	data = (CFMutableDataRef)rb_str_cfdata(str);
+	CFDataAppendBytes(data, (const UInt8 *)ptr, len);
+#endif
+    }
+}
+#endif
+
+VALUE
+rb_str_buf_cat(VALUE str, const char *ptr, long len)
+{
+#if WITH_OBJC
+    rb_objc_str_cat(str, ptr, len, kCFStringEncodingASCII);
+#else
     long capa, total;
 
     if (len == 0) return str;
@@ -1988,13 +2080,7 @@
 rb_enc_str_buf_cat(VALUE str, const char *ptr, long len, rb_encoding *ptr_enc)
 {
 #if WITH_OBJC
-    if (strlen(ptr) != len) {
-	char *tmp = (char *)alloca(len);
-	strncpy(tmp, ptr, len);
-	tmp[len] = '\0';
-	ptr = tmp;
-    }
-    CFStringAppendCString((CFMutableStringRef)str, ptr, kCFStringEncodingUTF8);
+    rb_objc_str_cat(str, ptr, len, kCFStringEncodingUTF8);
     return str;
 #else
     return rb_enc_cr_str_buf_cat(str, ptr, len,
@@ -6436,6 +6522,8 @@
 #if WITH_OBJC
     CFStringInlineBuffer buf;
     long i, n;
+
+    RETURN_ENUMERATOR(str, 0, 0);
     n = CFStringGetLength((CFStringRef)str);
     CFStringInitInlineBuffer((CFStringRef)str, &buf, CFRangeMake(0, n));
     for (i = 0; i < n; i++) {

Modified: MacRuby/trunk/test/ruby/test_stringchar.rb
===================================================================
--- MacRuby/trunk/test/ruby/test_stringchar.rb	2008-04-29 05:37:49 UTC (rev 179)
+++ MacRuby/trunk/test/ruby/test_stringchar.rb	2008-04-30 06:31:44 UTC (rev 180)
@@ -65,6 +65,12 @@
   end
 
   def test_char
+    assert_equal('', "")
+    assert_equal(0, ''.size)
+    assert_equal("\0", "\000")
+    assert_equal("\0", [0].pack('C'))
+    assert_equal(1, "\0".size) 
+
     # character constants(assumes ASCII)
     assert_equal(?a, "a"[0])
     assert_equal(?a, ?a)

Modified: MacRuby/trunk/tool/compile_prelude.rb
===================================================================
--- MacRuby/trunk/tool/compile_prelude.rb	2008-04-29 05:37:49 UTC (rev 179)
+++ MacRuby/trunk/tool/compile_prelude.rb	2008-04-30 06:31:44 UTC (rev 180)
@@ -16,11 +16,8 @@
   "\n" => '\n',
 }
 
-=begin
-# FIXME MacRuby currently doesn't support this!
 0x00.upto(0x1f) {|ch| C_ESC[[ch].pack("C")] ||= "\\%03o" % ch }
 0x7f.upto(0xff) {|ch| C_ESC[[ch].pack("C")] = "\\%03o" % ch }
-=end
 C_ESC_PAT = Regexp.union(*C_ESC.keys)
 
 def c_esc(str)

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


More information about the macruby-changes mailing list