diff options
Diffstat (limited to 'tests/gnu/test-obstack-printf.c')
-rwxr-xr-x | tests/gnu/test-obstack-printf.c | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/tests/gnu/test-obstack-printf.c b/tests/gnu/test-obstack-printf.c new file mode 100755 index 00000000..6d2aceca --- /dev/null +++ b/tests/gnu/test-obstack-printf.c @@ -0,0 +1,138 @@ +/* Test of obstack_printf() and obstack_vprintf() functions. + Copyright (C) 2008-2010 Free Software Foundation, Inc. + + This program 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 3 of the License, or + (at your option) any later version. + + This program 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 this program. If not, see <http://www.gnu.org/licenses/>. */ + +/* Written by Eric Blake <ebb9@byu.net>, 2008. */ + +#include <config.h> + +#include <stdio.h> + +#include "signature.h" +SIGNATURE_CHECK (obstack_printf, int, (struct obstack *, char const *, ...)); +SIGNATURE_CHECK (obstack_vprintf, int, (struct obstack *, char const *, + va_list)); + +#include "obstack.h" +#include "xalloc.h" + +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> + +#include "progname.h" +#include "macros.h" + +#define obstack_chunk_alloc xmalloc +#define obstack_chunk_free free + +static void +test_function (int (*my_obstack_printf) (struct obstack *, const char *, ...)) +{ + struct obstack obs; + obstack_init (&obs); + /* In general, be careful that arguments to obstack_* don't have + side effects, as not all compilers evaluate macro arguments only + once. */ + + /* Grow the obstack to near its boundary, then check that short + output longer than the obstack free space grows the obstack. */ + { + char *base = obstack_base (&obs); + char *new_base; + int result; + int room = obstack_room (&obs) - 4; + + obstack_blank_fast (&obs, room); + result = my_obstack_printf (&obs, "%d %s", 123, "456"); + ASSERT (result == 7); + ASSERT (result + room == obstack_object_size (&obs)); + obstack_1grow (&obs, 0); + new_base = obstack_finish (&obs); + ASSERT (base != new_base); + ASSERT (strcmp (new_base + room, "123 456") == 0); + } + + /* Check that strings shorter than the obstack free space don't + cause a reshuffling of the obstack. */ + { + char *base = obstack_base (&obs); + char *new_base; + int result; + int room = obstack_room (&obs); + + ASSERT (8 < room); + result = my_obstack_printf (&obs, "%d %s", 123, "456"); + ASSERT (result == 7); + ASSERT (result == obstack_object_size (&obs)); + new_base = obstack_base (&obs); + ASSERT (base == new_base); + ASSERT (strncmp (base, "123 456", result) == 0); + obstack_finish (&obs); + } + + /* Check for generating much more output than a chunk size. */ + { + char *base = obstack_base (&obs); + char *new_base; + int result; + int i; + + ASSERT (obstack_chunk_size (&obs) < 10000); + result = my_obstack_printf (&obs, "%010000d", 0); + ASSERT (result == 10000); + ASSERT (result == obstack_object_size (&obs)); + new_base = obstack_base (&obs); + ASSERT (base != new_base); + for (i = 0; i < 10000; i++) + ASSERT (new_base[i] == '0'); + } + + obstack_free (&obs, NULL); +} + +static int +my_obstack_printf (struct obstack *obs, const char *format, ...) +{ + va_list args; + int ret; + + va_start (args, format); + ret = obstack_vprintf (obs, format, args); + va_end (args); + return ret; +} + +static void +test_obstack_vprintf () +{ + test_function (my_obstack_printf); +} + +static void +test_obstack_printf () +{ + test_function (obstack_printf); +} + +int +main (int argc, char *argv[]) +{ + set_program_name (argv[0]); + + test_obstack_vprintf (); + test_obstack_printf (); + return 0; +} |