torture_su_alloc.c 17.7 KB
Newer Older
Pekka Pessi's avatar
Pekka Pessi committed
1 2 3
/*
 * This file is part of the Sofia-SIP package
 *
4
 * Copyright (C) 2006 Nokia Corporation.
Pekka Pessi's avatar
Pekka Pessi committed
5 6 7
 *
 * Contact: Pekka Pessi <pekka.pessi@nokia.com>
 *
8
 * This library is free software; you can redistribute it and/or
Pekka Pessi's avatar
Pekka Pessi committed
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
 * 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.
 *
 * This 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 this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 *
 */

Pekka Pessi's avatar
Pekka Pessi committed
25
/**@internal 
Pekka Pessi's avatar
Pekka Pessi committed
26 27 28 29 30
 * @file su_alloc_test.c
 *
 * Testing functions for su_alloc functions.
 *
 * @author Pekka Pessi <Pekka.Pessi@nokia.com>
31
 *
Pekka Pessi's avatar
Pekka Pessi committed
32 33 34 35 36 37 38
 * @date Created: Thu May  2 18:17:46 2002 ppessi
 */

#include "config.h"

#include <stdio.h>
#include <string.h>
39
#include <stdlib.h>
Pekka Pessi's avatar
Pekka Pessi committed
40

41 42 43
#include <sofia-sip/su_alloc.h>
#include <sofia-sip/su_strlst.h>
#include <sofia-sip/su_alloc_stat.h>
Pekka Pessi's avatar
Pekka Pessi committed
44 45

#define TSTFLAGS tstflags
46
#include <sofia-sip/tstdef.h>
Pekka Pessi's avatar
Pekka Pessi committed
47 48 49 50 51

int tstflags;

char const *name = "su_alloc_test";

52 53 54 55 56 57 58 59 60
/* Type derived from home */
typedef struct { su_home_t home[1]; int *p; } exhome_t;

void exdestructor(void *arg)
{
  exhome_t *ex = arg;
  (*ex->p)++;
}

Michael Jerris's avatar
Michael Jerris committed
61 62 63 64 65 66
void test_destructor(void *a)
{
  su_home_t *h = a;
  h->suh_size = 13;
}

67
/** Test basic memory home operations  */
68
static int test_alloc(void)
Pekka Pessi's avatar
Pekka Pessi committed
69
{
70
  exhome_t *h0, *h1, *h2, *h3;
Pekka Pessi's avatar
Pekka Pessi committed
71 72 73 74 75
  su_home_t home[1] = { SU_HOME_INIT(home) };
  enum { N = 40 };
  void *m0[N], *m1[N], *m;
  char *c, *c0, *p0, *p1;
  int i;
76
  enum { destructed_once = 1 };
77
  int d0, d1a, d1, d2, d3;
Pekka Pessi's avatar
Pekka Pessi committed
78 79 80

  BEGIN();

81
  TEST_1(h0 = su_home_new(sizeof(*h0)));
82 83
  TEST_1(h1 = su_home_clone(h0->home, sizeof(*h1)));

84 85
  d0 = d1a = d1 = d2 = d3 = 0;
  h0->p = &d0; h1->p = &d1a;
86 87
  TEST(su_home_destructor(h0->home, exdestructor), 0);
  TEST(su_home_destructor(h1->home, exdestructor), 0);
88 89 90 91

  TEST_1(h2 = su_home_ref(h0->home));
  su_home_unref(h0->home);
  TEST(d0, 0);
92 93 94 95

  for (i = 0; i < 128; i++)
    TEST_1(su_alloc(h0->home, 16));

96 97 98 99 100 101 102
  for (i = 0; i < 128; i++)
    TEST_1(su_alloc(h1->home, 16));

  su_home_unref(h1->home);
  TEST(d1a, destructed_once);

  TEST_1(h1 = su_home_clone(h0->home, sizeof(*h1)));
103
  TEST(su_home_destructor(h1->home, exdestructor), 0);
104 105
  h1->p = &d1;

106 107 108 109 110 111
  for (i = 0; i < 128; i++)
    TEST_1(su_alloc(h1->home, 16));

  for (i = 0; i < 128; i++)
    TEST_1(su_alloc(h2->home, 16));

112 113
  su_home_unref(h2->home); /* Should call destructor of cloned home, too */

114 115
  TEST(d0, destructed_once);
  TEST(d1, destructed_once);
116 117

  TEST_1(h0 = su_home_new(sizeof(*h0)));
118 119 120
  TEST_1(h1 = su_home_clone(h0->home, sizeof(*h1)));
  TEST_1(h2 = su_home_clone(h1->home, sizeof(*h2)));
  TEST_1(h3 = su_home_clone(h2->home, sizeof(*h3)));
Pekka Pessi's avatar
Pekka Pessi committed
121

122
  TEST(su_home_threadsafe(h0->home), 0);
Pekka Pessi's avatar
Pekka Pessi committed
123 124

  for (i = 0; i < N; i++) {
125 126
    TEST_1(m0[i] = su_zalloc(h3->home, 20));
    TEST_1(m1[i] = su_zalloc(h2->home, 20));
Pekka Pessi's avatar
Pekka Pessi committed
127 128
  }

129
  TEST_1(m = su_zalloc(h2->home, 20));
Pekka Pessi's avatar
Pekka Pessi committed
130

131 132
  TEST_1(su_in_home(h2->home, m));
  TEST_1(!su_in_home(h2->home, (char *)m + 1));
133
  TEST_1(!su_in_home(h2->home, (void *)(intptr_t)su_in_home));
134 135 136 137
  TEST_1(!su_in_home(h3->home, m));
  TEST_1(!su_in_home(NULL, m));
  TEST_1(!su_in_home(h3->home, NULL));

Pekka Pessi's avatar
Pekka Pessi committed
138 139
  TEST(su_home_move(home, NULL), 0);
  TEST(su_home_move(NULL, home), 0);
140 141 142
  TEST(su_home_move(home, h3->home), 0);
  TEST(su_home_move(h2->home, h3->home), 0);
  TEST(su_home_move(h1->home, h2->home), 0);
Pekka Pessi's avatar
Pekka Pessi committed
143 144 145 146

  su_home_preload(home, 1, 1024 + 2 * 8);

  TEST_1(c = su_zalloc(home, 64)); p0 = c; p1 = c + 1024;
147
  TEST_P(c = su_realloc(home, c0 = c, 127), c0);
Pekka Pessi's avatar
Pekka Pessi committed
148

149
  TEST_1(c = c0 = su_zalloc(home, 1024 - 128));
Pekka Pessi's avatar
Pekka Pessi committed
150
  TEST_1(p0 <= c); TEST_1(c < p1);
151 152 153
  TEST_P(c = su_realloc(home, c, 128), c0);
  TEST_P(c = su_realloc(home, c, 1023 - 128), c0);
  TEST_P(c = su_realloc(home, c, 1024 - 128), c0);
Pekka Pessi's avatar
Pekka Pessi committed
154 155 156
  TEST_1(c = su_realloc(home, c, 1024));
  TEST_1(c = su_realloc(home, c, 2 * 1024));

157
  TEST_P(c = su_realloc(home, p0, 126), p0);
Pekka Pessi's avatar
Pekka Pessi committed
158
  TEST_1(c = su_realloc(home, p0, 1024));
159
  TEST_P(c = su_realloc(home, c, 0), NULL);
Pekka Pessi's avatar
Pekka Pessi committed
160 161

  su_home_check(home);
162
  su_home_deinit(home);
Pekka Pessi's avatar
Pekka Pessi committed
163

164 165 166 167
  su_home_check(h2->home);
  su_home_zap(h2->home);
  su_home_check(h0->home);
  su_home_zap(h0->home);
Pekka Pessi's avatar
Pekka Pessi committed
168

169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
  {
    su_home_t h1[1];

    memset(h1, 0, sizeof h1);

    TEST(su_home_init(h1), 0);
    TEST(su_home_threadsafe(h1), 0);

    TEST_1(su_home_ref(h1));
    TEST_1(su_home_ref(h1));

    TEST(su_home_destructor(h1, test_destructor), 0);

    TEST_1(!su_home_unref(h1));
    TEST_1(!su_home_unref(h1));
    TEST_1(su_home_unref(h1));
    TEST(h1->suh_size, 13);
  }

Pekka Pessi's avatar
Pekka Pessi committed
188 189 190 191 192 193 194 195 196 197 198 199 200
  END();
}

static int test_strdupcat(void)
{
  su_home_t home[1] = { SU_HOME_INIT(home) };

  BEGIN();

  TEST_S(su_strdup(home, "foo"), "foo");
  TEST_S(su_strcat(home, "foo", "bar"), "foobar");
  TEST_S(su_strndup(home, "foobar", 3), "foo");

201 202 203
  TEST_S(su_strcat_all(home, NULL), "");
  TEST_S(su_strcat_all(home, "a", "", "b", "", NULL), "ab");

Pekka Pessi's avatar
Pekka Pessi committed
204
  su_home_deinit(home);
205

Pekka Pessi's avatar
Pekka Pessi committed
206 207 208
  END();
}

209 210 211 212 213 214 215 216 217 218 219 220 221 222
#include <stdarg.h>

static int test_sprintf(char const *fmt, ...)
{
  BEGIN();

  su_home_t home[1] = { SU_HOME_INIT(home) };
  va_list va;

  TEST_S(su_sprintf(home, "foo%s", "bar"), "foobar");

  va_start(va, fmt);
  TEST_S(su_vsprintf(home, fmt, va), "foo.bar");

223
  TEST_S(su_sprintf(home, "foo%200s", "bar"),
224 225 226 227 228 229
	 "foo                                                             "
	 "                                                                "
	 "                                                                "
	 "        bar");

  su_home_deinit(home);
230

231 232 233
  END();
}

Pekka Pessi's avatar
Pekka Pessi committed
234 235 236 237 238 239 240 241 242
static int test_strlst(void)
{
  su_home_t home[1] = { SU_HOME_INIT(home) };
  su_strlst_t *l, *l1, *l2;
  char *s;
  char foo[] = "foo";
  char bar[] = "bar";
  char baz[] = "baz";

243 244
  su_home_stat_t parent[1], kids[2];

Pekka Pessi's avatar
Pekka Pessi committed
245 246
  BEGIN();

247 248 249
  parent->hs_size = (sizeof parent);
  kids[0].hs_size = (sizeof kids[0]);
  kids[1].hs_size = (sizeof kids[1]);
250

251 252
  su_home_init_stats(home);

Pekka Pessi's avatar
Pekka Pessi committed
253 254 255 256 257 258 259 260 261 262
  /* Test API for invalid arguments */
  TEST_1(l = su_strlst_create(NULL));
  TEST_1(l2 = su_strlst_dup(home, l));
  TEST_VOID(su_strlst_destroy(l2));
  TEST_1(!su_strlst_dup(home, NULL));
  TEST_1(l1 = su_strlst_copy(home, l));
  TEST_VOID(su_strlst_destroy(l1));
  TEST_1(!su_strlst_copy(home, NULL));

  TEST_VOID(su_strlst_destroy(NULL));
263
  TEST_VOID(su_strlst_destroy(l));
Pekka Pessi's avatar
Pekka Pessi committed
264 265 266 267 268 269 270 271 272 273 274 275 276 277 278

  TEST_1(!su_strlst_dup_append(NULL, "aa"));
  TEST_1(!su_strlst_append(NULL, "bee"));
  TEST_1(!su_strlst_item(NULL, 1));
  TEST_1(!su_strlst_set_item(NULL, 1, "cee"));
  TEST_1(!su_strlst_remove(NULL, 1));
  TEST_S(s = su_strlst_join(NULL, home, "a"), "");
  TEST_VOID(su_free(home, s));

  TEST_1(!su_strlst_split(home, NULL, "."));

  TEST_1(s = su_strdup(home, "aaa"));
  TEST_1(l = su_strlst_split(home, s, NULL));
  TEST_S(su_strlst_item(l, 0), "aaa");
  TEST_VOID(su_strlst_destroy(l));
279

Pekka Pessi's avatar
Pekka Pessi committed
280 281 282 283 284 285 286 287
  TEST_VOID(su_free(home, s));

  TEST_1(!su_strlst_dup_split(home, NULL, "."));

  TEST_1(l1 = su_strlst_dup_split(home, "aaa", ""));
  TEST_S(su_strlst_item(l1, 0), "aaa");
  TEST_VOID(su_strlst_destroy(l1));

288
  TEST_SIZE(su_strlst_len(NULL), 0);
Pekka Pessi's avatar
Pekka Pessi committed
289 290
  TEST_1(!su_strlst_get_array(NULL));
  TEST_VOID(su_strlst_free_array(NULL, NULL));
291

Pekka Pessi's avatar
Pekka Pessi committed
292 293 294 295 296 297 298 299
  TEST_1(l = su_strlst_create(home));
  TEST_VOID(su_strlst_free_array(l, NULL));
  TEST_S(su_strlst_dup_append(l, "oh"), "oh");
  TEST_VOID(su_strlst_free_array(l, NULL));
  TEST_VOID(su_strlst_destroy(l));

  /* Test functionality */
  TEST_1(l = su_strlst_create(home));
300 301

  su_home_init_stats(su_strlst_home(l));
302 303

  TEST_S(su_strlst_join(l, home, "bar"), "");
Pekka Pessi's avatar
Pekka Pessi committed
304 305 306
  TEST_S(su_strlst_append(l, foo), "foo");
  TEST_S(su_strlst_dup_append(l, bar), "bar");
  TEST_S(su_strlst_append(l, baz), "baz");
307
  TEST_S((s = su_strlst_join(l, home, "!")), "foo!bar!baz");
Pekka Pessi's avatar
Pekka Pessi committed
308 309 310 311

  TEST_S(su_strlst_item(l, 0), foo);
  TEST_S(su_strlst_item(l, 1), bar);
  TEST_S(su_strlst_item(l, 2), baz);
312 313
  TEST_P(su_strlst_item(l, 3), NULL);
  TEST_P(su_strlst_item(l, (unsigned)-1), NULL);
Pekka Pessi's avatar
Pekka Pessi committed
314 315 316

  TEST_1(l1 = su_strlst_copy(su_strlst_home(l), l));
  TEST_1(l2 = su_strlst_dup(su_strlst_home(l), l));
317

Pekka Pessi's avatar
Pekka Pessi committed
318
  strcpy(foo, "hum"); strcpy(bar, "pah"); strcpy(baz, "hah");
319

320 321
  TEST_S(su_strlst_dup_append(l1, "kuik"), "kuik");
  TEST_S(su_strlst_dup_append(l2, "uik"), "uik");
322 323 324 325

  TEST_S((s = su_strlst_join(l, home, ".")), "hum.bar.hah");
  TEST_S((su_strlst_join(l1, home, ".")), "hum.bar.hah.kuik");
  TEST_S((su_strlst_join(l2, home, ".")), "foo.bar.baz.uik");
326 327 328 329 330

  su_strlst_destroy(l2);

  su_home_get_stats(su_strlst_home(l), 0, kids, sizeof kids);

331 332 333
  TEST_SIZE(kids->hs_clones, 2);
  TEST64(kids->hs_allocs.hsa_number, 3);
  TEST64(kids->hs_frees.hsf_number, 1);
Pekka Pessi's avatar
Pekka Pessi committed
334 335 336 337 338 339

  su_strlst_destroy(l);

  TEST_S(s, "hum.bar.hah");

  TEST_1(l = su_strlst_create(home));
340 341 342

  su_home_init_stats(su_strlst_home(l));

Pekka Pessi's avatar
Pekka Pessi committed
343 344 345 346 347 348 349 350 351 352 353 354
  TEST_S(su_strlst_join(l, home, "bar"), "");
  TEST_S(su_strlst_append(l, "a"), "a");
  TEST_S(su_strlst_append(l, "b"), "b");
  TEST_S(su_strlst_append(l, "c"), "c");
  TEST_S(su_strlst_append(l, "d"), "d");
  TEST_S(su_strlst_append(l, "e"), "e");
  TEST_S(su_strlst_append(l, "f"), "f");
  TEST_S(su_strlst_append(l, "g"), "g");
  TEST_S(su_strlst_append(l, "h"), "h");
  TEST_S(su_strlst_append(l, "i"), "i");
  TEST_S(su_strlst_append(l, "j"), "j");

355
  TEST_S((s = su_strlst_join(l, home, "")), "abcdefghij");
Pekka Pessi's avatar
Pekka Pessi committed
356 357 358 359 360 361 362 363 364 365 366
  TEST_S(su_strlst_append(l, "a"), "a");
  TEST_S(su_strlst_append(l, "b"), "b");
  TEST_S(su_strlst_append(l, "c"), "c");
  TEST_S(su_strlst_append(l, "d"), "d");
  TEST_S(su_strlst_append(l, "e"), "e");
  TEST_S(su_strlst_append(l, "f"), "f");
  TEST_S(su_strlst_append(l, "g"), "g");
  TEST_S(su_strlst_append(l, "h"), "h");
  TEST_S(su_strlst_append(l, "i"), "i");
  TEST_S(su_strlst_append(l, "j"), "j");

367
  TEST_S((s = su_strlst_join(l, home, "")), "abcdefghijabcdefghij");
Pekka Pessi's avatar
Pekka Pessi committed
368

369 370 371
  su_home_get_stats(su_strlst_home(l), 0, kids + 1, (sizeof kids[1]));
  su_home_stat_add(kids, kids + 1);

Pekka Pessi's avatar
Pekka Pessi committed
372
  su_strlst_destroy(l);
373 374

  su_home_get_stats(home, 1, parent, (sizeof parent));
375

Pekka Pessi's avatar
Pekka Pessi committed
376 377 378 379 380 381 382 383
  su_home_check(home);
  su_home_deinit(home);

  su_home_init(home);

  {
    char s[] = "foo\nfaa\n";
    TEST_1((l = su_strlst_split(home, s, "\n")));
384
    TEST_SIZE(su_strlst_len(l), 3);
Pekka Pessi's avatar
Pekka Pessi committed
385 386 387 388 389 390 391
    TEST_1(su_strlst_append(l, "bar"));
    TEST_S(su_strlst_join(l, home, "\n"), "foo\nfaa\n\nbar");
  }

  {
    char s[] = "foo";
    TEST_1((l = su_strlst_split(home, s, "\n")));
392
    TEST_SIZE(su_strlst_len(l), 1);
Pekka Pessi's avatar
Pekka Pessi committed
393 394 395 396 397
  }

  {
    char s[] = "\n\n";
    TEST_1((l = su_strlst_split(home, s, "\n")));
398
    TEST_SIZE(su_strlst_len(l), 3);
Pekka Pessi's avatar
Pekka Pessi committed
399 400 401 402 403
  }

  {
    char s[] = "";
    TEST_1((l = su_strlst_split(home, s, "\n")));
404
    TEST_SIZE(su_strlst_len(l), 1);
Pekka Pessi's avatar
Pekka Pessi committed
405
  }
406

Pekka Pessi's avatar
Pekka Pessi committed
407 408 409 410 411 412 413 414 415 416 417 418
  {
    int i;

#define S \
      "a\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\n" \
      "n\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n" \
      "A\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\n" \
      "N\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n"

    char s[] = S;

    TEST_1((l = su_strlst_split(home, s, "\n")));
419
    TEST_SIZE(su_strlst_len(l), 53);
Pekka Pessi's avatar
Pekka Pessi committed
420 421 422 423 424 425 426 427
    TEST_1(su_strlst_append(l, "bar"));
    TEST_S(su_strlst_join(l, home, "\n"), S "\nbar");

    TEST_1(!su_strlst_remove(l, 54));

    for (i = 0; i < 54; i++) {
      TEST_1(su_strlst_remove(l, 0));
      TEST_1(!su_strlst_remove(l, 53 - i));
428
      TEST_SIZE(su_strlst_len(l), 53 - i);
Pekka Pessi's avatar
Pekka Pessi committed
429 430 431
    }

    TEST_1(!su_strlst_remove(l, 0));
432
    TEST_SIZE(su_strlst_len(l), 0);
Pekka Pessi's avatar
Pekka Pessi committed
433 434
  }

435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473
  {
    char const *s0;

    TEST_1(l = su_strlst_create_with(NULL, s0 = "a", "b", NULL));
    TEST_1(su_strlst_item(l, 0) == s0);
    TEST_S(su_strlst_item(l, 0), "a");
    TEST_S(su_strlst_item(l, 1), "b");
    TEST_1(su_strlst_item(l, 2) == NULL);

    TEST_S(su_slprintf(l, "1: %u", 1), "1: 1");
    TEST_S(su_slprintf(l, "1.0: %g", 1.0), "1.0: 1");

    TEST_1(su_strlst_append(l, ""));

    TEST_S(su_strlst_join(l, home, "\n"), 
	   "a\n" "b\n" "1: 1\n" "1.0: 1\n");

    TEST_VOID(su_strlst_destroy(l));

    TEST_1(l2 = su_strlst_create_with_dup(NULL,
					  s0 = "0", "1", "2", "3",
					  "4", "5", "6", "7",
					  NULL));
    TEST_1(su_strlst_item(l2, 0) != s0);
    TEST_S(su_strlst_item(l2, 0), "0");
    TEST_S(su_strlst_item(l2, 1), "1");
    TEST_S(su_strlst_item(l2, 2), "2");
    TEST_S(su_strlst_item(l2, 3), "3");
    TEST_S(su_strlst_item(l2, 4), "4");
    TEST_S(su_strlst_item(l2, 5), "5");
    TEST_S(su_strlst_item(l2, 6), "6");
    TEST_S(su_strlst_item(l2, 7), "7");
    TEST_1(su_strlst_item(l2, 8) == NULL);

    TEST_S(su_strlst_join(l2, home, ""), "01234567");

    TEST_VOID(su_strlst_destroy(l2));
  }
  su_home_check(home);
Pekka Pessi's avatar
Pekka Pessi committed
474 475 476 477 478
  su_home_deinit(home);

  END();
}

479
#include <sofia-sip/su_vector.h>
Pekka Pessi's avatar
Pekka Pessi committed
480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509

typedef struct test_data_s {
  su_home_t test_home[1];
  int data;
} test_data_t;

static void test_vector_free(void *data)
{
  su_home_zap((su_home_t *) data);
}

static int test_vectors(void)
{
  su_home_t home[1] = { SU_HOME_INIT(home) };
  su_vector_t *v, *w;
  test_data_t *data1, *data2, *data3, *data4;
  char foo[] = "foo";
  char bar[] = "bar";
  char baz[] = "baz";
  void **a;
  int i;

  BEGIN();

  TEST_1(v = su_vector_create(home, NULL));
  TEST_1(su_vector_is_empty(v));
  TEST(su_vector_append(v, foo), 0);
  TEST(su_vector_append(v, bar), 0);
  TEST(su_vector_insert(v, 0, baz), 0);

510 511 512 513 514
  TEST_P(su_vector_item(v, 0), baz);
  TEST_P(su_vector_item(v, 1), foo);
  TEST_P(su_vector_item(v, 2), bar);
  TEST_P(su_vector_item(v, 3), NULL);
  TEST_P(su_vector_item(v, (unsigned)-1), NULL);
Pekka Pessi's avatar
Pekka Pessi committed
515
  TEST_1(!su_vector_is_empty(v));
516

Pekka Pessi's avatar
Pekka Pessi committed
517 518 519 520 521 522 523 524 525 526 527 528 529 530
  su_vector_destroy(v);

  TEST_1(v = su_vector_create(home, NULL));
  TEST(su_vector_insert(v, 0, "j"), 0);
  TEST(su_vector_insert(v, 0, "i"), 0);
  TEST(su_vector_insert(v, 0, "h"), 0);
  TEST(su_vector_insert(v, 0, "g"), 0);
  TEST(su_vector_insert(v, 0, "f"), 0);
  TEST(su_vector_insert(v, 0, "e"), 0);
  TEST(su_vector_insert(v, 0, "d"), 0);
  TEST(su_vector_insert(v, 0, "c"), 0);
  TEST(su_vector_insert(v, 0, "b"), 0);
  TEST(su_vector_insert(v, 0, "a"), 0);

531
  TEST_SIZE(su_vector_len(v), 10);
Pekka Pessi's avatar
Pekka Pessi committed
532 533 534 535 536 537
  TEST_1(a = su_vector_get_array(v));

  for (i = 0; i < 10; i++) {
    TEST_S(su_vector_item(v, i), a[i]);
  }

538 539
  TEST_P(su_vector_item(v, 10), NULL);
  TEST_P(a[10], NULL);
Pekka Pessi's avatar
Pekka Pessi committed
540 541 542 543 544 545 546 547 548 549 550 551 552

  TEST_1(w = su_vector_create(home, NULL));
  TEST(su_vector_append(w, "a"), 0);
  TEST(su_vector_append(w, "b"), 0);
  TEST(su_vector_append(w, "c"), 0);
  TEST(su_vector_append(w, "d"), 0);
  TEST(su_vector_append(w, "e"), 0);
  TEST(su_vector_append(w, "f"), 0);
  TEST(su_vector_append(w, "g"), 0);
  TEST(su_vector_append(w, "h"), 0);
  TEST(su_vector_append(w, "i"), 0);
  TEST(su_vector_append(w, "j"), 0);

553
  TEST_SIZE(su_vector_len(w), 10);
Pekka Pessi's avatar
Pekka Pessi committed
554 555 556 557 558 559 560 561 562 563

  for (i = 0; i < 10; i++) {
    TEST_S(su_vector_item(v, i), a[i]);
  }

  su_vector_empty(w);
  TEST_1(su_vector_is_empty(w));

  su_vector_destroy(v);
  su_vector_destroy(w);
564

Pekka Pessi's avatar
Pekka Pessi committed
565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580
  TEST_1(v = su_vector_create(home, test_vector_free));
  data1 = su_home_clone(home, sizeof(test_data_t));
  data1->data = 1;

  data2 = su_home_clone(home, sizeof(test_data_t));
  data2->data = 2;

  data3 = su_home_clone(home, sizeof(test_data_t));
  data3->data = 3;

  data4 = su_home_clone(home, sizeof(test_data_t));
  data4->data = 4;

  TEST(su_vector_append(v, data1), 0);
  TEST(su_vector_append(v, data2), 0);
  TEST(su_vector_append(v, data3), 0);
581
  TEST(su_vector_append(v, data4), 0);
Pekka Pessi's avatar
Pekka Pessi committed
582

583
  TEST_SIZE(su_vector_len(v), 4);
Pekka Pessi's avatar
Pekka Pessi committed
584

585 586 587 588
  TEST_P(su_vector_item(v, 0), data1);
  TEST_P(su_vector_item(v, 1), data2);
  TEST_P(su_vector_item(v, 2), data3);
  TEST_P(su_vector_item(v, 3), data4);
Pekka Pessi's avatar
Pekka Pessi committed
589 590 591 592 593 594 595 596

  TEST(data1->data, 1);
  TEST(data2->data, 2);
  TEST(data3->data, 3);
  TEST(data4->data, 4);

  TEST(su_vector_remove(v, 2), 0);

597
  TEST_SIZE(su_vector_len(v), 3);
Pekka Pessi's avatar
Pekka Pessi committed
598

599 600 601
  TEST_P(su_vector_item(v, 0), data1);
  TEST_P(su_vector_item(v, 1), data2);
  TEST_P(su_vector_item(v, 2), data4);
Pekka Pessi's avatar
Pekka Pessi committed
602 603 604 605 606 607 608 609 610 611 612 613

  TEST(data1->data, 1);
  TEST(data2->data, 2);
  TEST(data4->data, 4);

  su_vector_destroy(v);

  su_home_check(home);
  su_home_deinit(home);

  END();
}
Pekka Pessi's avatar
Pekka Pessi committed
614 615

#define ALIGNMENT (8)
616
#define ALIGN(n)  ((size_t)((n) + (ALIGNMENT - 1)) & (size_t)~(ALIGNMENT - 1))
Pekka Pessi's avatar
Pekka Pessi committed
617 618 619 620 621 622

static int test_auto(void)
{
  BEGIN();

  int i;
623
  su_home_t tmphome[SU_HOME_AUTO_SIZE(8000)];
Pekka Pessi's avatar
Pekka Pessi committed
624
  char *b = NULL;
625
  su_home_stat_t hs[1];
Pekka Pessi's avatar
Pekka Pessi committed
626 627 628

  TEST_1(!su_home_auto(tmphome, sizeof tmphome[0]));
  TEST_1(su_home_auto(tmphome, sizeof tmphome));
629

Pekka Pessi's avatar
Pekka Pessi committed
630 631 632 633 634 635
  for (i = 0; i < 8192; i++)
    TEST_1(su_alloc(tmphome, 12));

  TEST_VOID(su_home_deinit(tmphome));

  TEST_1(su_home_auto(tmphome, sizeof tmphome));
636

637 638
  su_home_init_stats(tmphome);

Pekka Pessi's avatar
Pekka Pessi committed
639 640
  for (i = 1; i < 8192; i++) {
    TEST_1(b = su_realloc(tmphome, b, i));
641 642 643 644 645 646 647 648 649 650
    b[i - 1] = '\125';
  }

  for (i = 1; i < 8192; i++) {
    TEST(b[i - 1], '\125');
  }

  for (i = 1; i < 8192; i++) {
    TEST_1(b = su_realloc(tmphome, b, i));
    b[i - 1] = '\125';
651

652 653
    if ((i % 32) == 0)
      TEST_1(b = su_realloc(tmphome, b, 1));
Pekka Pessi's avatar
Pekka Pessi committed
654 655
  }

656 657
  su_home_get_stats(tmphome, 0, hs, sizeof *hs);

658
  TEST64(hs->hs_allocs.hsa_preload + hs->hs_allocs.hsa_number, 
659
	  8191 + 8191 + 8191 / 32);
660
  TEST64(hs->hs_frees.hsf_preload + hs->hs_frees.hsf_number,
661
	 8191 + 8191 + 8191 / 32 - 1);
662 663 664 665
  /*
    This test depends on macro SU_HOME_AUTO_SIZE() calculating
    offsetof(su_block_t, sub_nodes[7]) correctly with

666
    ((3 * sizeof (void *) + 4 * sizeof(unsigned) +
667 668
      7 * (sizeof (long) + sizeof(void *)) + 7)
  */
669 670
  TEST_1(hs->hs_frees.hsf_preload == hs->hs_allocs.hsa_preload);

671 672 673 674 675
  su_free(tmphome, b);

  for (i = 1; i < 8192; i++)
    TEST_1(b = su_alloc(tmphome, 1));

Pekka Pessi's avatar
Pekka Pessi committed
676
  TEST_VOID(su_home_deinit(tmphome));
677

Pekka Pessi's avatar
Pekka Pessi committed
678 679
  END();
}
680

681
void usage(int exitcode)
682
{
683 684
  fprintf(stderr, "usage: %s [-v] [-a]\n", name);
  exit(exitcode);
685 686 687 688 689 690 691 692 693 694
}

int main(int argc, char *argv[])
{
  int retval = 0;
  int i;

  for (i = 1; argv[i]; i++) {
    if (strcmp(argv[i], "-v") == 0)
      tstflags |= tst_verbatim;
695 696
    else if (strcmp(argv[i], "-a") == 0)
      tstflags |= tst_abort;
697
    else
698
      usage(1);
699
  }
700 701 702
#if HAVE_OPEN_C
  tstflags |= tst_verbatim;
#endif
703

704 705 706 707 708 709 710 711 712 713
  retval |= test_alloc();
  retval |= test_strdupcat();
  retval |= test_sprintf("%s.%s", "foo", "bar");
  retval |= test_strlst();
  retval |= test_vectors();
  retval |= test_auto();

  return retval;
}