summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2005-07-23 01:02:18 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2005-07-23 01:02:18 +0000
commit6524f34a2688436249d111a3456a097c7111722c (patch)
treef9c83bf95a7873e01e38ff396a8bc5490b61162c
parente6a02b93747266925fd536a30715352bf2c60c07 (diff)
* sprintf.c (rb_vsprintf, rb_sprintf): new functions return new String,
using missing/vsnprintf.c. [ruby-dev:26580] * missing/vsnprintf.c: made the output changeable. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@8825 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog45
-rw-r--r--common.mk3
-rw-r--r--configure.in3
-rw-r--r--error.c8
-rw-r--r--eval.c40
-rw-r--r--intern.h15
-rw-r--r--io.c7
-rw-r--r--missing/vsnprintf.c28
-rw-r--r--object.c12
-rw-r--r--parse.y6
-rw-r--r--process.c3
-rw-r--r--sprintf.c117
-rw-r--r--string.c17
-rw-r--r--struct.c12
-rw-r--r--variable.c6
-rw-r--r--win32/win32.c4
-rw-r--r--win32/win32.h6
17 files changed, 200 insertions, 132 deletions
diff --git a/ChangeLog b/ChangeLog
index 3cd9dc4f71..bc1d741a98 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Sat Jul 23 10:01:41 2005 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * sprintf.c (rb_vsprintf, rb_sprintf): new functions return new String,
+ using missing/vsnprintf.c. [ruby-dev:26580]
+
+ * missing/vsnprintf.c: made the output changeable.
+
Fri Jul 22 15:02:39 2005 Kouhei Sutou <kou@cozmixng.org>
* lib/rss/rss.rb: moved copyright description to lib/rss.rb.
@@ -13,7 +20,7 @@ Fri Jul 22 15:02:39 2005 Kouhei Sutou <kou@cozmixng.org>
* sample/rss/tdiary-plugin/rss-recent.rb: ditto.
* sample/rss/tdiary-plugin/rss-recent.rb: 0.0.6 -> 0.0.7.
-
+
Fri Jul 22 14:37:43 2005 Kouhei Sutou <kou@cozmixng.org>
* lib/rss/parser.rb (RSS::Parser#initialize): accept HTTP/FTP
@@ -24,48 +31,48 @@ Fri Jul 22 14:37:43 2005 Kouhei Sutou <kou@cozmixng.org>
Fri Jul 22 07:01:42 2005 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
- * ext/tk/tkutil/tkutil.c (tk_conv_args): forget to revert
+ * ext/tk/tkutil/tkutil.c (tk_conv_args): forget to revert
thread_critical and gc_disable when raise ArgumentError.
* ext/tk/lib/remote-tk.rb: RemoteTkIp doesn't need to include TkUtil.
* ext/tk/tcltklib.c: add TclTkIp#has_mainwindow? method.
- * ext/tk/lib/tk.rb: add Tk.has_mainwindow? method.
+ * ext/tk/lib/tk.rb: add Tk.has_mainwindow? method.
- * ext/tk/lib/multi-tk.rb: add MultiTkIp#has_mainwindow? method.
+ * ext/tk/lib/multi-tk.rb: add MultiTkIp#has_mainwindow? method.
- * ext/tk/lib/remote-tk.rb: add RemoteTkIp#has_mainwindow? method.
+ * ext/tk/lib/remote-tk.rb: add RemoteTkIp#has_mainwindow? method.
* ext/tk/lib/multi-tk.rb: slave IP fail to exit itself when $SAFE==4.
- * ext/tk/lib/multi-tk.rb: remove constants from MultiTkIp module to
+ * ext/tk/lib/multi-tk.rb: remove constants from MultiTkIp module to
avoid access from external.
- * ext/tk/lib/multi-tk.rb: check_root flag is ignored on slave IPs'
- mainloop.
+ * ext/tk/lib/multi-tk.rb: check_root flag is ignored on slave IPs'
+ mainloop.
- * ext/tk/lib/multi-tk.rb: hang-up Tk.mainloop called on a slave IP
+ * ext/tk/lib/multi-tk.rb: hang-up Tk.mainloop called on a slave IP
with $SAFE==4.
* ext/tk/lib/multi-tk.rb: MultiTkIp#bg_eval_proc doesn't work
- properly.
+ properly.
* ext/tk/lib/multi-tk.rb: add MultiTkIp#set_cb_error(proc) and
- cb_error(exc) to log errors at callbacks on safe slave IPs.
+ cb_error(exc) to log errors at callbacks on safe slave IPs.
- * ext/tk/lib/multi-tk.rb: fail to get an available slave IP object
- when call Tk.mainloop in the block which is given to new_* method,
- because cannot finish initialize while the root widget is alive.
+ * ext/tk/lib/multi-tk.rb: fail to get an available slave IP object
+ when call Tk.mainloop in the block which is given to new_* method,
+ because cannot finish initialize while the root widget is alive.
- * ext/tk/lib/multi-tk.rb: fail to control a slave IP when Tk.mainloop
+ * ext/tk/lib/multi-tk.rb: fail to control a slave IP when Tk.mainloop
runs on the IP.
Thu Jul 21 01:00:00 2005 NARUSE, Yui <naruse@ruby-lang.org>
- * ext/nkf/nkf-utf8/{nkf.c,utf8tbl.c,config.h}:
- import 1.76
- [ruby-dev:26592] nkf constification
+ * ext/nkf/nkf-utf8/{nkf.c,utf8tbl.c,config.h}:
+ import 1.76
+ [ruby-dev:26592] nkf constification
Wed Jul 20 19:18:52 2005 NAKAMURA Usaku <usa@ruby-lang.org>
@@ -132,7 +139,7 @@ Tue Jul 19 14:10:50 2005 Hirokazu Yamamoto <ocean@m2.ccsnet.ne.jp>
Tue Jul 19 13:19:46 2005 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tk/lib/tk/variable.rb: For symmetry, add TkVariable#string. It
- returns a string even if the default value type of the TkVariable
+ returns a string even if the default value type of the TkVariable
object is not "string".
Mon Jul 18 21:39:18 2005 Hirokazu Yamamoto <ocean@m2.ccsnet.ne.jp>
diff --git a/common.mk b/common.mk
index 9df384f878..e53aaf89dd 100644
--- a/common.mk
+++ b/common.mk
@@ -178,7 +178,6 @@ flock.$(OBJEXT): {$(VPATH)}flock.c
memcmp.$(OBJEXT): {$(VPATH)}memcmp.c
memmove.$(OBJEXT): {$(VPATH)}memmove.c
mkdir.$(OBJEXT): {$(VPATH)}mkdir.c
-vsnprintf.$(OBJEXT): {$(VPATH)}vsnprintf.c
strcasecmp.$(OBJEXT): {$(VPATH)}strcasecmp.c
strncasecmp.$(OBJEXT): {$(VPATH)}strncasecmp.c
strchr.$(OBJEXT): {$(VPATH)}strchr.c
@@ -302,7 +301,7 @@ signal.$(OBJEXT): {$(VPATH)}signal.c {$(VPATH)}ruby.h config.h \
sjis.$(OBJEXT): {$(VPATH)}sjis.c {$(VPATH)}regenc.h \
{$(VPATH)}oniguruma.h config.h
sprintf.$(OBJEXT): {$(VPATH)}sprintf.c {$(VPATH)}ruby.h config.h \
- {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h
+ {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h {$(VPATH)}missing/vsnprintf.c
st.$(OBJEXT): {$(VPATH)}st.c config.h {$(VPATH)}st.h
string.$(OBJEXT): {$(VPATH)}string.c {$(VPATH)}ruby.h config.h \
{$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \
diff --git a/configure.in b/configure.in
index 2028f89a77..87e453b2e8 100644
--- a/configure.in
+++ b/configure.in
@@ -353,7 +353,6 @@ mingw*) LIBS="-lshell32 -lws2_32 $LIBS"
ac_cv_func_times=yes
ac_cv_func_waitpid=yes
ac_cv_func_fsync=yes
- ac_cv_func_vsnprintf=yes
ac_cv_func_seekdir=yes
ac_cv_func_telldir=yes
ac_cv_func_isinf=yes
@@ -482,7 +481,7 @@ AC_TYPE_SIGNAL
AC_FUNC_ALLOCA
AC_FUNC_MEMCMP
AC_REPLACE_FUNCS(dup2 memmove strcasecmp strncasecmp strerror strftime\
- strchr strstr strtoul crypt flock vsnprintf\
+ strchr strstr strtoul crypt flock\
isnan finite isinf hypot acosh erf)
AC_CHECK_FUNCS(fmod killpg wait4 waitpid fork spawnv syscall chroot fsync getcwd\
truncate chsize times utimes fcntl lockf lstat link symlink readlink\
diff --git a/error.c b/error.c
index f35dc2ba3e..48cb00da38 100644
--- a/error.c
+++ b/error.c
@@ -956,14 +956,10 @@ syserr_initialize(argc, argv, self)
else err = "unknown error";
if (!NIL_P(mesg)) {
VALUE str = mesg;
- size_t len;
StringValue(str);
- len = strlen(err)+RSTRING(str)->len+3;
- mesg = rb_str_new(0, len);
- snprintf(RSTRING(mesg)->ptr, len+1, "%s - %.*s", err,
- (int)RSTRING(str)->len, RSTRING(str)->ptr);
- RSTRING(mesg)->len = strlen(RSTRING(mesg)->ptr);
+ mesg = rb_sprintf("%s - %.*s", err,
+ (int)RSTRING(str)->len, RSTRING(str)->ptr);
}
else {
mesg = rb_str_new2(err);
diff --git a/eval.c b/eval.c
index 2058ae7b5e..1b4559c67d 100644
--- a/eval.c
+++ b/eval.c
@@ -6120,7 +6120,7 @@ backtrace(lev)
int lev;
{
struct FRAME *frame = ruby_frame;
- char buf[BUFSIZ];
+ VALUE str;
volatile VALUE ary;
NODE *n;
@@ -6131,17 +6131,16 @@ backtrace(lev)
if (lev < 0) {
ruby_set_current_source();
if (frame->this_func) {
- snprintf(buf, BUFSIZ, "%s:%d:in `%s'",
- ruby_sourcefile, ruby_sourceline,
- rb_id2name(frame->this_func));
+ str = rb_sprintf("%s:%d:in `%s'", ruby_sourcefile, ruby_sourceline,
+ rb_id2name(frame->this_func));
}
else if (ruby_sourceline == 0) {
- snprintf(buf, BUFSIZ, "%s", ruby_sourcefile);
+ str = rb_str_new2(ruby_sourcefile);
}
else {
- snprintf(buf, BUFSIZ, "%s:%d", ruby_sourcefile, ruby_sourceline);
+ str = rb_sprintf("%s:%d", ruby_sourcefile, ruby_sourceline);
}
- rb_ary_push(ary, rb_str_new2(buf));
+ rb_ary_push(ary, str);
if (lev < -1) return ary;
}
else {
@@ -6156,14 +6155,13 @@ backtrace(lev)
for (; frame && (n = frame->node); frame = frame->prev) {
if (frame->prev && frame->prev->this_func) {
if (frame->prev->node == n) continue;
- snprintf(buf, BUFSIZ, "%s:%d:in `%s'",
- n->nd_file, nd_line(n),
- rb_id2name(frame->prev->this_func));
+ str = rb_sprintf("%s:%d:in `%s'", n->nd_file, nd_line(n),
+ rb_id2name(frame->prev->this_func));
}
else {
- snprintf(buf, BUFSIZ, "%s:%d", n->nd_file, nd_line(n));
+ str = rb_sprintf("%s:%d", n->nd_file, nd_line(n));
}
- rb_ary_push(ary, rb_str_new2(buf));
+ rb_ary_push(ary, str);
}
return ary;
@@ -8667,23 +8665,16 @@ proc_to_s(self)
NODE *node;
char *cname = rb_obj_classname(self);
const int w = (SIZEOF_LONG * CHAR_BIT) / 4;
- long len = strlen(cname)+6+w; /* 6:tags 16:addr */
VALUE str;
Data_Get_Struct(self, struct BLOCK, data);
if ((node = data->frame.node) || (node = data->body)) {
- len += strlen(node->nd_file) + 2 + (SIZEOF_LONG*CHAR_BIT-NODE_LSHIFT)/3;
- str = rb_str_new(0, len);
- snprintf(RSTRING(str)->ptr, len+1,
- "#<%s:0x%.*lx@%s:%d>", cname, w, (VALUE)data->body,
- node->nd_file, nd_line(node));
+ str = rb_sprintf("#<%s:0x%.*lx@%s:%d>", cname, w, (VALUE)data->body,
+ node->nd_file, nd_line(node));
}
else {
- str = rb_str_new(0, len);
- snprintf(RSTRING(str)->ptr, len+1,
- "#<%s:0x%.*lx>", cname, w, (VALUE)data->body);
+ str = rb_sprintf("#<%s:0x%.*lx>", cname, w, (VALUE)data->body);
}
- RSTRING(str)->len = strlen(RSTRING(str)->ptr);
if (OBJ_TAINTED(self)) OBJ_TAINT(str);
return str;
@@ -12761,11 +12752,8 @@ rb_thread_inspect(thread)
rb_thread_t th = rb_thread_check(thread);
const char *status = thread_status_name(th->status);
VALUE str;
- size_t len = strlen(cname)+7+16+9+1;
- str = rb_str_new(0, len); /* 7:tags 16:addr 9:status 1:nul */
- snprintf(RSTRING(str)->ptr, len, "#<%s:0x%lx %s>", cname, thread, status);
- RSTRING(str)->len = strlen(RSTRING(str)->ptr);
+ str = rb_sprintf("#<%s:0x%lx %s>", cname, thread, status);
OBJ_INFECT(str, thread);
return str;
diff --git a/intern.h b/intern.h
index e61e394b60..fe5737343d 100644
--- a/intern.h
+++ b/intern.h
@@ -15,6 +15,12 @@
#ifndef RUBY_INTERN_H
#define RUBY_INTERN_H 1
+#ifdef HAVE_STDARG_PROTOTYPES
+# include <stdarg.h>
+#else
+# include <varargs.h>
+#endif
+
/*
* Functions and variables that are used by more than one source file of
* the kernel.
@@ -449,7 +455,14 @@ void rb_trap_exit _((void));
void rb_trap_exec _((void));
const char *ruby_signal_name _((int));
/* sprintf.c */
-VALUE rb_f_sprintf _((int, VALUE*));
+VALUE rb_f_sprintf _((int, const VALUE*));
+VALUE rb_sprintf __((const char*, ...))
+#ifdef __GNUC__
+ __attribute__((format(printf,1,2)))
+#endif
+ ;
+VALUE rb_vsprintf _((const char*, va_list));
+VALUE rb_str_format _((int, const VALUE *, VALUE));
/* string.c */
VALUE rb_str_new _((const char*, long));
VALUE rb_str_new2 _((const char*));
diff --git a/io.c b/io.c
index e128a1b8c1..020ed7e873 100644
--- a/io.c
+++ b/io.c
@@ -1093,19 +1093,14 @@ rb_io_inspect(obj)
{
OpenFile *fptr;
char *buf, *cname, *st = "";
- long len;
fptr = RFILE(rb_io_taint_check(obj))->fptr;
if (!fptr || !fptr->path) return rb_any_to_s(obj);
cname = rb_obj_classname(obj);
- len = strlen(cname) + strlen(fptr->path) + 5;
if (fptr->fd < 0) {
st = " (closed)";
- len += 9;
}
- buf = ALLOCA_N(char, len);
- snprintf(buf, len, "#<%s:%s%s>", cname, fptr->path, st);
- return rb_str_new2(buf);
+ return rb_sprintf("#<%s:%s%s>", cname, fptr->path, st);
}
/*
diff --git a/missing/vsnprintf.c b/missing/vsnprintf.c
index e3362a91f9..1fcbb36bfd 100644
--- a/missing/vsnprintf.c
+++ b/missing/vsnprintf.c
@@ -65,8 +65,14 @@
#define u_short unsigned short
#define u_int unsigned int
-#undef __P
+#if !defined(HAVE_STDARG_PROTOTYPES)
#if defined(__STDC__)
+#define HAVE_STDARG_PROTOTYPES 1
+#endif
+#endif
+
+#undef __P
+#if defined(HAVE_STDARG_PROTOTYPES)
# include <stdarg.h>
# if !defined(__P)
# define __P(x) x
@@ -151,12 +157,15 @@ struct __sbuf {
*/
typedef struct __sFILE {
unsigned char *_p; /* current position in (some) buffer */
+#if 0
int _r; /* read space left for getc() */
+#endif
int _w; /* write space left for putc() */
short _flags; /* flags, below; this FILE is free if 0 */
short _file; /* fileno, if Unix descriptor, else -1 */
struct __sbuf _bf; /* the buffer (at least 1 byte, if !NULL) */
int _lbfsize; /* 0 or -_bf._size, for inline putc */
+ int (*vwrite)(/* struct __sFILE*, struct __suio * */);
} FILE;
@@ -673,10 +682,9 @@ reswitch: switch (ch) {
uqval = -uqval;
sign = '-';
}
- } else {
-#else /* _HAVE_SANE_QUAD_ */
- {
+ } else
#endif /* _HAVE_SANE_QUAD_ */
+ {
ulval = SARG();
if ((long)ulval < 0) {
ulval = -ulval;
@@ -1083,6 +1091,7 @@ vsnprintf(str, n, fmt, ap)
f._flags = __SWR | __SSTR;
f._bf._base = f._p = (unsigned char *)str;
f._bf._size = f._w = n - 1;
+ f.vwrite = BSD__sfvwrite;
ret = BSD_vfprintf(&f, fmt, ap);
*f._p = 0;
return (ret);
@@ -1092,14 +1101,8 @@ vsnprintf(str, n, fmt, ap)
static char sccsid[] = "@(#)snprintf.c 8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */
-#if defined(__STDC__)
-# include <stdarg.h>
-#else
-# include <varargs.h>
-#endif
-
int
-#if defined(__STDC__)
+#if defined(HAVE_STDARG_PROTOTYPES)
snprintf(char *str, size_t n, char const *fmt, ...)
#else
snprintf(str, n, fmt, va_alist)
@@ -1115,7 +1118,7 @@ va_dcl
if ((int)n < 1)
return (EOF);
-#if defined(__STDC__)
+#if defined(HAVE_STDARG_PROTOTYPES)
va_start(ap, fmt);
#else
va_start(ap);
@@ -1123,6 +1126,7 @@ va_dcl
f._flags = __SWR | __SSTR;
f._bf._base = f._p = (unsigned char *)str;
f._bf._size = f._w = n - 1;
+ f.vwrite = BSD__sfvwrite;
ret = BSD_vfprintf(&f, fmt, ap);
*f._p = 0;
va_end(ap);
diff --git a/object.c b/object.c
index af8f289f46..e505b60ea7 100644
--- a/object.c
+++ b/object.c
@@ -298,13 +298,9 @@ rb_any_to_s(obj)
VALUE obj;
{
char *cname = rb_obj_classname(obj);
- size_t len;
VALUE str;
- len = strlen(cname)+6+16;
- str = rb_str_new(0, len); /* 6:tags 16:addr */
- snprintf(RSTRING(str)->ptr, len+1, "#<%s:0x%lx>", cname, obj);
- RSTRING(str)->len = strlen(RSTRING(str)->ptr);
+ str = rb_sprintf("#<%s:0x%lx>", cname, obj);
if (OBJ_TAINTED(obj)) OBJ_TAINT(str);
return str;
@@ -385,14 +381,10 @@ rb_obj_inspect(obj)
&& ROBJECT(obj)->iv_tbl
&& ROBJECT(obj)->iv_tbl->num_entries > 0) {
VALUE str;
- size_t len;
char *c;
c = rb_obj_classname(obj);
- len = strlen(c)+10+16;
- str = rb_str_new(0, len); /* 10:tags 16:addr */
- snprintf(RSTRING(str)->ptr, len+1, "-<%s:0x%lx", c, obj);
- RSTRING(str)->len = strlen(RSTRING(str)->ptr);
+ str = rb_sprintf("-<%s:0x%lx", c, obj);
return rb_exec_recursive(inspect_obj, obj, str);
}
return rb_funcall(obj, rb_intern("to_s"), 0, 0);
diff --git a/parse.y b/parse.y
index d743b76765..3ac72387b0 100644
--- a/parse.y
+++ b/parse.y
@@ -8904,13 +8904,13 @@ ripper_compile_error(parser, fmt, va_alist)
va_dcl
#endif
{
- char buf[BUFSIZ];
+ VALUE str;
va_list args;
va_init_list(args, fmt);
- vsnprintf(buf, BUFSIZ, fmt, args);
+ str = rb_vsprintf(fmt, args);
va_end(args);
- rb_funcall(parser->value, rb_intern("compile_error"), 1, rb_str_new2(buf));
+ rb_funcall(parser->value, rb_intern("compile_error"), 1, str);
}
static void
diff --git a/process.c b/process.c
index 6e10e7eb35..2a865de9b0 100644
--- a/process.c
+++ b/process.c
@@ -280,8 +280,7 @@ pst_inspect(st)
pid = pst_pid(st);
status = NUM2INT(st);
- snprintf(buf, sizeof(buf), "#<%s: pid=%ld", rb_class2name(CLASS_OF(st)), NUM2LONG(pid));
- str = rb_str_new2(buf);
+ str = rb_sprintf("#<%s: pid=%ld", rb_class2name(CLASS_OF(st)), NUM2LONG(pid));
if (WIFSTOPPED(status)) {
int stopsig = WSTOPSIG(status);
const char *signame = ruby_signal_name(stopsig);
diff --git a/sprintf.c b/sprintf.c
index 59195450bc..bdb24c1da0 100644
--- a/sprintf.c
+++ b/sprintf.c
@@ -15,6 +15,13 @@
#include "ruby.h"
#include <ctype.h>
#include <math.h>
+#ifdef HAVE_STDARG_PROTOTYPES
+#include <stdarg.h>
+#define va_init_list(a,b) va_start(a,b)
+#else
+#include <varargs.h>
+#define va_init_list(a,b) va_start(a)
+#endif
#define BIT_DIGITS(N) (((N)*146)/485 + 1) /* log2(10) =~ 146/485 */
@@ -96,6 +103,12 @@ sign_bits(base, p)
blen += (l);\
} while (0)
+#define FILL(c, l) do { \
+ CHECK(l);\
+ memset(&buf[blen], c, l);\
+ blen += (l);\
+} while (0)
+
#define GETARG() (nextvalue != Qundef ? nextvalue : \
posarg < 0 ? \
(rb_raise(rb_eArgError, "unnumbered(%d) mixed with numbered", nextarg), 0) : \
@@ -230,9 +243,17 @@ sign_bits(base, p)
VALUE
rb_f_sprintf(argc, argv)
int argc;
- VALUE *argv;
+ const VALUE *argv;
{
+ return rb_str_format(argc - 1, argv + 1, GETNTHARG(0));
+}
+
+VALUE
+rb_str_format(argc, argv, fmt)
+ int argc;
+ const VALUE *argv;
VALUE fmt;
+{
const char *p, *end;
char *buf;
int blen, bsiz;
@@ -246,7 +267,8 @@ rb_f_sprintf(argc, argv)
VALUE tmp;
VALUE str;
- fmt = GETNTHARG(0);
+ ++argc;
+ --argv;
if (OBJ_TAINTED(fmt)) tainted = 1;
StringValue(fmt);
fmt = rb_str_new4(fmt);
@@ -380,13 +402,14 @@ rb_f_sprintf(argc, argv)
VALUE val = GETARG();
char c;
- if (!(flags & FMINUS))
- while (--width > 0)
- PUSH(" ", 1);
c = NUM2INT(val) & 0xff;
- PUSH(&c, 1);
- while (--width > 0)
- PUSH(" ", 1);
+ if (!(flags & FWIDTH)) {
+ PUSH(&c, 1);
+ }
+ else {
+ FILL(' ', width);
+ buf[blen - ((flags & FMINUS) ? width : 1)] = c;
+ }
}
break;
@@ -807,3 +830,81 @@ fmt_setup(buf, c, flags, width, prec)
*buf++ = c;
*buf = '\0';
}
+
+#undef FILE
+#define FILE rb_printf_buffer
+#define __sbuf rb_printf_sbuf
+#define __sFILE rb_printf_sfile
+#undef feof
+#undef ferror
+#undef fileno
+#include "missing/vsnprintf.c"
+
+static int
+ruby__sfvwrite(fp, uio)
+ register rb_printf_buffer *fp;
+ register struct __suio *uio;
+{
+ struct __siov *iov;
+ VALUE result = (VALUE)fp->_bf._base;
+ char *buf = fp->_p;
+ size_t len, n;
+ int blen = buf - RSTRING(result)->ptr, bsiz = fp->_w;
+
+ if (RBASIC(result)->klass) {
+ rb_raise(rb_eRuntimeError, "rb_vsprintf reentered");
+ }
+ if ((len = uio->uio_resid) == 0)
+ return 0;
+ CHECK(len);
+ fp->_w = bsiz;
+ for (iov = uio->uio_iov; len > 0; ++iov) {
+ MEMCPY(buf, iov->iov_base, char, n = iov->iov_len);
+ buf += n;
+ len -= n;
+ }
+ fp->_p = (unsigned char *)buf;
+ return 0;
+}
+
+VALUE
+rb_vsprintf(fmt, ap)
+ const char *fmt;
+ va_list ap;
+{
+ rb_printf_buffer f;
+ VALUE result;
+
+ f._flags = __SWR | __SSTR;
+ f._bf._size = 0;
+ f._w = 120;
+ result = rb_str_buf_new(f._w);
+ f._bf._base = (unsigned char *)result;
+ f._p = (unsigned char *)RSTRING(result)->ptr;
+ RBASIC(result)->klass = 0;
+ f.vwrite = ruby__sfvwrite;
+ BSD_vfprintf(&f, fmt, ap);
+ RBASIC(result)->klass = rb_cString;
+ rb_str_resize(result, (char *)f._p - RSTRING(result)->ptr);
+
+ return result;
+}
+
+VALUE
+#ifdef HAVE_STDARG_PROTOTYPES
+rb_sprintf(const char *format, ...)
+#else
+ruby_sprintf(format, va_alist)
+ const char *format;
+ va_dcl
+#endif
+{
+ VALUE result;
+ va_list ap;
+
+ va_init_list(ap, format);
+ result = rb_vsprintf(format, ap);
+ va_end(ap);
+
+ return result;
+}
diff --git a/string.c b/string.c
index 51147f36ec..bbdafd0d25 100644
--- a/string.c
+++ b/string.c
@@ -444,22 +444,13 @@ rb_str_times(str, times)
*/
static VALUE
-rb_str_format(str, arg)
+rb_str_format_m(str, arg)
VALUE str, arg;
{
- VALUE *argv;
-
if (TYPE(arg) == T_ARRAY) {
- argv = ALLOCA_N(VALUE, RARRAY(arg)->len + 1);
- argv[0] = str;
- MEMCPY(argv+1, RARRAY(arg)->ptr, VALUE, RARRAY(arg)->len);
- return rb_f_sprintf(RARRAY(arg)->len+1, argv);
+ return rb_str_format(RARRAY(arg)->len, RARRAY(arg)->ptr, str);
}
-
- argv = ALLOCA_N(VALUE, 2);
- argv[0] = str;
- argv[1] = arg;
- return rb_f_sprintf(2, argv);
+ return rb_str_format(1, &arg, str);
}
static int
@@ -4669,7 +4660,7 @@ Init_String()
rb_define_method(rb_cString, "casecmp", rb_str_casecmp, 1);
rb_define_method(rb_cString, "+", rb_str_plus, 1);
rb_define_method(rb_cString, "*", rb_str_times, 1);
- rb_define_method(rb_cString, "%", rb_str_format, 1);
+ rb_define_method(rb_cString, "%", rb_str_format_m, 1);
rb_define_method(rb_cString, "[]", rb_str_aref_m, -1);
rb_define_method(rb_cString, "[]=", rb_str_aset_m, -1);
rb_define_method(rb_cString, "insert", rb_str_insert, 2);
diff --git a/struct.c b/struct.c
index 4468cbe0f3..f6d825a01e 100644
--- a/struct.c
+++ b/struct.c
@@ -476,19 +476,11 @@ inspect_struct(s, dummy, recur)
long i;
if (recur) {
- char *cname = rb_class2name(rb_obj_class(s));
- size_t len = strlen(cname) + 14;
- VALUE str = rb_str_new(0, len);
-
- snprintf(RSTRING(str)->ptr, len+1, "#<struct %s:...>", cname);
- RSTRING(str)->len = strlen(RSTRING(str)->ptr);
- return str;
+ return rb_sprintf("#<struct %s:...>", cname);
}
members = rb_struct_members(s);
- str = rb_str_buf_new2("#<struct ");
- rb_str_cat2(str, cname);
- rb_str_cat2(str, " ");
+ str = rb_sprintf("#<struct %s ", cname);
for (i=0; i<RSTRUCT(s)->len; i++) {
VALUE slot;
ID id;
diff --git a/variable.c b/variable.c
index 1139b016ca..bd5ea3c32d 100644
--- a/variable.c
+++ b/variable.c
@@ -196,7 +196,6 @@ rb_class_path(klass)
}
else {
char *s = "Class";
- size_t len;
if (TYPE(klass) == T_MODULE) {
if (rb_obj_class(klass) == rb_cModule) {
@@ -206,10 +205,7 @@ rb_class_path(klass)
s = rb_class2name(RBASIC(klass)->klass);
}
}
- len = 2 + strlen(s) + 3 + 2 * SIZEOF_LONG + 1;
- path = rb_str_new(0, len);
- snprintf(RSTRING(path)->ptr, len+1, "#<%s:0x%lx>", s, klass);
- RSTRING(path)->len = strlen(RSTRING(path)->ptr);
+ path = rb_sprintf("#<%s:0x%lx>", s, klass);
rb_ivar_set(klass, tmp_classpath, path);
return path;
diff --git a/win32/win32.c b/win32/win32.c
index 7345f3d2df..1839aeebb0 100644
--- a/win32/win32.c
+++ b/win32/win32.c
@@ -3602,9 +3602,7 @@ rb_w32_utime(const char *path, struct utimbuf *times)
int
rb_w32_vsnprintf(char *buf, size_t size, const char *format, va_list va)
{
- int ret = _vsnprintf(buf, size, format, va);
- if (size > 0) buf[size - 1] = 0;
- return ret;
+ return vsnprintf(buf, size, format, va);
}
int
diff --git a/win32/win32.h b/win32/win32.h
index a347f04f7a..68d9c488c2 100644
--- a/win32/win32.h
+++ b/win32/win32.h
@@ -178,10 +178,8 @@ extern int rb_w32_rename(const char *, const char *);
extern char **rb_w32_get_environ(void);
extern void rb_w32_free_environ(char **);
-#define vsnprintf(s,n,f,l) rb_w32_vsnprintf(s,n,f,l)
-#define snprintf rb_w32_snprintf
-extern int rb_w32_vsnprintf(char *, size_t, const char *, va_list);
-extern int rb_w32_snprintf(char *, size_t, const char *, ...);
+DEPRECATED(extern int rb_w32_vsnprintf(char *, size_t, const char *, va_list));
+DEPRECATED(extern int rb_w32_snprintf(char *, size_t, const char *, ...));
extern int chown(const char *, int, int);
extern int link(const char *, const char *);