/*
 * Copyright 2002 Silicon Graphics, Inc. All rights reserved.
 */
#include <kl_lib.h>

alloc_functions_t alloc_functions;

/*
 * _kl_alloc_block()
 */
void *
_kl_alloc_block(int size, int flags, void *ra)
{
	void *blk;

	if (size == 0) {
		errno = EINVAL;
		return((void *)NULL);
	}
	if (KL_BLOCK_ALLOC()) {
	        blk = KL_BLOCK_ALLOC()(size, flags, ra);
	} else {
		if ((blk = (void*)malloc(size))) {
			bzero(blk, size);
		}
	}
	if (!blk) {
		errno = ENOMEM;
	}
	return(blk);
}

/*
 * _kl_realloc_block()
 */
void *
_kl_realloc_block(void *b, int new_size, int flags, void *ra)
{
	void * blk;


	if (!b || new_size == 0) {
		errno = EINVAL;
		return((void *)NULL);
	}

	if (KL_BLOCK_REALLOC()) {
		blk = (void *)KL_BLOCK_REALLOC()(b, new_size, flags, ra);
	} else {
		if ((blk = (void *)realloc(b, new_size))) {
			bzero(blk, new_size);
		}
	}
	if (!blk) {
		errno = ENOMEM;
	}
	return(blk);
}

/*
 * _kl_dup_block()
 */
void *
_kl_dup_block(void *b, int flags, void *ra)
{
	void *blk;

	if (!b) {
		errno = EINVAL;
		return((void *)NULL);
	}

	if (KL_BLOCK_DUP()) {
		blk = (void *)KL_BLOCK_DUP()(b, flags, ra);
	} else {
		/* There is no way to determine the size of a block if 
		 * it has been allocated via malloc(). Therefore return 
		 * a NULL pointer (and an error).
		 */
		errno = EPERM;
		return((void *)NULL);
	}
	if (!blk) {
		errno = ENOMEM;
	}
	return(blk);
}

/*
 * _kl_str_to_block()
 */
void *
_kl_str_to_block(char *s, int flags, void *ra)
{
	void *blk = (void *)NULL;

	if (!s) {
		errno = EINVAL;
		return((void *)NULL);
	}

	if (KL_STR_TO_BLOCK()) {
		blk = (void *)KL_STR_TO_BLOCK()(s, flags, ra);
	} else {
		int size;

		if ((size = (strlen(s) + 1))) {
			blk = _kl_alloc_block(size, flags, ra);
			bcopy(s, blk, size);
		}
	}
	if (!blk) {
		errno = ENOMEM;
	}
	return(blk);
}

/*
 * kl_free_block()
 */
void
kl_free_block(void *blk)
{
	if (!blk) {
		return;
	}
	if (KL_BLOCK_FREE()) {
		KL_BLOCK_FREE()(blk);
	} else {
		free(blk);
	}
}
