diff options
| author | cremno <[email protected]> | 2014-08-03 21:15:48 +0200 |
|---|---|---|
| committer | cremno <[email protected]> | 2014-08-03 21:15:48 +0200 |
| commit | b6e27218ad1ffdba6d2103b85d5d9231b6380008 (patch) | |
| tree | 6b84ad30e85f50fa4eab6c7373306e741d194508 /src/etc.c | |
| parent | 206f89e2090524f009fc5a87f42c15a453ebdbee (diff) | |
| download | mruby-b6e27218ad1ffdba6d2103b85d5d9231b6380008.tar.gz mruby-b6e27218ad1ffdba6d2103b85d5d9231b6380008.zip | |
MSVC: add simple (v)snprintf implementation
_snprintf is not C99's snprintf!
This simple implementation, unlike _snprintf,
always null-terminates and returns the expected
return value (in most cases).
Other C99 behaviors (like format specifiers) require
adding a complete snprintf implementation.
Do we want or need that?
The same applies to vsnprintf (aka _vsnprintf).
Diffstat (limited to 'src/etc.c')
| -rw-r--r-- | src/etc.c | 37 |
1 files changed, 37 insertions, 0 deletions
@@ -183,3 +183,40 @@ mrb_regexp_p(mrb_state *mrb, mrb_value v) { return mrb_class_defined(mrb, REGEXP_CLASS) && mrb_obj_is_kind_of(mrb, v, mrb_class_get(mrb, REGEXP_CLASS)); } + +#if defined _MSC_VER && _MSC_VER < 1900 + +#ifndef va_copy +static void +mrb_msvc_va_copy(va_list *dest, va_list src) +{ + *dest = src; +} +#define va_copy(dest, src) msvc_va_copy(&(dest), src) +#endif + +MRB_API int +mrb_msvc_vsnprintf(char *s, size_t n, const char *format, va_list arg) +{ + int cnt; + va_list argcp; + va_copy(argcp, arg); + if (n == 0 || (cnt = _vsnprintf_s(s, n, _TRUNCATE, format, argcp)) < 0) { + cnt = _vscprintf(format, arg); + } + va_end(argcp); + return cnt; +} + +MRB_API int +mrb_msvc_snprintf(char *s, size_t n, const char *format, ...) +{ + va_list arg; + int ret; + va_start(arg, format); + ret = mrb_msvc_vsnprintf(s, n, format, arg); + va_end(arg); + return ret; +} + +#endif /* defined _MSC_VER && _MSC_VER < 1900 */ |
