diff --git a/libc/stdio/lib_snprintf.c b/libc/stdio/lib_snprintf.c index 76e9016eba..d1232e11a9 100644 --- a/libc/stdio/lib_snprintf.c +++ b/libc/stdio/lib_snprintf.c @@ -1,7 +1,7 @@ /**************************************************************************** * libc/stdio/lib_snprintf.c * - * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011, 2014 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -82,19 +82,41 @@ int snprintf(FAR char *buf, size_t size, const char *format, ...) { - struct lib_memoutstream_s memoutstream; + union + { + struct lib_outstream_s nulloutstream; + struct lib_memoutstream_s memoutstream; + } u; + + FAR struct lib_outstream_s *stream; va_list ap; - int n; + int n; - /* Initialize a memory stream to write to the buffer */ + /* "If the value of [size] is zero on a call to snprintf(), nothing shall + * be written, the number of bytes that would have been written had [size] + * been sufficiently large excluding the terminating null shall be returned, + * and [buf] may be a null pointer." -- opengroup.org + */ - lib_memoutstream((FAR struct lib_memoutstream_s *)&memoutstream, buf, size); + if (size > 0) + { + /* Initialize a memory stream to write to the buffer */ + + lib_memoutstream(&u.memoutstream, buf, size); + stream = &u.memoutstream.public; + } + else + { + /* Use a null stream to get the size of the buffer */ + + lib_nulloutstream(&u.nulloutstream); + stream = &u.nulloutstream; + } /* Then let lib_vsprintf do the real work */ va_start(ap, format); - n = lib_vsprintf((FAR struct lib_outstream_s *)&memoutstream.public, - format, ap); + n = lib_vsprintf(stream, format, ap); va_end(ap); return n; }