Mercurial > ecos
changeset 2903:4fc5c84f2234
* cdl/stdio.cdl Added option CYGIMP_LIBC_STDIO_C99_SNPRINTF for activation
of C99 compliant snprintf() return value.
* src/output/vfnprintf.cxx: Added optional C99 compliant return value
calculation.
* tests/snprintf.c: New test for snprintf including C99 implementation.
| author | jld |
|---|---|
| date | Thu, 20 Aug 2009 16:09:18 +0000 |
| parents | c23173de14a8 |
| children | 88af52c64ce4 |
| files | packages/language/c/libc/stdio/current/ChangeLog packages/language/c/libc/stdio/current/cdl/stdio.cdl packages/language/c/libc/stdio/current/src/output/vfnprintf.cxx packages/language/c/libc/stdio/current/tests/snprintf.c |
| diffstat | 4 files changed, 172 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/packages/language/c/libc/stdio/current/ChangeLog +++ b/packages/language/c/libc/stdio/current/ChangeLog @@ -1,3 +1,12 @@ +2009-08-20 Uwe Kindler <uwe_kindler@web.de> + + * cdl/stdio.cdl Added option CYGIMP_LIBC_STDIO_C99_SNPRINTF + for activation of C99 compliant snprintf() return value. + * src/output/vfnprintf.cxx: Added optional C99 compliant return + value calculation. + * tests/snprintf.c: New test for snprintf including C99 + implementation. + 2009-08-07 Jonathan Larmour <jifl@eCosCentric.com> * src/common/vsnprintf.cxx (class Cyg_VsnprintfStream):
--- a/packages/language/c/libc/stdio/current/cdl/stdio.cdl +++ b/packages/language/c/libc/stdio/current/cdl/stdio.cdl @@ -8,7 +8,7 @@ ## ####ECOSGPLCOPYRIGHTBEGIN#### ## ------------------------------------------- ## This file is part of eCos, the Embedded Configurable Operating System. -## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. +## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2009 Free Software Foundation, Inc. ## ## eCos is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free @@ -378,6 +378,19 @@ cdl_package CYGPKG_LIBC_STDIO { the streams to be locked when accessed by multiple threads simultaneously." } + + cdl_option CYGIMP_LIBC_STDIO_C99_SNPRINTF { + display "C99 compliant snprintf() family" + default_value 0 + description " + This option allows C99 compliant implementation of + snprintf() family (i.e. snprintf(), vsnprintf()) + of functions. C99 compliant snprintf() functions + return the number of characters that would have been written + to a sufficiently sized buffer (excluding the '\\0'). + If this option is disabled, the functions simply return + the number of bytes that have been written to the buffer." + } # ==================================================================== @@ -435,7 +448,7 @@ cdl_package CYGPKG_LIBC_STDIO { flavor data no_define calculated { - "tests/sprintf1 tests/sprintf2 tests/sscanf tests/stdiooutput " + "tests/sprintf1 tests/sprintf2 tests/snprintf tests/sscanf tests/stdiooutput " . ((CYGPKG_IO_FILEIO && CYGPKG_FS_RAM) ? "tests/fileio " : "") } description "
--- a/packages/language/c/libc/stdio/current/src/output/vfnprintf.cxx +++ b/packages/language/c/libc/stdio/current/src/output/vfnprintf.cxx @@ -8,7 +8,7 @@ // ####ECOSGPLCOPYRIGHTBEGIN#### // ------------------------------------------- // This file is part of eCos, the Embedded Configurable Operating System. -// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2009 Free Software Foundation, Inc. // // eCos is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free @@ -206,6 +206,17 @@ vfnprintf ( FILE *stream, size_t n, cons /* * BEWARE, these `goto error' on error, and PAD uses `n'. */ +#ifdef CYGIMP_LIBC_STDIO_C99_SNPRINTF +#define PRINT(ptr, len) \ +CYG_MACRO_START \ + if ((size_t)(ret + 1) < n) { \ + cyg_ucount32 length = MIN( (cyg_ucount32) len, n - ret - 1); \ + if (((Cyg_OutputStream *)stream)->write( (const cyg_uint8 *)ptr, \ + length, &length )) \ + goto error; \ + } \ +CYG_MACRO_END +#else #define PRINT(ptr, len) \ CYG_MACRO_START \ cyg_ucount32 length = MIN( (cyg_ucount32) len, n - ret - 1); \ @@ -217,7 +228,7 @@ CYG_MACRO_START goto done; \ } \ CYG_MACRO_END - +#endif // CYGIMP_LIBC_STDIO_C99_SNPRINTF #define PAD(howmany, with) \ CYG_MACRO_START \ @@ -276,7 +287,11 @@ CYG_MACRO_END PRINT(cp, y); ret += y; } +#ifdef CYGIMP_LIBC_STDIO_C99_SNPRINTF + if (x <= 0) +#else if ((x <= 0) || (ret >= (int)n)) // @@@ this check with n isn't good enough +#endif goto done; fmt++; /* skip over '%' */
new file mode 100644 --- /dev/null +++ b/packages/language/c/libc/stdio/current/tests/snprintf.c @@ -0,0 +1,131 @@ +//================================================================= +// +// snprintf.c +// +// Testcase for C library snprintf() implementation +// +//================================================================= +// ####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2009 Free Software Foundation, Inc. +// +// eCos is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 or (at your option) any later +// version. +// +// eCos is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License +// along with eCos; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// As a special exception, if other files instantiate templates or use +// macros or inline functions from this file, or you compile this file +// and link it with other works to produce a work based on this file, +// this file does not by itself cause the resulting work to be covered by +// the GNU General Public License. However the source code for this file +// must still be made available in accordance with section (3) of the GNU +// General Public License v2. +// +// This exception does not invalidate any other reasons why a work based +// on this file might be covered by the GNU General Public License. +// ------------------------------------------- +// ####ECOSGPLCOPYRIGHTEND#### +//================================================================= +//#####DESCRIPTIONBEGIN#### +// +// Author(s): Uwe Kindler +// Contributors: +// Date: 2009-08-05 +// Description: Contains testcode for C library snprintf() function +// +// +//####DESCRIPTIONEND#### + +// CONFIGURATION + +#include <pkgconf/libc_stdio.h> // Configuration header + +// INCLUDES + +#include <stdio.h> +#include <cyg/infra/testcase.h> + +static int my_strnlen(const char *s, size_t maxlen) +{ + const char *ptr; + const char *endptr; + + ptr = s; + endptr = s + maxlen; + while ((*ptr != '\0') && (ptr != endptr)) + { + ptr++; + } + + return (int)(ptr-s); +} // my_strlen() + +static void +test( CYG_ADDRWORD data ) +{ + static char x[32]; + static char y[4]; + int xret; + int yret; + int xstrlen; + int ystrlen; + + // fill buffer to ensure that there are no zeros in the buffers + memset(x, 0xFF, sizeof(x)); + memset(y, 0xFF, sizeof(y)); + + // print into a buffer with sufficient size + xret = snprintf(x, sizeof(x), "%d:%d:%d:%d", 1, 2, 3, 4); + xstrlen = my_strnlen(x, sizeof(x)); + + // print into a buffer that is too small + yret = snprintf(y, sizeof(y), "%d:%d:%d:%d", 1, 2, 3, 4); + ystrlen = my_strnlen(y, sizeof(y)); + + CYG_TEST_PASS_FAIL(xret == xstrlen, "[buffer > strlen] return code"); + +#ifdef CYGIMP_LIBC_STDIO_C99_SNPRINTF + // C99 compliant implementation returns the number of characters that + // would have been written had size been sufficiently large, + // not counting the terminating nul character + CYG_TEST_PASS_FAIL(xret == yret, "[buffer < strlen] return code"); + CYG_TEST_INFO("C99 compliant implementation of snprintf()"); +#else + // default eCos implementation returns number of bytes written into + // the buffer without terminating nul character + CYG_TEST_PASS_FAIL(yret == ystrlen, "[buffer < strlen] return code"); + CYG_TEST_INFO("Default implementation of snprintf() (no C99 compliance)"); +#endif + + + CYG_TEST_FINISH("Finished tests from testcase " __FILE__ + " for C library snprintf() function return values"); + +} // test() + +int +main(int argc, char *argv[]) +{ + CYG_TEST_INIT(); + + CYG_TEST_INFO("Starting tests from testcase " __FILE__ " for C " + "library snprintf() function return values"); + CYG_TEST_INFO("These test return values of snprinf() family of functions"); + + test(0); + + return 0; +} // main() + +// EOF snprintf.c
