/* Test of obstack_printf() and obstack_vprintf() functions. Copyright (C) 2008-2023 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 . */ /* Written by Eric Blake , 2008. */ #include #include #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 #include #include #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[]) { test_obstack_vprintf (); test_obstack_printf (); return 0; }