[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