mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Feature #5896
* vsnprintf.c (BSD_vfprintf): [EXPERIMENTAL] object representation in rb_enc_vsprintf(). [Feature #5896] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@35776 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
60e8cd2e68
commit
ce8e2d5404
6 changed files with 88 additions and 10 deletions
|
@ -1,3 +1,8 @@
|
||||||
|
Thu May 24 23:36:51 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* vsnprintf.c (BSD_vfprintf): [EXPERIMENTAL] object representation in
|
||||||
|
rb_enc_vsprintf(). [Feature #5896]
|
||||||
|
|
||||||
Thu May 24 15:33:01 2012 Koichi Sasada <ko1@atdot.net>
|
Thu May 24 15:33:01 2012 Koichi Sasada <ko1@atdot.net>
|
||||||
|
|
||||||
* vm_method.c (rb_method_defined_by): removed.
|
* vm_method.c (rb_method_defined_by): removed.
|
||||||
|
|
4
error.c
4
error.c
|
@ -1116,9 +1116,9 @@ nometh_err_args(VALUE self)
|
||||||
void
|
void
|
||||||
rb_invalid_str(const char *str, const char *type)
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -120,18 +120,18 @@ typedef char ruby_check_sizeof_voidp[SIZEOF_VOIDP == sizeof(void*) ? 1 : -1];
|
||||||
|
|
||||||
#if defined PRIdPTR && !defined PRI_VALUE_PREFIX
|
#if defined PRIdPTR && !defined PRI_VALUE_PREFIX
|
||||||
#define PRIdVALUE PRIdPTR
|
#define PRIdVALUE PRIdPTR
|
||||||
#define PRIiVALUE PRIiPTR
|
|
||||||
#define PRIoVALUE PRIoPTR
|
#define PRIoVALUE PRIoPTR
|
||||||
#define PRIuVALUE PRIuPTR
|
#define PRIuVALUE PRIuPTR
|
||||||
#define PRIxVALUE PRIxPTR
|
#define PRIxVALUE PRIxPTR
|
||||||
#define PRIXVALUE PRIXPTR
|
#define PRIXVALUE PRIXPTR
|
||||||
|
#define PRIsVALUE PRIiPTR
|
||||||
#else
|
#else
|
||||||
#define PRIdVALUE PRI_VALUE_PREFIX"d"
|
#define PRIdVALUE PRI_VALUE_PREFIX"d"
|
||||||
#define PRIiVALUE PRI_VALUE_PREFIX"i"
|
|
||||||
#define PRIoVALUE PRI_VALUE_PREFIX"o"
|
#define PRIoVALUE PRI_VALUE_PREFIX"o"
|
||||||
#define PRIuVALUE PRI_VALUE_PREFIX"u"
|
#define PRIuVALUE PRI_VALUE_PREFIX"u"
|
||||||
#define PRIxVALUE PRI_VALUE_PREFIX"x"
|
#define PRIxVALUE PRI_VALUE_PREFIX"x"
|
||||||
#define PRIXVALUE PRI_VALUE_PREFIX"X"
|
#define PRIXVALUE PRI_VALUE_PREFIX"X"
|
||||||
|
#define PRIsVALUE PRI_VALUE_PREFIX"i"
|
||||||
#endif
|
#endif
|
||||||
#ifndef PRI_VALUE_PREFIX
|
#ifndef PRI_VALUE_PREFIX
|
||||||
# define PRI_VALUE_PREFIX ""
|
# define PRI_VALUE_PREFIX ""
|
||||||
|
|
47
sprintf.c
47
sprintf.c
|
@ -1146,6 +1146,11 @@ fmt_setup(char *buf, size_t size, int c, int flags, int width, int prec)
|
||||||
#define BSD__hdtoa ruby_hdtoa
|
#define BSD__hdtoa ruby_hdtoa
|
||||||
#include "vsnprintf.c"
|
#include "vsnprintf.c"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
rb_printf_buffer base;
|
||||||
|
volatile VALUE value;
|
||||||
|
} rb_printf_buffer_extra;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ruby__sfvwrite(register rb_printf_buffer *fp, register struct __suio *uio)
|
ruby__sfvwrite(register rb_printf_buffer *fp, register struct __suio *uio)
|
||||||
{
|
{
|
||||||
|
@ -1172,10 +1177,41 @@ ruby__sfvwrite(register rb_printf_buffer *fp, register struct __suio *uio)
|
||||||
return 0;
|
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
|
VALUE
|
||||||
rb_enc_vsprintf(rb_encoding *enc, const char *fmt, va_list ap)
|
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;
|
VALUE result;
|
||||||
|
|
||||||
f._flags = __SWR | __SSTR;
|
f._flags = __SWR | __SSTR;
|
||||||
|
@ -1194,9 +1230,12 @@ rb_enc_vsprintf(rb_encoding *enc, const char *fmt, va_list ap)
|
||||||
f._p = (unsigned char *)RSTRING_PTR(result);
|
f._p = (unsigned char *)RSTRING_PTR(result);
|
||||||
RBASIC(result)->klass = 0;
|
RBASIC(result)->klass = 0;
|
||||||
f.vwrite = ruby__sfvwrite;
|
f.vwrite = ruby__sfvwrite;
|
||||||
|
f.vextra = ruby__sfvextra;
|
||||||
|
buffer.value = 0;
|
||||||
BSD_vfprintf(&f, fmt, ap);
|
BSD_vfprintf(&f, fmt, ap);
|
||||||
RBASIC(result)->klass = rb_cString;
|
RBASIC(result)->klass = rb_cString;
|
||||||
rb_str_resize(result, (char *)f._p - RSTRING_PTR(result));
|
rb_str_resize(result, (char *)f._p - RSTRING_PTR(result));
|
||||||
|
#undef f
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -1236,7 +1275,8 @@ rb_sprintf(const char *format, ...)
|
||||||
VALUE
|
VALUE
|
||||||
rb_str_vcatf(VALUE str, const char *fmt, va_list ap)
|
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;
|
VALUE klass;
|
||||||
|
|
||||||
StringValue(str);
|
StringValue(str);
|
||||||
|
@ -1249,9 +1289,12 @@ rb_str_vcatf(VALUE str, const char *fmt, va_list ap)
|
||||||
klass = RBASIC(str)->klass;
|
klass = RBASIC(str)->klass;
|
||||||
RBASIC(str)->klass = 0;
|
RBASIC(str)->klass = 0;
|
||||||
f.vwrite = ruby__sfvwrite;
|
f.vwrite = ruby__sfvwrite;
|
||||||
|
f.vextra = ruby__sfvextra;
|
||||||
|
buffer.value = 0;
|
||||||
BSD_vfprintf(&f, fmt, ap);
|
BSD_vfprintf(&f, fmt, ap);
|
||||||
RBASIC(str)->klass = klass;
|
RBASIC(str)->klass = klass;
|
||||||
rb_str_resize(str, (char *)f._p - RSTRING_PTR(str));
|
rb_str_resize(str, (char *)f._p - RSTRING_PTR(str));
|
||||||
|
#undef f
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
|
@ -154,10 +154,9 @@ unknown_keyword_error(const rb_iseq_t *iseq, VALUE hash)
|
||||||
}
|
}
|
||||||
keys = rb_funcall(hash, rb_intern("keys"), 0, 0);
|
keys = rb_funcall(hash, rb_intern("keys"), 0, 0);
|
||||||
if (!RB_TYPE_P(keys, T_ARRAY)) rb_raise(rb_eArgError, "unknown keyword");
|
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);
|
keys = rb_funcall(keys, rb_intern("join"), 1, sep);
|
||||||
RB_GC_GUARD(keys);
|
rb_raise(rb_eArgError, "unknown keyword%s: %"PRIsVALUE, msg, keys);
|
||||||
rb_raise(rb_eArgError, msg, RSTRING_PTR(keys));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
33
vsnprintf.c
33
vsnprintf.c
|
@ -183,6 +183,7 @@ typedef struct __sFILE {
|
||||||
struct __sbuf _bf; /* the buffer (at least 1 byte, if !NULL) */
|
struct __sbuf _bf; /* the buffer (at least 1 byte, if !NULL) */
|
||||||
size_t _lbfsize; /* 0 or -_bf._size, for inline putc */
|
size_t _lbfsize; /* 0 or -_bf._size, for inline putc */
|
||||||
int (*vwrite)(/* struct __sFILE*, struct __suio * */);
|
int (*vwrite)(/* struct __sFILE*, struct __suio * */);
|
||||||
|
char *(*vextra)(/* struct __sFILE*, size_t, void*, long* */);
|
||||||
} FILE;
|
} FILE;
|
||||||
|
|
||||||
|
|
||||||
|
@ -793,11 +794,39 @@ reswitch: switch (ch) {
|
||||||
size = 1;
|
size = 1;
|
||||||
sign = '\0';
|
sign = '\0';
|
||||||
break;
|
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':
|
case 'D':
|
||||||
flags |= LONGINT;
|
flags |= LONGINT;
|
||||||
/*FALLTHROUGH*/
|
/*FALLTHROUGH*/
|
||||||
case 'd':
|
case 'd':
|
||||||
case 'i':
|
decimal:
|
||||||
#ifdef _HAVE_SANE_QUAD_
|
#ifdef _HAVE_SANE_QUAD_
|
||||||
if (flags & QUADINT) {
|
if (flags & QUADINT) {
|
||||||
uqval = va_arg(ap, quad_t);
|
uqval = va_arg(ap, quad_t);
|
||||||
|
@ -1269,6 +1298,7 @@ ruby_vsnprintf(char *str, size_t n, const char *fmt, va_list ap)
|
||||||
f._bf._base = f._p = (unsigned char *)str;
|
f._bf._base = f._p = (unsigned char *)str;
|
||||||
f._bf._size = f._w = n - 1;
|
f._bf._size = f._w = n - 1;
|
||||||
f.vwrite = BSD__sfvwrite;
|
f.vwrite = BSD__sfvwrite;
|
||||||
|
f.vextra = 0;
|
||||||
ret = (int)BSD_vfprintf(&f, fmt, ap);
|
ret = (int)BSD_vfprintf(&f, fmt, ap);
|
||||||
*f._p = 0;
|
*f._p = 0;
|
||||||
return (ret);
|
return (ret);
|
||||||
|
@ -1289,6 +1319,7 @@ ruby_snprintf(char *str, size_t n, char const *fmt, ...)
|
||||||
f._bf._base = f._p = (unsigned char *)str;
|
f._bf._base = f._p = (unsigned char *)str;
|
||||||
f._bf._size = f._w = n - 1;
|
f._bf._size = f._w = n - 1;
|
||||||
f.vwrite = BSD__sfvwrite;
|
f.vwrite = BSD__sfvwrite;
|
||||||
|
f.vextra = 0;
|
||||||
ret = (int)BSD_vfprintf(&f, fmt, ap);
|
ret = (int)BSD_vfprintf(&f, fmt, ap);
|
||||||
*f._p = 0;
|
*f._p = 0;
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
Loading…
Add table
Reference in a new issue