-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Andrew Dunbar: > Hmm currently I'm using _vscprintf / vsprintf on Windows/MSVC inside > #ifdef _WIN32 > and vasprintf Ubuntu/gcc inside #else > But my C-fu is to puny to figure out what #ifdefs to use to detect > what combination of C compiler and libc I'm compiling under.
> Apparently it's important with snprintf since some implementations > return "an unspecified return value less than 1" with size=0. That's true, but no current Unix implementation should do that, since the return value of snprintf() is standardised in the current POSIX standard (IEEE 1003.1-2004) and in the C99 standard (ISO/IEC 9899:1999). The following code should handle Windows and both old and new Unix, although it's completely untested and comes with no warranty: /* Compile with "-D_XOPEN_SOURCE=600 -std=c99" */ int my_vasprintf(char **res, char const *fmt, va_list args) { int sz, r; #ifdef _WIN32 sz = _vscprintf(fmt, args); #else sz = snprintf(NULL, 0, fmt, args); #endif #if defined(_WIN32) || (defined(__STDC__) && __STDC__ >= 199901L) \ || (defined(_XOPEN_VERSION) && (_XOPEN_VERSION >= 600)) if (sz < 0) return sz; if (sz >= 0) { #else if (sz >= 1) { #endif if ((*res = malloc(sz + 1)) == NULL) return -1; if ((sz = sprintf(*res, fmt, args)) < 0) { free(*res); *res = NULL; } return sz; } #define MAXLN 65535 *res = NULL; for (sz = 128; sz <= MAXLN; sz *= 2) { if ((*res = realloc(*res, sz)) == NULL) return -1; r = vsnprintf(*res, sz, fmt, args); if (r > 0 && r < sz) return r; } errno = ENOMEM; if (*res) { free(*res); *res = NULL; } return -1; } Obviously, this will be slower than the modern implementation, and you may want to tune the initial buffer size for the expected string length. - river. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (SunOS) iEYEARECAAYFAk2i0QcACgkQIXd7fCuc5vI1ewCfTdlavg0rr56l7JzwAe5Oea9x 55sAnA4MIosJLfOnD/O3z/nkq0yqD5CE =AGMe -----END PGP SIGNATURE----- _______________________________________________ Toolserver-l mailing list (Toolserver-l@lists.wikimedia.org) https://lists.wikimedia.org/mailman/listinfo/toolserver-l Posting guidelines for this list: https://wiki.toolserver.org/view/Mailing_list_etiquette