irplib_utils.h

00001 /* $Id: irplib_utils.h,v 1.42 2009/01/29 08:54:58 llundin Exp $
00002  *
00003  * This file is part of the irplib package 
00004  * Copyright (C) 2002,2003 European Southern Observatory
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02111-1307  USA
00019  */
00020 
00021 /*
00022  * $Author: llundin $
00023  * $Date: 2009/01/29 08:54:58 $
00024  * $Revision: 1.42 $
00025  * $Name: visir-3_2_2 $
00026  */
00027 
00028 #ifndef IRPLIB_UTILS_H
00029 #define IRPLIB_UTILS_H
00030 
00031 /*-----------------------------------------------------------------------------
00032                                    Includes
00033  -----------------------------------------------------------------------------*/
00034 
00035 #include <stdarg.h>
00036 
00037 #include <cpl.h>
00038 
00039 /*-----------------------------------------------------------------------------
00040                                    Define
00041  -----------------------------------------------------------------------------*/
00042 
00043 #define IRPLIB_XSTRINGIFY(TOSTRING) #TOSTRING
00044 #define IRPLIB_STRINGIFY(TOSTRING) IRPLIB_XSTRINGIFY(TOSTRING)
00045 
00046 /* FIXME: Remove when no longer used by any irplib-based pipelines */
00047 #define irplib_vsprintf cpl_vsprintf
00048 #define irplib_sprintf  cpl_sprintf
00049 
00050 /* FIXME: Remove when no longer used by any irplib-based pipelines */
00051 /* Useful for debugging */
00052 #define irplib_trace()  do if (cpl_error_get_code()) { \
00053     cpl_msg_debug(cpl_func, __FILE__ " at line %d: ERROR '%s' at %s", \
00054          __LINE__, cpl_error_get_message(), cpl_error_get_where()); \
00055   } else { \
00056     cpl_msg_debug(cpl_func, __FILE__ " at line %d: OK", __LINE__); \
00057   } while (0)
00058 
00059 #define irplib_error_recover(ESTATE, ...)                                      \
00060     do if (!cpl_errorstate_is_equal(ESTATE)) {                                 \
00061         cpl_msg_warning(cpl_func, __VA_ARGS__);                                \
00062         cpl_msg_indent_more();                                                 \
00063         cpl_errorstate_dump(ESTATE, CPL_FALSE, irplib_errorstate_warning);     \
00064         cpl_msg_indent_less();                                                 \
00065         cpl_errorstate_set(ESTATE);                                            \
00066     } while (0)
00067 
00068 
00069 
00070 /*----------------------------------------------------------------------------*/
00071 /*
00072   @brief Declare a function suitable for use with irplib_dfs_table_convert()
00073   @param  table_set_row    The name of the function to declare
00074   @see irplib_dfs_table_convert(), irplib_table_read_from_frameset()
00075 
00076 */
00077 /*----------------------------------------------------------------------------*/
00078 #define IRPLIB_UTIL_SET_ROW(table_set_row)                      \
00079     cpl_boolean table_set_row(cpl_table *,                      \
00080                               const char *,                     \
00081                               int,                              \
00082                               const cpl_frame *,                \
00083                               const cpl_parameterlist *)
00084 
00085 
00086 /*----------------------------------------------------------------------------*/
00087 /*
00088   @brief Declare a function suitable for use with irplib_dfs_table_convert()
00089   @param  table_check    The name of the function to declare
00090   @see irplib_dfs_table_convert()
00091 
00092 */
00093 /*----------------------------------------------------------------------------*/
00094 #define IRPLIB_UTIL_CHECK(table_check)                          \
00095     cpl_error_code table_check(cpl_table *,                     \
00096                                const cpl_frameset *,            \
00097                                const cpl_parameterlist *)
00098 
00099 
00100 /*----------------------------------------------------------------------------*/
00101 /*
00102   @brief   Conditional skip to the (unqiue) return point of the function
00103   @param   CONDITION    The condition to check
00104   @see cpl_error_ensure()
00105 
00106   skip_if() takes one argument, which is a logical expression. 
00107   If the logical expression is false skip_if() takes no action and
00108   program execution continues.
00109   If the logical expression is true this indicates an error. In this case
00110   skip_if() will set the location of the error to the point where it
00111   was invoked in the recipe code (unless the error location is already in the
00112   recipe code). If no error code had been set, then skip_if() will set one.
00113   Finally, skip_if() causes program execution to skip to the macro 'end_skip'.
00114   The macro end_skip is located towards the end of the function, after
00115   which all resource deallocation and the function return is located. 
00116 
00117   The use of skip_if() assumes the following coding practice:
00118   1) Pointers used for dynamically allocated memory that they "own" shall always
00119      point to either NULL or to allocated memory (including CPL-objects).
00120   2) Such pointers may not be reused to point to memory whose deallocation
00121      requires calls to different functions.
00122   3) Pointers of type FILE should be set NULL when not pointing to an open
00123      stream and their closing calls (fclose(), freopen(), etc.) following the
00124      'end_skip' should be guarded against such NULL pointers.
00125 
00126   Error checking with skip_if() is encouraged due to the following advantages:
00127   1) It ensures that a CPL-error code is set.
00128   2) It ensures that the location of the error in the _recipe_ code is noted.
00129   3) The error checking may be confined to a single concise line.
00130   4) It is not necessary to replicate memory deallocation for every error
00131      condition.
00132   5) If more extensive error reporting/handling is required it is not precluded
00133      by the use of skip_if().
00134   6) It allows for a single point of function return.
00135   7) It allows for optional, uniformly formatted debugging/tracing information
00136      at each macro invocation.
00137 
00138   The implementation of skip_if() uses a goto/label construction.
00139   According to Kerningham & Ritchie, The C Programming Language, 2nd edition,
00140   Section 3.8:
00141   "This organization is handy if the error-handling code is non-trivial,
00142   and if errors can occur in several places."
00143 
00144   The use of goto for any other purpose should be avoided.
00145 
00146 */
00147 /*----------------------------------------------------------------------------*/
00148 #define skip_if(CONDITION)                                                     \
00149     do {                                                                       \
00150         cpl_error_ensure(!cpl_error_get_code(), cpl_error_get_code(),          \
00151                          goto cleanup, "Propagating a pre-existing error");    \
00152         cpl_error_ensure(!(CONDITION), cpl_error_get_code(),                   \
00153                          goto cleanup, "Propagating error");\
00154     } while (0)
00155 
00156 /*----------------------------------------------------------------------------*/
00157 /*
00158   @brief   Skip if A < B
00159   @param   A   The 1st double to compare
00160   @param   B   The 2nd double to compare
00161   @param   MSG The message to use on failure
00162   @see skip_if()
00163   @note A and B are evaluated exactly once
00164 */
00165 /*----------------------------------------------------------------------------*/
00166 #define skip_if_lt(A, B, MSG)                                                  \
00167     do {                                                                       \
00168         const double tmpa = (double)(A);                                       \
00169         const double tmpb = (double)(B);                                       \
00170                                                                                \
00171         cpl_error_ensure(!cpl_error_get_code(), cpl_error_get_code(),          \
00172                          goto cleanup, "Propagating a pre-existing error");    \
00173         cpl_error_ensure(tmpa >= tmpb, CPL_ERROR_DATA_NOT_FOUND,               \
00174                          goto cleanup, "Need at least %g (not %g) %s",         \
00175                          tmpb, tmpa, MSG);                                     \
00176     } while (0)
00177 
00178 /*----------------------------------------------------------------------------*/
00179 /*
00180   @brief   Conditional skip on coding bug
00181   @param   CONDITION    The condition to check
00182   @see skip_if()
00183   @note unlike assert() this check cannot be disabled
00184  */
00185 /*----------------------------------------------------------------------------*/
00186 #define bug_if(CONDITION)                                                      \
00187     do {                                                                       \
00188         cpl_error_ensure(!cpl_error_get_code(), cpl_error_get_code(),          \
00189                          goto cleanup, "Propagating an unexpected error, "     \
00190                          "please report to " PACKAGE_BUGREPORT);               \
00191         cpl_error_ensure(!(CONDITION), CPL_ERROR_UNSPECIFIED,                  \
00192                          goto cleanup, "Internal error, please report to "     \
00193                          PACKAGE_BUGREPORT);                                   \
00194     } while (0)
00195 
00196 /*----------------------------------------------------------------------------*/
00197 /*
00198   @brief   Conditional skip with error creation
00199   @param   CONDITION    The condition to check
00200   @param   ERROR        The error code to set
00201   @param   MSG          A printf-style error message. As a matter of
00202                         user-friendliness the message should mention any
00203                         value that caused the @em CONDITION to fail.
00204   @see skip_if()
00205   @note unlike assert() this check cannot be disabled
00206  */
00207 /*----------------------------------------------------------------------------*/
00208 #define error_if(CONDITION, ERROR, ...)                                        \
00209     do {                                                                       \
00210         cpl_error_ensure(cpl_error_get_code() == CPL_ERROR_NONE &&             \
00211                          !(CONDITION), ERROR, goto cleanup,  __VA_ARGS__);     \
00212     } while (0)
00213 
00214 /*----------------------------------------------------------------------------*/
00215 /*
00216   @brief   Define the single point of resource deallocation and return
00217   @see skip_if()
00218   @note end_skip should be used exactly once in functions that use skip_if() etc
00219 */
00220 /*----------------------------------------------------------------------------*/
00221 #define end_skip \
00222     do {                                                                     \
00223         cleanup:                                                             \
00224         if (cpl_error_get_code())                                            \
00225             cpl_msg_debug(cpl_func, "Cleanup in " __FILE__ " line %u with "  \
00226                           "error '%s' at %s", __LINE__,                      \
00227                           cpl_error_get_message(), cpl_error_get_where());   \
00228         else                                                                 \
00229             cpl_msg_debug(cpl_func, "Cleanup in " __FILE__ " line %u",       \
00230                           __LINE__);                                         \
00231     } while (0)
00232 
00233 
00234 /*----------------------------------------------------------------------------*/
00246 /*----------------------------------------------------------------------------*/
00247 #define irplib_ensure(CONDITION, ec, ...)                                      \
00248     cpl_error_ensure(CONDITION, ec, goto cleanup,  __VA_ARGS__)
00249 
00250 /*----------------------------------------------------------------------------*/
00280 /*----------------------------------------------------------------------------*/
00281 
00282 #define irplib_check(COMMAND, ...)                                             \
00283   do {                                                                         \
00284     cpl_errorstate irplib_check_prestate = cpl_errorstate_get();               \
00285     skip_if(0);                                                                \
00286     COMMAND;                                                                   \
00287         irplib_trace(); \
00288     irplib_ensure(cpl_errorstate_is_equal(irplib_check_prestate),              \
00289                   cpl_error_get_code(), __VA_ARGS__);                          \
00290         irplib_trace(); \
00291   } while (0)
00292 
00293 /*-----------------------------------------------------------------------------
00294                                    Function prototypes
00295  -----------------------------------------------------------------------------*/
00296 
00297 
00298 
00299 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE > CPL_VERSION(4, 8, 0)
00300 cpl_error_code irplib_dfs_save_image(cpl_frameset            *,
00301                                      const cpl_parameterlist *,
00302                                      const cpl_frameset      *,
00303                                      const cpl_image         *,
00304                                      cpl_type_bpp             ,
00305                                      const char              *,
00306                                      const char              *,
00307                                      const cpl_propertylist  *,
00308                                      const char              *,
00309                                      const char              *,
00310                                      const char              *);
00311 
00312 
00313 cpl_error_code irplib_dfs_save_propertylist(cpl_frameset            *,
00314                                             const cpl_parameterlist *,
00315                                             const cpl_frameset      *,
00316                                             const char              *,
00317                                             const char              *,
00318                                             const cpl_propertylist  *,
00319                                             const char              *,
00320                                             const char              *,
00321                                             const char              *);
00322 
00323 cpl_error_code irplib_dfs_save_imagelist(cpl_frameset            *,
00324                                          const cpl_parameterlist *,
00325                                          const cpl_frameset      *,
00326                                          const cpl_imagelist     *,
00327                                          cpl_type_bpp             ,
00328                                          const char              *,
00329                                          const char              *,
00330                                          const cpl_propertylist  *,
00331                                          const char              *,
00332                                          const char              *,
00333                                          const char              *);
00334 
00335 cpl_error_code irplib_dfs_save_table(cpl_frameset            *,
00336                                      const cpl_parameterlist *,
00337                                      const cpl_frameset      *,
00338                                      const cpl_table         *,
00339                                      const cpl_propertylist  *,
00340                                      const char              *,
00341                                      const char              *,
00342                                      const cpl_propertylist  *,
00343                                      const char              *,
00344                                      const char              *,
00345                                      const char              *);
00346 #else
00347 #define irplib_dfs_save_image cpl_dfs_save_image
00348 #define irplib_dfs_save_propertylist cpl_dfs_save_propertylist
00349 #define irplib_dfs_save_imagelist cpl_dfs_save_imagelist
00350 #define irplib_dfs_save_table cpl_dfs_save_table
00351 #endif
00352 
00353 void irplib_reset(void);
00354 int irplib_compare_tags(cpl_frame *, cpl_frame *);
00355 const char * irplib_frameset_find_file(const cpl_frameset *, const char *);
00356 cpl_frame * irplib_frameset_get_first_from_group(const cpl_frameset *,
00357                                                  cpl_frame_group);
00358 
00359 cpl_error_code irplib_apertures_find_max_flux(const cpl_apertures *, int *,
00360                                               int);
00361 
00362 int irplib_isinf(double value);
00363 int irplib_isnan(double value);
00364 
00365 void irplib_errorstate_warning(unsigned, unsigned, unsigned);
00366 
00367 cpl_error_code
00368 irplib_dfs_table_convert(cpl_table *, cpl_frameset *, const cpl_frameset *,
00369                          int, char, const char *, const char *,
00370                          const cpl_parameterlist *, const char *,
00371                          const cpl_propertylist *, const cpl_propertylist *,
00372                          const char *, const char *, const char *,
00373                          cpl_boolean (*)(cpl_table *, const char *, int,
00374                                             const cpl_frame *,
00375                                             const cpl_parameterlist *),
00376                          cpl_error_code (*)(cpl_table *,
00377                                             const cpl_frameset *,
00378                                             const cpl_parameterlist *));
00379 
00380 cpl_error_code irplib_table_read_from_frameset(cpl_table *,
00381                                                const cpl_frameset *,
00382                                                int,
00383                                                char,
00384                                                const cpl_parameterlist *,
00385                                                cpl_boolean (*)
00386                                                (cpl_table *, const char *,
00387                                                 int, const cpl_frame *,
00388                                                 const cpl_parameterlist *));
00389 
00390 cpl_error_code irplib_image_split(const cpl_image *,
00391                                   cpl_image *, cpl_image *, cpl_image *,
00392                                   double, cpl_boolean,
00393                                   double, cpl_boolean,
00394                                   double, double,
00395                                   cpl_boolean, cpl_boolean, cpl_boolean);
00396 
00397 #endif

Generated on Fri Jul 3 11:15:23 2009 for VISIR Pipeline Reference Manual by  doxygen 1.5.8