diff --git a/ChangeLog b/ChangeLog index dcb34e573d..44ada6165f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +Mon Dec 22 12:05:14 2008 Nobuyoshi Nakada + + * configure.in (mingw): no longer uses snprintf and vsnprintf of + msvcrt. + + * win32/win32.c (rb_w32_vsnprintf, rb_w32_snprintf): removed. + + * win32/Makefile.sub (config.h): vsnprintf exists in VC7 or later. + + * win32/mkexports.rb (Exports#initialize): aliases + rb_w32_vsnprintf and rb_w32_snprintf for binary compatibility. + + * sprintf.c (rb_str_format): uses snprintf instead of sprintf. + + * numeric.c (flo_to_s, rb_num2long, rb_num2ll): ditto. + Mon Dec 22 10:59:31 2008 Yukihiro Matsumoto * string.c (rb_str_upto): should return enumerator if called diff --git a/configure.in b/configure.in index 37a069455a..5b75f7364c 100644 --- a/configure.in +++ b/configure.in @@ -580,8 +580,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_snprintf=yes - ac_cv_func_vsnprintf=yes ac_cv_func_seekdir=yes ac_cv_func_telldir=yes ac_cv_func_isinf=yes diff --git a/include/ruby/missing.h b/include/ruby/missing.h index 16d5a6f02b..ea40f62a52 100644 --- a/include/ruby/missing.h +++ b/include/ruby/missing.h @@ -144,9 +144,13 @@ RUBY_EXTERN long strtol(const char *, char **, int); #endif */ -#ifndef HAVE_VSNPRINTF +#if defined HAVE_VSNPRINTF || defined HAVE_SNPRINTF # include +#endif +#ifndef HAVE_SNPRINTF RUBY_EXTERN int snprintf(char *, size_t n, char const *, ...); +#endif +#ifndef HAVE_VSNPRINTF RUBY_EXTERN int vsnprintf(char *, size_t n, char const *, va_list); #endif diff --git a/include/ruby/win32.h b/include/ruby/win32.h index bd4d66493b..582348d338 100644 --- a/include/ruby/win32.h +++ b/include/ruby/win32.h @@ -243,11 +243,6 @@ extern char **rb_w32_get_environ(void); extern void rb_w32_free_environ(char **); extern int rb_w32_map_errno(DWORD); -#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 *, ...); - extern int chown(const char *, int, int); extern int link(const char *, const char *); extern int gettimeofday(struct timeval *, struct timezone *); diff --git a/numeric.c b/numeric.c index 29497b0648..c2c8730872 100644 --- a/numeric.c +++ b/numeric.c @@ -530,12 +530,12 @@ flo_to_s(VALUE flt) else if(isnan(value)) return rb_usascii_str_new2("NaN"); - sprintf(buf, "%#.15g", value); /* ensure to print decimal point */ + snprintf(buf, sizeof(buf), "%#.15g", value); /* ensure to print decimal point */ if (!(e = strchr(buf, 'e'))) { e = buf + strlen(buf); } if (!ISDIGIT(e[-1])) { /* reformat if ended with decimal point (ex 111111111111111.) */ - sprintf(buf, "%#.14e", value); + snprintf(buf, sizeof(buf), "%#.14e", value); if (!(e = strchr(buf, 'e'))) { e = buf + strlen(buf); } @@ -1554,7 +1554,7 @@ rb_num2long(VALUE val) char buf[24]; char *s; - sprintf(buf, "%-.10g", RFLOAT_VALUE(val)); + snprintf(buf, sizeof(buf), "%-.10g", RFLOAT_VALUE(val)); if ((s = strchr(buf, ' ')) != 0) *s = '\0'; rb_raise(rb_eRangeError, "float %s out of range of integer", buf); } @@ -1700,7 +1700,7 @@ rb_num2ll(VALUE val) char buf[24]; char *s; - sprintf(buf, "%-.10g", RFLOAT_VALUE(val)); + snprintf(buf, sizeof(buf), "%-.10g", RFLOAT_VALUE(val)); if ((s = strchr(buf, ' ')) != 0) *s = '\0'; rb_raise(rb_eRangeError, "float %s out of range of long long", buf); } diff --git a/sprintf.c b/sprintf.c index 23671e6b93..1195f9b17b 100644 --- a/sprintf.c +++ b/sprintf.c @@ -25,7 +25,7 @@ #define BITSPERDIG (SIZEOF_BDIGITS*CHAR_BIT) #define EXTENDSIGN(n, l) (((~0 << (n)) >> (((n)*(l)) % BITSPERDIG)) & ~(~0 << (n))) -static void fmt_setup(char*,int,int,int,int); +static void fmt_setup(char*,size_t,int,int,int,int); static char* remove_sign_bits(char *str, int base) @@ -800,8 +800,8 @@ rb_str_format(int argc, const VALUE *argv, VALUE fmt) sc = ' '; width--; } - sprintf(fbuf, "%%l%c", c); - sprintf(nbuf, fbuf, v); + snprintf(fbuf, sizeof(fbuf), "%%l%c", c); + snprintf(nbuf, sizeof(nbuf), fbuf, v); s = nbuf; } else { @@ -809,8 +809,8 @@ rb_str_format(int argc, const VALUE *argv, VALUE fmt) if (v < 0) { dots = 1; } - sprintf(fbuf, "%%l%c", *p == 'X' ? 'x' : *p); - sprintf(++s, fbuf, v); + snprintf(fbuf, sizeof(fbuf), "%%l%c", *p == 'X' ? 'x' : *p); + snprintf(++s, sizeof(nbuf) - 1, fbuf, v); if (v < 0) { char d = 0; @@ -980,7 +980,7 @@ rb_str_format(int argc, const VALUE *argv, VALUE fmt) need = width; CHECK(need); - sprintf(&buf[blen], "%*s", need, ""); + snprintf(&buf[blen], need, "%*s", need, ""); if (flags & FMINUS) { if (!isnan(fval) && fval < 0.0) buf[blen++] = '-'; @@ -1004,7 +1004,7 @@ rb_str_format(int argc, const VALUE *argv, VALUE fmt) break; } - fmt_setup(fbuf, *p, flags, width, prec); + fmt_setup(fbuf, sizeof(fbuf), *p, flags, width, prec); need = 0; if (*p != 'e' && *p != 'E') { i = INT_MIN; @@ -1018,7 +1018,7 @@ rb_str_format(int argc, const VALUE *argv, VALUE fmt) need += 20; CHECK(need); - sprintf(&buf[blen], fbuf, fval); + snprintf(&buf[blen], need, fbuf, fval); blen += strlen(&buf[blen]); } break; @@ -1041,8 +1041,9 @@ rb_str_format(int argc, const VALUE *argv, VALUE fmt) } static void -fmt_setup(char *buf, int c, int flags, int width, int prec) +fmt_setup(char *buf, size_t size, int c, int flags, int width, int prec) { + char *end = buf + size; *buf++ = '%'; if (flags & FSHARP) *buf++ = '#'; if (flags & FPLUS) *buf++ = '+'; @@ -1051,12 +1052,12 @@ fmt_setup(char *buf, int c, int flags, int width, int prec) if (flags & FSPACE) *buf++ = ' '; if (flags & FWIDTH) { - sprintf(buf, "%d", width); + snprintf(buf, end - buf, "%d", width); buf += strlen(buf); } if (flags & FPREC) { - sprintf(buf, ".%d", prec); + snprintf(buf, end - buf, ".%d", prec); buf += strlen(buf); } @@ -1084,7 +1085,15 @@ fmt_setup(char *buf, int c, int flags, int width, int prec) #undef snprintf #define FLOATING_POINT 1 #define BSD__dtoa ruby_dtoa +#undef HAVE_VSNPRINTF +#undef HAVE_SNPRINTF +#if _MSC_VER >= 1300 +#pragma warning(disable: 4273) +#endif #include "missing/vsnprintf.c" +#if _MSC_VER >= 1300 +#pragma warning(default: 4273) +#endif static int ruby__sfvwrite(register rb_printf_buffer *fp, register struct __suio *uio) diff --git a/win32/Makefile.sub b/win32/Makefile.sub index 57864b46d2..96dbfebc8e 100644 --- a/win32/Makefile.sub +++ b/win32/Makefile.sub @@ -423,7 +423,9 @@ $(CONFIG_H): $(MKFILES) $(srcdir)/win32/Makefile.sub $(win_srcdir)/Makefile.sub #define HAVE_STRTOUL 1 #define HAVE_FLOCK 1 #define HAVE_SNPRINTF 1 +!if $(MSC_VER) >= 1300 #define HAVE_VSNPRINTF 1 +!endif #define HAVE_ISNAN 1 #define HAVE_FINITE 1 #define HAVE_HYPOT 1 diff --git a/win32/mkexports.rb b/win32/mkexports.rb index 2ed251ec1c..adf0c5e336 100755 --- a/win32/mkexports.rb +++ b/win32/mkexports.rb @@ -51,6 +51,8 @@ class Exports end end syms["NtInitialize"] ||= "ruby_sysinit" if syms["ruby_sysinit"] + syms["rb_w32_vsnprintf"] ||= "vsnprintf" + syms["rb_w32_snprintf"] ||= "snprintf" @syms = syms end diff --git a/win32/win32.c b/win32/win32.c index 6cffc21ade..9697c8ec60 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -4552,26 +4552,6 @@ rb_w32_utime(const char *path, const struct utimbuf *times) return ret; } -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; -} - -int -rb_w32_snprintf(char *buf, size_t size, const char *format, ...) -{ - int ret; - va_list va; - - va_start(va, format); - ret = vsnprintf(buf, size, format, va); - va_end(va); - return ret; -} - int rb_w32_mkdir(const char *path, int mode) {