/*                                                                            *
 *   This file is part of the ESO X-shooter Pipeline                          *
 *   Copyright (C) 2006 European Southern Observatory                         *
 *                                                                            *
 *   This library 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, 51 Franklin St, Fifth Floor, Boston, MA  02111-1307  USA     *
 *                                                                            */

/*
 * $Author: amodigli $
 * $Date: 2011-12-02 14:15:28 $
 * $Revision: 1.15 $
 * $Name: not supported by cvs2svn $
 */

#ifndef XSH_ERROR_H
#define XSH_ERROR_H

/*----------------------------------------------------------------------------*/
/**
  @defgroup xsh_error Error handling

  @defgroup xsh_error_macro       Xshooter error handling
  @ingroup xsh_error
*/
/*----------------------------------------------------------------------------*/
/**@{*/

/*-----------------------------------------------------------------------------
   			     Includes
 -----------------------------------------------------------------------------*/
#include <irplib_error.h>

#include <cpl.h>

/*-----------------------------------------------------------------------------
                             Defines
 -----------------------------------------------------------------------------*/
/* To save some key-strokes, use the irplib error handling macros
   under different (shorter) names.
   Additionally, irplib macros require the VA_ARGS to be enclosed in (),
*/
#define assure(CONDITION, ERROR_CODE, ...)          \
  irplib_error_assure(CONDITION, ERROR_CODE, (__VA_ARGS__), goto cleanup)

/** Condition */
#define assure_nomsg(BOOL, CODE) \
    assure(BOOL, CODE, " ")

/* Define check macro using error message */
#define check_msg(COMMAND, ...)                                                \
  irplib_error_assure((cpl_msg_indent_more(),                                  \
                       (COMMAND),                                              \
                       cpl_msg_indent_less(),                                  \
                       cpl_error_get_code() == CPL_ERROR_NONE),                \
		      cpl_error_get_code(),                                    \
		      (__VA_ARGS__), goto cleanup)

/* Define check macro without error message */
#define check(COMMAND) check_msg(COMMAND, " ")

#define cknull_msg(NULLEXP, ...) \
  cpl_error_ensure((NULLEXP) != NULL, \
  CPL_ERROR_UNSPECIFIED, goto cleanup,__VA_ARGS__)

#define cknull(NULLEXP) cknull_msg(NULLEXP," ")

#define assure_mem(PTR) \
    assure((PTR) != NULL, CPL_ERROR_ILLEGAL_OUTPUT, "Memory allocation failure!")
/* Assertions */
#define passure(CONDITION, ...) assure(CONDITION, CPL_ERROR_UNSPECIFIED,      \
                                "Internal program error. Please report to "   \
                                PACKAGE_BUGREPORT " " __VA_ARGS__)
/* Assumes that PACKAGE_BUGREPORT contains no formatting special characters */

#define xsh_error_reset() xsh_irplib_error_reset()

/* Define here on which level to print
   error messages + tracing information
*/
#define xsh_error_dump(level)  irplib_error_dump(level, level)

#define xsh_error_msg(...) \
  if(cpl_error_get_code()!= CPL_ERROR_NULL_INPUT){\
    irplib_error_push(cpl_error_get_code(), (__VA_ARGS__));\
  }

#define XSH_ASSURE_NOT_NULL(pointer) \
  assure(pointer != NULL, CPL_ERROR_NULL_INPUT,\
    "You have null pointer in input: " #pointer)

#define XSH_ASSURE_NOT_NULL_MSG(pointer,msg)       \
  assure(pointer != NULL, CPL_ERROR_NULL_INPUT,\
    "You have null pointer in input: " #pointer "\n" msg)

#define XSH_ASSURE_NOT_ILLEGAL(cond) \
  assure(cond, CPL_ERROR_ILLEGAL_INPUT,\
    "condition failed: " #cond )

#define XSH_ASSURE_NOT_ILLEGAL_MSG(cond, msg) \
  assure(cond, CPL_ERROR_ILLEGAL_INPUT,\
    "condition failed: " #cond "\n" msg)

#define XSH_ASSURE_NOT_MISMATCH(cond) \
  assure(cond, CPL_ERROR_TYPE_MISMATCH,\
    "condition failed: "#cond )

#define XSH_CMP_INT(A, OPERATOR, B, SUFFIX ,...)\
  assure(A OPERATOR B, CPL_ERROR_ILLEGAL_INPUT,\
  "assertion failed: %s %s %s : %d %s %d\n"\
   #SUFFIX "", #A, #OPERATOR, #B , A, #OPERATOR, B __VA_ARGS__)

#define XSH_CHECK_COND(A, OPERATOR, B, SUFFIX, ...)\
  assure(A OPERATOR B, CPL_ERROR_ILLEGAL_INPUT,\
  "assertion failed: %s %s %s\n" #SUFFIX "", #A, #OPERATOR, #B, __VA_ARGS__)

#define XSH_CHECK_FRAMESET_SIZE(FRAMESET,OPERATOR,SIZE)\
  XSH_CHECK_COND(cpl_frameset_get_size(FRAMESET),OPERATOR,SIZE,\
    "%s","Frameset size invalid:")

#define XSH_REGDEBUG( ...)\
  xsh_msg_debug("<< REGDEBUG >> :" __VA_ARGS__)

#endif
/**@}*/

