/* $Id: cpl_memory-test.c,v 1.18 2008/02/07 10:47:51 llundin Exp $ * * This file is part of the ESO Common Pipeline Library * Copyright (C) 2001-2004 European Southern Observatory * * 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 2 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, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * $Author: llundin $ * $Date: 2008/02/07 10:47:51 $ * $Revision: 1.18 $ * $Name: $ */ #ifdef HAVE_CONFIG_H # include #endif /*----------------------------------------------------------------------------- Includes -----------------------------------------------------------------------------*/ #include #include "cpl_memory.h" #include "cpl_tools.h" /*----------------------------------------------------------------------------- Defines -----------------------------------------------------------------------------*/ #ifndef CPL_MEMORY_BENCH # define CPL_MEMORY_BENCH 1 #endif #ifndef CPL_XMEMORY_MODE # error "Must know CPL_XMEMORY_MODE" #endif #ifndef CPL_XMEMORY_MAXPTRS # error "Must know CPL_XMEMORY_MAXPTRS" #endif /* Fill the xmemory table to this level */ /* A positive number not exceeding 1.0 */ #ifndef CPL_XMEMORY_FILL # define CPL_XMEMORY_FILL 0.999 #endif /* Half the number of pointers to test with */ #if CPL_XMEMORY_MODE == 2 #define CPL_MEMORY_MAXPTRS_HALF \ ((int)(0.5*CPL_XMEMORY_MAXPTRS*CPL_XMEMORY_FILL)) #else #define CPL_MEMORY_MAXPTRS_HALF \ ((int)(0.5*200003*CPL_XMEMORY_FILL)) #endif #if CPL_XMEMORY_MODE == 0 # define CPL_MEMORY_IS_EMPTY -1 # define CPL_MEMORY_IS_NON_EMPTY -1 #else # define CPL_MEMORY_IS_EMPTY 1 # define CPL_MEMORY_IS_NON_EMPTY 0 #endif /*----------------------------------------------------------------------------*/ /** * @defgroup cpl_utils_test Testing of the CPL memory functions */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ /** @brief Unit tests of CPL memory module **/ /*----------------------------------------------------------------------------*/ int main(void) { cpl_test_init(PACKAGE_BUGREPORT, CPL_MSG_WARNING); /* Insert tests below */ /* Test cpl_malloc(), cpl_calloc, cpl_realloc(), cpl_free() */ { const size_t size = 997; void * buf1; void * buf2; if (cpl_msg_get_level() <= CPL_MSG_INFO) cpl_memory_dump(); cpl_test_eq(cpl_memory_is_empty(), CPL_MEMORY_IS_EMPTY); if (cpl_msg_get_level() <= CPL_MSG_INFO) cpl_memory_dump(); buf1 = cpl_malloc(size); buf2 = cpl_calloc(size, size); cpl_test_eq(cpl_memory_is_empty(), CPL_MEMORY_IS_NON_EMPTY); cpl_free(buf1); cpl_free(buf2); cpl_test_eq(cpl_memory_is_empty(), CPL_MEMORY_IS_EMPTY); buf1 = cpl_malloc(size); buf2 = cpl_calloc(size, size); cpl_test_nonnull(buf1); cpl_test_nonnull(buf2); cpl_test(buf1 != buf2); cpl_test(memset(buf1, 0, size) == buf1); cpl_test_eq(memcmp(buf1, buf2, size), 0); buf2 = cpl_realloc(buf2, size); cpl_test_nonnull(buf2); cpl_test(buf1 != buf2); cpl_test_eq(memcmp(buf1, buf2, size), 0); cpl_free(buf1); cpl_free(buf2); cpl_test_eq(cpl_memory_is_empty(), CPL_MEMORY_IS_EMPTY); /* Test cpl_malloc() involving zero size */ buf1 = cpl_malloc(0); if (buf1 == NULL) { cpl_msg_info(cpl_func, "cpl_malloc(0) returned NULL"); } else { cpl_test_eq(cpl_memory_is_empty(), CPL_MEMORY_IS_NON_EMPTY); } cpl_free(buf1); cpl_test_eq(cpl_memory_is_empty(), CPL_MEMORY_IS_EMPTY); /* Test cpl_calloc() involving zero size */ buf2 = cpl_calloc(0, 0); if (buf2 == NULL) { cpl_msg_info(cpl_func, "cpl_calloc(0, 0) returned NULL"); } else { cpl_test_eq(cpl_memory_is_empty(), CPL_MEMORY_IS_NON_EMPTY); } cpl_free(buf2); buf1 = cpl_calloc(0, size); if (buf1 == NULL) { cpl_msg_info(cpl_func, "cpl_calloc(0, size) returned NULL"); } cpl_free(buf1); buf1 = cpl_calloc(size, 0); if (buf1 == NULL) { cpl_msg_info(cpl_func, "cpl_calloc(size, 0) returned NULL"); } else { cpl_test_eq(cpl_memory_is_empty(), CPL_MEMORY_IS_NON_EMPTY); } cpl_free(buf1); /* Test cpl_realloc() involving zero size */ buf1 = cpl_realloc(NULL, 0); if (buf1 == NULL) { cpl_msg_info(cpl_func, "cpl_realloc(NULL, 0) returned NULL"); } else { cpl_test_eq(cpl_memory_is_empty(), CPL_MEMORY_IS_NON_EMPTY); } buf1 = cpl_realloc(buf1, 0); if (buf1 == NULL) { cpl_msg_info(cpl_func, "cpl_realloc(buf1, 0) returned NULL"); } else { cpl_test_eq(cpl_memory_is_empty(), CPL_MEMORY_IS_NON_EMPTY); } buf1 = cpl_realloc(buf1, size); cpl_test_nonnull(buf1); buf1 = cpl_realloc(buf1, 0); if (buf1 == NULL) { cpl_msg_info(cpl_func, "cpl_realloc(buf1, 0) returned NULL"); } else { cpl_test_eq(cpl_memory_is_empty(), CPL_MEMORY_IS_NON_EMPTY); } cpl_free(buf1); cpl_test_eq(cpl_memory_is_empty(), CPL_MEMORY_IS_EMPTY); } /* Test cpl_sprintf() */ { const char * string = __FILE__; /* Some non-empty string */ const char * null; /* This string is supposed to always be NULL */ const char * null2; /* This string is supposed to always be NULL */ char * nonnull; /* String is supposed to never be NULL */ /* Create a copy of an empty string */ nonnull = cpl_sprintf("%s", ""); cpl_test_error(CPL_ERROR_NONE); cpl_test_eq_string(nonnull, ""); cpl_free(nonnull); /* Create a copy of the string */ nonnull = cpl_sprintf("%s", string); cpl_test_error(CPL_ERROR_NONE); cpl_test_eq_string(nonnull, string); cpl_free(nonnull); /* Successfully create an illegal format string */ nonnull = cpl_sprintf("%s %s", string, "%"); cpl_test_error(CPL_ERROR_NONE); cpl_test_eq_string(nonnull, __FILE__ " %"); /* Check if an error is produced using that illegal format */ null = cpl_sprintf(nonnull, "."); if (null != NULL) { cpl_test_error(CPL_ERROR_NONE); cpl_msg_warning(cpl_func, "The supposedly illegal format '%s' " "produced the string: '%s'", nonnull, null); cpl_free((char*)null); null = NULL; } else { cpl_test_error(CPL_ERROR_ILLEGAL_INPUT); } cpl_free(nonnull); null2 = cpl_sprintf(null); cpl_test_error(CPL_ERROR_NULL_INPUT); cpl_test_null(null2); } /* Test cpl_strdup() */ { const char * string = __FILE__; /* Some non-empty string */ char * nonnull; /* String is supposed to never be NULL */ /* Create a copy of the string */ nonnull = cpl_strdup(string); cpl_test_nonnull(nonnull); cpl_test(strlen(nonnull) == strlen(string)); cpl_test(strcmp(nonnull, string) == 0); cpl_test_error(CPL_ERROR_NONE); cpl_free(nonnull); } if (CPL_MEMORY_BENCH > 0 && CPL_MEMORY_MAXPTRS_HALF > 0) { /* Always compile the bench-marking code */ int ii = CPL_MEMORY_BENCH; int i; void * buf1[CPL_MEMORY_MAXPTRS_HALF]; void * buf2[CPL_MEMORY_MAXPTRS_HALF]; cpl_msg_info("", "Testing memory allocation with %d X 2*%d", CPL_MEMORY_BENCH, CPL_MEMORY_MAXPTRS_HALF); do { for (i = 0; i < CPL_MEMORY_MAXPTRS_HALF; i++) { buf1[i] = cpl_malloc(16); buf2[i] = cpl_calloc(4, 16); } cpl_test_eq(cpl_memory_is_empty(), CPL_MEMORY_IS_NON_EMPTY); for (i = 0; i < CPL_MEMORY_MAXPTRS_HALF; i++) { buf1[i] = cpl_realloc(buf1[i], 32); buf2[i] = cpl_realloc(buf2[i], 32); } cpl_test_eq(cpl_memory_is_empty(), CPL_MEMORY_IS_NON_EMPTY); for (i = 0; i < CPL_MEMORY_MAXPTRS_HALF; i++) { cpl_free(buf1[i]); cpl_free(buf2[i]); } cpl_test_eq(cpl_memory_is_empty(), CPL_MEMORY_IS_EMPTY); } while (--ii); } if (cpl_msg_get_level() <= CPL_MSG_INFO) cpl_memory_dump(); return cpl_test_end(0); }