/*
 * Copyright (c) 2000-2004 Sendmail, Inc. and its suppliers.
 *	All rights reserved.
 *
 * By using this file, you agree to the terms and conditions set
 * forth in the LICENSE file which can be found at the top level of
 * the sendmail distribution.
 */

#include "sm/generic.h"
SM_IDSTR(id, "@(#)$Id: t-heap.c,v 1.13 2004/12/29 23:47:29 ca Exp $")

#include <stdio.h>
#include "sm/debug.h"
#include "sm/heap.h"
#include "sm/test.h"
#include "sm/io.h"

#if SM_HEAP_CHECK
extern SM_DEBUG_T SmHeapCheck;
# define HEAP_CHECK (SmHeapCheck > 0)
#else /* SM_HEAP_CHECK */
# define HEAP_CHECK 0
#endif /* SM_HEAP_CHECK */

int
main(int argc, char *argv[])
{
	int c;
	size_t s, i;
	void *p;

#if SM_HEAP_CHECK
	SmHeapCheck = 0;
#endif /* SM_HEAP_CHECK */
	while ((c = getopt(argc, argv, "H:")) != -1)
	{
		switch (c)
		{
#if SM_HEAP_CHECK
		  case 'H':
			SmHeapCheck = atoi(optarg);
			break;
#endif /* SM_HEAP_CHECK */
#if 0
		  default:
			usage(argv[0]);
			return(1);
#endif /* 0 */
		}
	}
	sm_test_begin(argc, argv, "test heap handling");

	p = sm_malloc(0);
	SM_TEST(p != NULL);
	sm_free(p);
#if 0
	/*
		HP-UX:
		realloc()	Changes the size of the block pointed to by ptr
				to size bytes and returns a pointer to the
				(possibly moved) block.  Existing contents are
				unchanged up to the lesser of the new and old
				sizes.  If ptr is a NULL pointer, realloc()
				behaves like malloc() for the specified size.
				If size is zero and ptr is not a NULL pointer,
				the object it points to is freed and NULL is
				returned.

		--> don't use it, size 0 is stupid anyway...
	*/

	p = sm_realloc(p, 0);
	SM_TEST(p != NULL);
#endif /* 0 */

	p = sm_malloc(10);
	SM_TEST(p != NULL);
	p = sm_realloc(p, 20);
	SM_TEST(p != NULL);
	p = sm_realloc(p, 30);
	SM_TEST(p != NULL);
	if (HEAP_CHECK)
	{
		sm_io_fprintf(smioout, "heap with 1 30-byte block allocated:\n");
		sm_heap_report(smioout, 3);
	}

	sm_free(p);
	if (HEAP_CHECK)
	{
		sm_io_fprintf(smioout, "heap with 0 blocks allocated:\n");
		sm_heap_report(smioout, 3);
	}

	for (s = 10; s < 10000; s += 500)
	{
		p = sm_zalloc(s);
		SM_TEST(p != NULL);
		if (p != NULL)
		{
			char *ptr;

			ptr = p;
			for (i = 0; i < s; i++)
				SM_TEST(ptr[i] == '\0');
			sm_free(p);
		}
	}

#if SM_T_DEBUG
	/* this will cause a core dump */
	printf("about to free %p for the second time\n", p);
	sm_free(p);
#endif /* SM_T_DEBUG */

	return sm_test_end();
}


syntax highlighted by Code2HTML, v. 0.9.1