[macruby-changes] [2119] MacRuby/branches/experimental

source_changes at macosforge.org source_changes at macosforge.org
Thu Jul 30 23:46:59 PDT 2009


Revision: 2119
          http://trac.macosforge.org/projects/ruby/changeset/2119
Author:   lsansonetti at apple.com
Date:     2009-07-30 23:46:57 -0700 (Thu, 30 Jul 2009)
Log Message:
-----------
various unicode/bytestring fixes

Modified Paths:
--------------
    MacRuby/branches/experimental/array.c
    MacRuby/branches/experimental/dir.c
    MacRuby/branches/experimental/file.c
    MacRuby/branches/experimental/include/ruby/ruby.h
    MacRuby/branches/experimental/include/ruby/util.h
    MacRuby/branches/experimental/process.c
    MacRuby/branches/experimental/string.c
    MacRuby/branches/experimental/util.c

Modified: MacRuby/branches/experimental/array.c
===================================================================
--- MacRuby/branches/experimental/array.c	2009-07-30 05:09:26 UTC (rev 2118)
+++ MacRuby/branches/experimental/array.c	2009-07-31 06:46:57 UTC (rev 2119)
@@ -2465,7 +2465,9 @@
 static VALUE
 rb_ary_equal(VALUE ary1, SEL sel, VALUE ary2)
 {
-    if (ary1 == ary2) return Qtrue;
+    if (ary1 == ary2) {
+	return Qtrue;
+    }
     if (TYPE(ary2) != T_ARRAY) {
 	if (!rb_respond_to(ary2, rb_intern("to_ary"))) {
 	    return Qfalse;

Modified: MacRuby/branches/experimental/dir.c
===================================================================
--- MacRuby/branches/experimental/dir.c	2009-07-30 05:09:26 UTC (rev 2118)
+++ MacRuby/branches/experimental/dir.c	2009-07-31 06:46:57 UTC (rev 2119)
@@ -744,9 +744,9 @@
 
     if (rb_block_given_p()) {
 	struct chdir_data args;
-	char *cwd = my_getcwd();
+	VALUE cwd = my_getcwd();
 
-	args.old_path = rb_tainted_str_new2(cwd); xfree(cwd);
+	args.old_path = cwd;
 	rb_objc_retain((const void *)args.old_path);
 	args.new_path = path;
 	args.done = Qfalse;
@@ -771,15 +771,8 @@
 static VALUE
 dir_s_getwd(VALUE dir, SEL sel)
 {
-    char *path;
-    VALUE cwd;
-
     rb_secure(4);
-    path = my_getcwd();
-    cwd = rb_tainted_str_new2(path);
-
-    xfree(path);
-    return cwd;
+    return my_getcwd();
 }
 
 static void

Modified: MacRuby/branches/experimental/file.c
===================================================================
--- MacRuby/branches/experimental/file.c	2009-07-30 05:09:26 UTC (rev 2118)
+++ MacRuby/branches/experimental/file.c	2009-07-31 06:46:57 UTC (rev 2119)
@@ -2619,46 +2619,50 @@
 
 static VALUE separator;
 
-static VALUE rb_file_join(VALUE ary, VALUE sep);
-
 static VALUE
 rb_file_join(VALUE ary, VALUE sep)
 {
     CFMutableStringRef res = CFStringCreateMutable(NULL, 0);
     CFStringRef sep_cf = (CFStringRef)sep;
-    long count;
 
-    count = RARRAY_LEN(ary);
+    const long count = RARRAY_LEN(ary);
     if (count > 0) {
-      long i;
-      for (i = 0; i < count; i++) {
-        VALUE tmp = RARRAY_AT(ary, i);
-        switch (TYPE(tmp)) {
-        case T_STRING:
-          break;
-        case T_ARRAY:
-          tmp = rb_file_join(tmp, sep);
-          break;
-        default:
-          FilePathStringValue(tmp);
-        }
+	long i;
+	for (i = 0; i < count; i++) {
+	    VALUE tmp = RARRAY_AT(ary, i);
+	    switch (TYPE(tmp)) {
+		case T_STRING:
+		    if (*(VALUE *)tmp == rb_cByteString) {
+			tmp = (VALUE)rb_bytestring_resolve_cfstring(tmp);
+		    }
+		    break;
 
-        CFStringRef tmp_cf = (CFStringRef)tmp;
+		case T_ARRAY:
+		    tmp = rb_file_join(tmp, sep);
+		    break;
 
-        if (i > 0) {
-          if (CFStringHasSuffix(res, sep_cf)) {
-            if (CFStringHasPrefix(tmp_cf, sep_cf)) {
-              // Remove trailing slash from res if tmp starts with a slash.
-              CFStringDelete(res, CFRangeMake(CFStringGetLength(res) - 1, 1));
-            }
-          }
-          else if (!CFStringHasPrefix(tmp_cf, sep_cf)) {
-            CFStringAppend(res, sep_cf);
-          }
-        }
+		default:
+		    FilePathStringValue(tmp);
+	    }
 
-        CFStringAppend(res, tmp_cf);
-      }
+	    CFStringRef tmp_cf = (CFStringRef)tmp;
+
+	    if (i > 0) {
+		if (CFStringHasSuffix(res, sep_cf)) {
+		    if (CFStringHasPrefix(tmp_cf, sep_cf)) {
+			// Remove trailing slash from res if tmp starts with a
+			// slash.
+			CFStringDelete(res,
+				CFRangeMake(CFStringGetLength(res) - 1, 1));
+		    }
+		}
+		else if (!CFStringHasPrefix(tmp_cf, sep_cf)) {
+		    CFStringAppend(res, sep_cf);
+		}
+	    }
+
+	    CFStringAppend(res, tmp_cf);
+	}
     }
 
     CFMakeCollectable(res);
@@ -3743,12 +3747,7 @@
     char *p = 0, *s;
 
     if (!is_absolute_path(p0)) {
-	char *buf = my_getcwd();
-	VALUE newpath;
-
-	newpath = rb_str_new2(buf);
-	xfree(buf);
-
+	VALUE newpath = my_getcwd();
 	rb_str_cat2(newpath, "/");
 	rb_str_cat2(newpath, p0);
 	path = newpath;

Modified: MacRuby/branches/experimental/include/ruby/ruby.h
===================================================================
--- MacRuby/branches/experimental/include/ruby/ruby.h	2009-07-30 05:09:26 UTC (rev 2118)
+++ MacRuby/branches/experimental/include/ruby/ruby.h	2009-07-31 06:46:57 UTC (rev 2119)
@@ -376,6 +376,7 @@
 VALUE rb_bytestring_new_with_data(const UInt8 *buf, long size);
 VALUE rb_bytestring_new_with_cfdata(CFMutableDataRef data);
 CFMutableDataRef rb_bytestring_wrapped_data(VALUE);
+CFStringRef rb_bytestring_resolve_cfstring(VALUE str);
 UInt8 *rb_bytestring_byte_pointer(VALUE);
 VALUE rb_coerce_to_bytestring(VALUE);
 long rb_bytestring_length(VALUE str);

Modified: MacRuby/branches/experimental/include/ruby/util.h
===================================================================
--- MacRuby/branches/experimental/include/ruby/util.h	2009-07-30 05:09:26 UTC (rev 2118)
+++ MacRuby/branches/experimental/include/ruby/util.h	2009-07-31 06:46:57 UTC (rev 2119)
@@ -65,7 +65,7 @@
 #define strdup(s) ruby_strdup(s)
 #endif
 
-char *ruby_getcwd(void);
+VALUE ruby_getcwd(void);
 #define my_getcwd() ruby_getcwd()
 
 double ruby_strtod(const char *, char **);

Modified: MacRuby/branches/experimental/process.c
===================================================================
--- MacRuby/branches/experimental/process.c	2009-07-30 05:09:26 UTC (rev 2118)
+++ MacRuby/branches/experimental/process.c	2009-07-31 06:46:57 UTC (rev 2119)
@@ -2113,9 +2113,9 @@
     obj = rb_ary_entry(options, EXEC_OPTION_CHDIR);
     if (!NIL_P(obj)) {
         if (!NIL_P(soptions)) {
-            char *cwd = my_getcwd();
+            VALUE cwd = my_getcwd();
             rb_ary_store(soptions, EXEC_OPTION_CHDIR,
-                         hide_obj(rb_str_new2(cwd)));
+                         hide_obj(cwd));
         }
         if (chdir(RSTRING_PTR(obj)) == -1)
             return -1;

Modified: MacRuby/branches/experimental/string.c
===================================================================
--- MacRuby/branches/experimental/string.c	2009-07-30 05:09:26 UTC (rev 2118)
+++ MacRuby/branches/experimental/string.c	2009-07-31 06:46:57 UTC (rev 2119)
@@ -944,11 +944,27 @@
  *  <code><=></code> <i>obj</i> returns zero.
  */
 
+#if 0
+static inline CFDataRef
+str_data(VALUE str)
+{
+    if (*(VALUE *)str == rb_cByteString) {
+	return rb_bytestring_wrapped_data(str);
+    }
+    else {
+	CFDataRef data = CFStringCreateExternalRepresentation(NULL, 
+		(CFStringRef)str, kCFStringEncodingUTF8, 0);
+	if (data != NULL) {
+	    CFMakeCollectable(data);
+	}
+	return data;
+    }
+}
+#endif
+
 static VALUE
 rb_str_equal_imp(VALUE str1, SEL sel, VALUE str2)
 {
-    int len;
-
     if (str1 == str2) {
 	return Qtrue;
     }
@@ -958,9 +974,10 @@
 	}
 	return rb_equal(str2, str1);
     }
-    len = RSTRING_LEN(str1);
-    if (len != RSTRING_LEN(str2)) {
-	return Qfalse;
+    if (*(VALUE *)str1 == *(VALUE *)str2) {
+	if (RSTRING_LEN(str1) != RSTRING_LEN(str2)) {
+	    return Qfalse;
+	}
     }
     if (!rb_objc_str_is_pure(str2)) {
 	/* This is to work around a strange bug in CFEqual's objc 
@@ -970,11 +987,7 @@
 	str1 = str2;
 	str2 = tmp;
     }
-    if (CFEqual((CFTypeRef)str1, (CFTypeRef)str2)) {
-	return Qtrue;
-    }
-
-    return Qfalse;
+    return CFEqual((CFTypeRef)str1, (CFTypeRef)str2) ? Qtrue : Qfalse;
 }
 
 VALUE
@@ -5431,6 +5444,52 @@
     CFDataSetLength(rb_bytestring_wrapped_data(str), newsize);
 }
 
+CFStringRef
+rb_bytestring_resolve_cfstring(VALUE str)
+{
+    CFDataRef data = rb_bytestring_wrapped_data(str);
+    CFStringRef cfstr = CFStringCreateFromExternalRepresentation(NULL,
+	data, kCFStringEncodingUTF8);
+    if (cfstr == NULL) {
+	// If UTF8 doesn't work, try ASCII.
+	cfstr = CFStringCreateFromExternalRepresentation(NULL,
+		data, kCFStringEncodingASCII);
+    }
+    if (cfstr != NULL) {
+	return CFMakeCollectable(cfstr);
+    }
+    return (CFStringRef)str;
+}
+
+static bool
+imp_rb_bytestring_isEqual(void *rcv, SEL sel, void *other)
+{
+    if (rcv == other) {
+	return true;
+    }
+    if (*(VALUE *)other == rb_cByteString) {
+	// Both operands are bytestrings.
+	CFDataRef rcv_data = rb_bytestring_wrapped_data((VALUE)rcv);
+	CFDataRef other_data = rb_bytestring_wrapped_data((VALUE)other);
+	if (CFDataGetLength(rcv_data) != CFDataGetLength(other_data)) {
+	    return false;
+	}
+	return CFEqual(rcv_data, other_data);
+    }
+    else {
+	// Given operand is a character string.
+	CFStringRef rcv_str = rb_bytestring_resolve_cfstring((VALUE)rcv);
+	if (rcv_str == (CFStringRef)rcv) {
+	    // Can't resolve a character string based on that data.
+	    return false;
+	}
+	if (CFStringGetLength(rcv_str) != CFStringGetLength(other)) {
+	    return false;
+	}
+	return CFEqual(rcv_str, (CFTypeRef)other);
+    }
+}
+
 static CFIndex
 imp_rb_bytestring_length(void *rcv, SEL sel) 
 {
@@ -5704,6 +5763,8 @@
 	    0, "@");
     objc_registerClassPair((Class)rb_cByteString);
 
+    rb_objc_install_method2((Class)rb_cByteString, "isEqual:",
+	    (IMP)imp_rb_bytestring_isEqual);
     rb_objc_install_method2((Class)rb_cByteString, "length",
 	    (IMP)imp_rb_bytestring_length);
     rb_objc_install_method2((Class)rb_cByteString, "characterAtIndex:",

Modified: MacRuby/branches/experimental/util.c
===================================================================
--- MacRuby/branches/experimental/util.c	2009-07-30 05:09:26 UTC (rev 2118)
+++ MacRuby/branches/experimental/util.c	2009-07-31 06:46:57 UTC (rev 2119)
@@ -738,33 +738,25 @@
     return tmp;
 }
 
-char *
+VALUE
 ruby_getcwd(void)
 {
-#ifdef HAVE_GETCWD
-    int size = 200;
-    char *buf = xmalloc(size);
-
-    while (!getcwd(buf, size)) {
-	if (errno != ERANGE) {
-	    free(buf);
-	    rb_sys_fail("getcwd");
-	}
-	size *= 2;
-	buf = xrealloc(buf, size);
+    char buf[PATH_MAX];
+    if (getcwd(buf, sizeof buf) == NULL) {
+	rb_sys_fail("getcwd");
     }
-#else
-# ifndef PATH_MAX
-#  define PATH_MAX 8192
-# endif
-    char *buf = xmalloc(PATH_MAX+1);
 
-    if (!getwd(buf)) {
-	free(buf);
-	rb_sys_fail("getwd");
-    }
-#endif
-    return buf;
+    CFStringRef tmp = CFStringCreateWithFileSystemRepresentation(NULL, buf);
+    assert(tmp != NULL);
+
+    CFMutableStringRef str = CFStringCreateMutableCopy(NULL, 0, tmp);
+    assert(str != NULL);
+    CFRelease(tmp);
+    CFMakeCollectable(str);
+    CFStringNormalize(str, kCFStringNormalizationFormC);
+
+    OBJ_TAINT(str); 
+    return (VALUE)str;
 }
 
 /****************************************************************
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090730/e358d535/attachment-0001.html>


More information about the macruby-changes mailing list