diff options
Diffstat (limited to 'libio/tst-memstream3.c')
-rw-r--r-- | libio/tst-memstream3.c | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/libio/tst-memstream3.c b/libio/tst-memstream3.c new file mode 100644 index 0000000000..38e5f7d150 --- /dev/null +++ b/libio/tst-memstream3.c @@ -0,0 +1,165 @@ +/* Test for open_memstream implementation. + Copyright (C) 2016 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <mcheck.h> +#include <stdio.h> +#include <stdarg.h> +#include <errno.h> + + +#ifndef CHAR_T +# define CHAR_T char +# define W(o) o +# define OPEN_MEMSTREAM open_memstream +# define PRINTF printf +# define FWRITE fwrite +# define FPUTC fputc +# define STRCMP strcmp +#endif + +#define S(s) S1 (s) +#define S1(s) #s + +static void +mcheck_abort (enum mcheck_status ev) +{ + printf ("mecheck failed with status %d\n", (int) ev); + exit (1); +} + +static void +error_printf (int line, const char *fmt, ...) +{ + va_list ap; + + printf ("error: %s:%i: ", __FILE__, line); + va_start (ap, fmt); + vprintf (fmt, ap); + va_end (ap); +} + +#define ERROR_RET1(...) \ + { error_printf(__LINE__, __VA_ARGS__); return 1; } + +static int +do_test_bz18241 (void) +{ + CHAR_T *buf; + size_t size; + + FILE *fp = OPEN_MEMSTREAM (&buf, &size); + if (fp == NULL) + ERROR_RET1 ("%s failed\n", S(OPEN_MEMSTREAM)); + + if (FPUTC (W('a'), fp) != W('a')) + ERROR_RET1 ("%s failed (errno = %d)\n", S(FPUTC), errno); + if (fflush (fp) != 0) + ERROR_RET1 ("fflush failed (errno = %d)\n", errno); + if (fseek (fp, -2, SEEK_SET) != -1) + ERROR_RET1 ("fseek failed (errno = %d)\n", errno); + if (errno != EINVAL) + ERROR_RET1 ("errno != EINVAL\n"); + if (ftell (fp) != 1) + ERROR_RET1 ("ftell failed (errno = %d)\n", errno); + if (ferror (fp) != 0) + ERROR_RET1 ("ferror != 0\n"); + + if (fseek (fp, -1, SEEK_CUR) == -1) + ERROR_RET1 ("fseek failed (errno = %d)\n", errno); + if (ftell (fp) != 0) + ERROR_RET1 ("ftell failed (errno = %d)\n", errno); + if (ferror (fp) != 0) + ERROR_RET1 ("ferror != 0\n"); + if (FPUTC (W('b'), fp) != W('b')) + ERROR_RET1 ("%s failed (errno = %d)\n", S(FPUTC), errno); + if (fflush (fp) != 0) + ERROR_RET1 ("fflush failed (errno = %d)\n", errno); + + if (fclose (fp) != 0) + ERROR_RET1 ("fclose failed (errno = %d\n", errno); + + if (STRCMP (buf, W("b")) != 0) + ERROR_RET1 ("%s failed\n", S(STRCMP)); + + free (buf); + + return 0; +} + +static int +do_test_bz20181 (void) +{ + CHAR_T *buf; + size_t size; + size_t ret; + + FILE *fp = OPEN_MEMSTREAM (&buf, &size); + if (fp == NULL) + ERROR_RET1 ("%s failed\n", S(OPEN_MEMSTREAM)); + + if ((ret = FWRITE (W("abc"), 1, 3, fp)) != 3) + ERROR_RET1 ("%s failed (errno = %d)\n", S(FWRITE), errno); + + if (fseek (fp, 0, SEEK_SET) != 0) + ERROR_RET1 ("fseek failed (errno = %d)\n", errno); + + if (FWRITE (W("z"), 1, 1, fp) != 1) + ERROR_RET1 ("%s failed (errno = %d)\n", S(FWRITE), errno); + + if (fflush (fp) != 0) + ERROR_RET1 ("fflush failed (errno = %d)\n", errno); + + /* Avoid truncating the buffer on close. */ + if (fseek (fp, 3, SEEK_SET) != 0) + ERROR_RET1 ("fseek failed (errno = %d)\n", errno); + + if (fclose (fp) != 0) + ERROR_RET1 ("fclose failed (errno = %d\n", errno); + + if (size != 3) + ERROR_RET1 ("size != 3\n"); + + if (buf[0] != W('z') + || buf[1] != W('b') + || buf[2] != W('c')) + { + PRINTF (W("error: buf {%c,%c,%c} != {z,b,c}\n"), + buf[0], buf[1], buf[2]); + return 1; + } + + free (buf); + + return 0; +} + +static int +do_test (void) +{ + int ret = 0; + + mcheck_pedantic (mcheck_abort); + + ret += do_test_bz18241 (); + ret += do_test_bz20181 (); + + return ret; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" |