/* $Id: cpl_init.c,v 1.22.2.2 2008/11/13 09:51:24 lbilbao Exp $ * * This file is part of the ESO Common Pipeline Library * Copyright (C) 2001-2005 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: lbilbao $ * $Date: 2008/11/13 09:51:24 $ * $Revision: 1.22.2.2 $ * $Name: $ */ #ifdef HAVE_CONFIG_H #include #endif #include #include /* getenv() */ #include /* strcmp() */ #include #ifdef CPL_WCS_INSTALLED /* If WCS is installed */ /* Get WCSLIB version number */ #include #endif /* End If WCS is installed */ #include "cpl_memory_impl.h" #include "cpl_msg.h" #include "cpl_tools.h" #include "cpl_init.h" /** * @defgroup cpl_init Library Initialization * * The module provides the CPL library startup routine. The startup routine * initialises CPL internal data structures. For this reason, any application * using functions from the CPL libraries @b must call the startup routine * prior to calling any other CPL function. * * @par Synopsis: * @code * #include * @endcode */ /**@{*/ /** * @brief * Initialise the CPL core library. * * @param self @em CPL_INIT_DEFAULT is the only supported value * @return Nothing. * @note The function must be called once before any other CPL function. * * This function sets up the library internal subsystems, which other * CPL functions expect to be in a defined state. In particular, the CPL * memory management and the CPL messaging systems are initialised by * this function call. * * One of the internal subsystems of CPL handles memory allocation. * The default CPL memory mode is defined during the build procedure, * this default can be changed during the call to cpl_init() via the * environment variable CPL_MEMORY_MODE. The valid values are * 0: Use the default system functions for memory handling * 1: Exit if a memory-allocation fails, provide checking for memory leaks, * limited reporting of memory allocation and limited protection on * deallocation of invalid pointers. * 2: Exit if a memory-allocation fails, provide checking for memory leaks, * extended reporting of memory allocation and protection on deallocation * of invalid pointers. * Any other value (including NULL) will leave the default memory mode * unchanged. * * Possible #_cpl_error_code_ set in this function: * - CPL_ERROR_INCOMPATIBLE_INPUT if there is an inconsistency between the run- * time and compile-time versions of a library that CPL depends on internally, * e.g. CFITSIO. This error may occur with dynamic linking. If it does occur, * the use of CPL may lead to unexpected behaviour. */ void cpl_init(unsigned self) { #ifndef CPL_CFITSIO_MAX_VERSION #define CPL_CFITSIO_MAX_VERSION 4.0 #endif #ifdef CFITSIO_VERSION #define CPL_CFITSIO_VERSION CFITSIO_VERSION #else /* This macro was introduced after version 2.510 */ /* Since CPL currently depends on version 2.510, it is assumed at this point that the version actually is 2.510. */ #define CPL_CFITSIO_VERSION 2.51 #endif float cfitsio_version; const float cfitsio_version_diff = fits_get_version(&cfitsio_version) - (CPL_CFITSIO_VERSION); /* FIXME: CPLs internal config.h should define a macro with the supported CFITSIO version range, to ensure consistency between configure and run-time check. */ const float cfitsio_version_supported_min = 2.51; const float cfitsio_version_supported_max = CPL_CFITSIO_MAX_VERSION; int memory_mode = CPL_XMEMORY_MODE; /* Default from configure */ const char * memory_mode_string = getenv("CPL_MEMORY_MODE"); const char * err_msg = NULL; if (memory_mode_string != NULL) { if (strcmp("0", memory_mode_string) == 0) { memory_mode = 0; } else if (strcmp("1", memory_mode_string) == 0) { memory_mode = 1; } else if (strcmp("2", memory_mode_string) == 0) { memory_mode = 2; } /* else: Ignore the environment variable */ } cpl_memory_init(memory_mode); cpl_msg_init(); if (self != CPL_INIT_DEFAULT) { /* Avoid unused variable warning */ cpl_msg_warning(cpl_func, "Illegal input ignored"); } /* Oh, grief: The choice of float for the CFITSIO version means that for version 2.510, fits_get_version() differs from 2.51. On a Intel Xeon running Scientific Linux SL 4.0 and gcc version 4.2.1 this difference amounts to 8 multiples of FLT_EPSILON. Let us hope future versions of CFITSIO chooses version numbers that are representable by floats with an accuracy better than 100 multiples of FLT_EPSILON. :-(((((((((((((((((((((((((((((((((((((((((((((((((((( */ if (cfitsio_version_diff < -100.0 * FLT_EPSILON) { (void)cpl_error_set_message_macro(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT, __FILE__, __LINE__, "Run-time version %.3f of CFITSIO " "is lower than compile-time version " "%.3f", cfitsio_version, CPL_CFITSIO_VERSION); } else if (cfitsio_version_diff > 100.0 * FLT_EPSILON) { (void)cpl_error_set_message_macro(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT, __FILE__, __LINE__, "Run-time version %.3f of CFITSIO is " "higher than compile-time version " "%.3f", cfitsio_version, CPL_CFITSIO_VERSION); } if (cfitsio_version < cfitsio_version_supported_min - 100.0 * FLT_EPSILON) { err_msg = cpl_sprintf("The run-time version %.3f of CFITSIO is lower " "than the supported version %.3f", cfitsio_version, cfitsio_version_supported_min); } else if (cfitsio_version > cfitsio_version_supported_max + 100.0 * FLT_EPSILON) { err_msg = cpl_sprintf("The run-time version %.3f of CFITSIO is higher " "than the supported version %.3f", cfitsio_version, cfitsio_version_supported_max); } if (err_msg != NULL) { if (cpl_error_get_code()) { /* There is already an existing CPL error code, so this additional problem is communicated via the CPL error state */ (void)cpl_error_set_message_macro(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT, __FILE__, __LINE__, err_msg); } else { /* This condition is not in itself an error, so issue a warning */ cpl_msg_warning(cpl_func, "%s. Continue at your own risk.", err_msg); } cpl_free((char*)err_msg); err_msg = NULL; } return; } /*----------------------------------------------------------------------------*/ /** @brief Create a string of version numbers of CPL and its libraries @param self CPL_DESCRIPTION_DEFAULT @return A pointer to a constant character array */ /*----------------------------------------------------------------------------*/ const char * cpl_get_description(unsigned self) { /* At a later stage decription_mode may be used to select what version information to return, e.g. CPL only, 3rd party libraries only, or both */ #ifdef CPL_WCS_INSTALLED #ifdef WCSLIB_VERSION #define CPL_WCS_APPEND ", WCSLIB = " CPL_STRINGIFY(WCSLIB_VERSION) #else #define CPL_WCS_APPEND ", WCSLIB" #endif #else #define CPL_WCS_APPEND " (WCSLIB unavailable)" #endif #ifdef CFITSIO_VERSION if (self != CPL_DESCRIPTION_DEFAULT) { /* Avoid unused variable warning */ cpl_msg_warning(cpl_func, "Illegal input ignored"); } return "CPL = " VERSION ", CFITSIO = " CPL_STRINGIFY(CFITSIO_VERSION) CPL_WCS_APPEND; #else float cfitsio_version; const char * form = "CPL = " VERSION ", CFITSIO = %5.3f" CPL_WCS_APPEND; /* better too long than too short */ static char desc[256]; if (self != CPL_DESCRIPTION_DEFAULT) { /* Avoid unused variable warning */ cpl_msg_warning(cpl_func, "Illegal input ignored"); } (void)fits_get_version(&cfitsio_version); (void)sprintf(desc, form, cfitsio_version); return desc; #endif } /** * @brief * Stop the internal subsystems of CPL. * * @return Nothing. * @note Currently, the behaviour of any CPL function becomes * undefined after this function is called. * * This function must be called after any other CPL function * is called. * */ void cpl_end(void) { (void) cpl_tools_get_cputime(CPL_CLOCK_RESET); cpl_msg_stop(); return; } /**@}*/