summaryrefslogtreecommitdiff
path: root/tests/test-obstack-printf.c
blob: 646515bc6e1e168d2f31c6838d91919fb2957ff5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/* Test of obstack_printf() and obstack_vprintf() functions.
   Copyright (C) 2008-2021 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 <https://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 "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;
}