[前][次][番号順一覧][スレッド一覧]

ruby-changes:23725

From: nobu <ko1@a...>
Date: Thu, 24 May 2012 23:37:04 +0900 (JST)
Subject: [ruby-changes:23725] nobu:r35776 (trunk): Feature #5896

nobu	2012-05-24 23:36:54 +0900 (Thu, 24 May 2012)

  New Revision: 35776

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=35776

  Log:
    Feature #5896
    
    * vsnprintf.c (BSD_vfprintf): [EXPERIMENTAL] object representation in
      rb_enc_vsprintf(). [Feature #5896]

  Modified files:
    trunk/ChangeLog
    trunk/error.c
    trunk/include/ruby/ruby.h
    trunk/sprintf.c
    trunk/vm_insnhelper.c
    trunk/vsnprintf.c

Index: include/ruby/ruby.h
===================================================================
--- include/ruby/ruby.h	(revision 35775)
+++ include/ruby/ruby.h	(revision 35776)
@@ -120,18 +120,18 @@
 
 #if defined PRIdPTR && !defined PRI_VALUE_PREFIX
 #define PRIdVALUE PRIdPTR
-#define PRIiVALUE PRIiPTR
 #define PRIoVALUE PRIoPTR
 #define PRIuVALUE PRIuPTR
 #define PRIxVALUE PRIxPTR
 #define PRIXVALUE PRIXPTR
+#define PRIsVALUE PRIiPTR
 #else
 #define PRIdVALUE PRI_VALUE_PREFIX"d"
-#define PRIiVALUE PRI_VALUE_PREFIX"i"
 #define PRIoVALUE PRI_VALUE_PREFIX"o"
 #define PRIuVALUE PRI_VALUE_PREFIX"u"
 #define PRIxVALUE PRI_VALUE_PREFIX"x"
 #define PRIXVALUE PRI_VALUE_PREFIX"X"
+#define PRIsVALUE PRI_VALUE_PREFIX"i"
 #endif
 #ifndef PRI_VALUE_PREFIX
 # define PRI_VALUE_PREFIX ""
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 35775)
+++ ChangeLog	(revision 35776)
@@ -1,3 +1,8 @@
+Thu May 24 23:36:51 2012  Nobuyoshi Nakada  <nobu@r...>
+
+	* vsnprintf.c (BSD_vfprintf): [EXPERIMENTAL] object representation in
+	  rb_enc_vsprintf(). [Feature #5896]
+
 Thu May 24 15:33:01 2012  Koichi Sasada  <ko1@a...>
 
 	* vm_method.c (rb_method_defined_by): removed.
Index: vsnprintf.c
===================================================================
--- vsnprintf.c	(revision 35775)
+++ vsnprintf.c	(revision 35776)
@@ -183,6 +183,7 @@
 	struct	__sbuf _bf;	/* the buffer (at least 1 byte, if !NULL) */
 	size_t	_lbfsize;	/* 0 or -_bf._size, for inline putc */
 	int	(*vwrite)(/* struct __sFILE*, struct __suio * */);
+	char	*(*vextra)(/* struct __sFILE*, size_t, void*, long* */);
 } FILE;
 
 
@@ -793,11 +794,39 @@
 			size = 1;
 			sign = '\0';
 			break;
+		case 'i':
+#ifdef _HAVE_SANE_QUAD_
+# define INTPTR_MASK (QUADINT|LONGINT|SHORTINT)
+#else
+# define INTPTR_MASK (LONGINT|SHORTINT)
+#endif
+#if defined _HAVE_SANE_QUAD_ && SIZEOF_VOIDP == SIZEOF_LONG_LONG
+# define INTPTR_FLAG QUADINT
+#elif SIZEOF_VOIDP == SIZEOF_LONG
+# define INTPTR_FLAG LONGINT
+#else
+# define INTPTR_FLAG 0
+#endif
+			if (fp->vextra && (flags & INTPTR_MASK) == INTPTR_FLAG) {
+				FLUSH();
+#if defined _HAVE_SANE_QUAD_ && SIZEOF_VOIDP == SIZEOF_LONG_LONG
+				uqval = va_arg(ap, u_quad_t);
+				cp = (*fp->vextra)(fp, sizeof(uqval), &uqval, &fieldsz);
+#else
+				ulval = va_arg(ap, u_long);
+				cp = (*fp->vextra)(fp, sizeof(ulval), &ulval, &fieldsz);
+#endif
+				if (!cp) goto error;
+				if (prec < 0) goto long_len;
+				size = fieldsz < prec ? (int)fieldsz : prec;
+				break;
+			}
+			goto decimal;
 		case 'D':
 			flags |= LONGINT;
 			/*FALLTHROUGH*/
 		case 'd':
-		case 'i':
+		decimal:
 #ifdef _HAVE_SANE_QUAD_
 			if (flags & QUADINT) {
 				uqval = va_arg(ap, quad_t);
@@ -1269,6 +1298,7 @@
 	f._bf._base = f._p = (unsigned char *)str;
 	f._bf._size = f._w = n - 1;
 	f.vwrite = BSD__sfvwrite;
+	f.vextra = 0;
 	ret = (int)BSD_vfprintf(&f, fmt, ap);
 	*f._p = 0;
 	return (ret);
@@ -1289,6 +1319,7 @@
 	f._bf._base = f._p = (unsigned char *)str;
 	f._bf._size = f._w = n - 1;
 	f.vwrite = BSD__sfvwrite;
+	f.vextra = 0;
 	ret = (int)BSD_vfprintf(&f, fmt, ap);
 	*f._p = 0;
 	va_end(ap);
Index: sprintf.c
===================================================================
--- sprintf.c	(revision 35775)
+++ sprintf.c	(revision 35776)
@@ -1146,6 +1146,11 @@
 #define BSD__hdtoa ruby_hdtoa
 #include "vsnprintf.c"
 
+typedef struct {
+    rb_printf_buffer base;
+    volatile VALUE value;
+} rb_printf_buffer_extra;
+
 static int
 ruby__sfvwrite(register rb_printf_buffer *fp, register struct __suio *uio)
 {
@@ -1172,10 +1177,41 @@
     return 0;
 }
 
+static char *
+ruby__sfvextra(rb_printf_buffer *fp, size_t valsize, void *valp, long *sz)
+{
+    VALUE value, result = (VALUE)fp->_bf._base;
+    rb_encoding *enc;
+    char *cp;
+
+    if (valsize != sizeof(VALUE)) return 0;
+    value = *(VALUE *)valp;
+    if (RBASIC(result)->klass) {
+	rb_raise(rb_eRuntimeError, "rb_vsprintf reentered");
+    }
+    value = rb_obj_as_string(value);
+    enc = rb_enc_compatible(result, value);
+    if (enc) {
+	rb_enc_associate(result, enc);
+    }
+    else {
+	enc = rb_enc_get(result);
+	value = rb_str_conv_enc_opts(value, rb_enc_get(value), enc,
+				     ECONV_UNDEF_REPLACE|ECONV_INVALID_REPLACE,
+				     Qnil);
+	*(volatile VALUE *)valp = value;
+    }
+    StringValueCStr(value);
+    RSTRING_GETMEM(value, cp, *sz);
+    ((rb_printf_buffer_extra *)fp)->value = value;
+    return cp;
+}
+
 VALUE
 rb_enc_vsprintf(rb_encoding *enc, const char *fmt, va_list ap)
 {
-    rb_printf_buffer f;
+    rb_printf_buffer_extra buffer;
+#define f buffer.base
     VALUE result;
 
     f._flags = __SWR | __SSTR;
@@ -1194,9 +1230,12 @@
     f._p = (unsigned char *)RSTRING_PTR(result);
     RBASIC(result)->klass = 0;
     f.vwrite = ruby__sfvwrite;
+    f.vextra = ruby__sfvextra;
+    buffer.value = 0;
     BSD_vfprintf(&f, fmt, ap);
     RBASIC(result)->klass = rb_cString;
     rb_str_resize(result, (char *)f._p - RSTRING_PTR(result));
+#undef f
 
     return result;
 }
@@ -1236,7 +1275,8 @@
 VALUE
 rb_str_vcatf(VALUE str, const char *fmt, va_list ap)
 {
-    rb_printf_buffer f;
+    rb_printf_buffer_extra buffer;
+#define f buffer.base
     VALUE klass;
 
     StringValue(str);
@@ -1249,9 +1289,12 @@
     klass = RBASIC(str)->klass;
     RBASIC(str)->klass = 0;
     f.vwrite = ruby__sfvwrite;
+    f.vextra = ruby__sfvextra;
+    buffer.value = 0;
     BSD_vfprintf(&f, fmt, ap);
     RBASIC(str)->klass = klass;
     rb_str_resize(str, (char *)f._p - RSTRING_PTR(str));
+#undef f
 
     return str;
 }
Index: error.c
===================================================================
--- error.c	(revision 35775)
+++ error.c	(revision 35776)
@@ -1116,9 +1116,9 @@
 void
 rb_invalid_str(const char *str, const char *type)
 {
-    volatile VALUE s = rb_str_inspect(rb_str_new2(str));
+    VALUE s = rb_str_inspect(rb_str_new2(str));
 
-    rb_raise(rb_eArgError, "invalid value for %s: %s", type, RSTRING_PTR(s));
+    rb_raise(rb_eArgError, "invalid value for %s: %"PRIsVALUE, type, s);
 }
 
 /*
Index: vm_insnhelper.c
===================================================================
--- vm_insnhelper.c	(revision 35775)
+++ vm_insnhelper.c	(revision 35776)
@@ -154,10 +154,9 @@
     }
     keys = rb_funcall(hash, rb_intern("keys"), 0, 0);
     if (!RB_TYPE_P(keys, T_ARRAY)) rb_raise(rb_eArgError, "unknown keyword");
-    msg = RARRAY_LEN(keys) == 1 ? "unknown keyword: %s" : "unknown keywords: %s";
+    msg = RARRAY_LEN(keys) == 1 ? "" : "s";
     keys = rb_funcall(keys, rb_intern("join"), 1, sep);
-    RB_GC_GUARD(keys);
-    rb_raise(rb_eArgError, msg, RSTRING_PTR(keys));
+    rb_raise(rb_eArgError, "unknown keyword%s: %"PRIsVALUE, msg, keys);
 }
 
 void

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]