/*
 * @(#)mwutil.h    generated by: makeheader 4.21  Mon Dec 20 16:30:15 2004
 *
 *		built from:	../../src/include/copyright.h
 *				../../src/include/pragma_interface.h
 *				include/msg_typedefs.h
 *				include/exception_typedefs.h
 *				include/err_typedefs.h
 *				./cputime.cpp
 *				./cycles.cpp
 *				./dconvert.cpp
 *				./demangle.cpp
 *				./dynload.cpp
 *				./emptystr.cpp
 *				./enum_str.cpp
 *				./expmatch.cpp
 *				./f2cstr.cpp
 *				./fgets.cpp
 *				./filelink.cpp
 *				./format.cpp
 *				./fp_conv.cpp
 *				./fpu.cpp
 *				./getcwd.cpp
 *				./hash.cpp
 *				./incrfcn.cpp
 *				./int_conv.cpp
 *				./logfile.cpp
 *				./lower.cpp
 *				./multibyte.cpp
 *				./mwclasses.cpp
 *				./perfcount.cpp
 *				./printf.cpp
 *				./purifytools.cpp
 *				./regexp.cpp
 *				./set.cpp
 *				./special_nans.cpp
 *				./stacktrc.cpp
 *				./strcat.cpp
 *				./strcmp.cpp
 *				./strcmpi.cpp
 *				./strcpy.cpp
 *				./strdup.cpp
 *				./strlen.cpp
 *				./strrep.c
 *				./strrstr.cpp
 *				./strtok.cpp
 *				./sysinfo.cpp
 *				./timeinfo.cpp
 *				./tmpnam.cpp
 *				./tolower.cpp
 *				./upper.cpp
 *				./ut_alloca.cpp
 *				./utassert.cpp
 *				./utsignal.cpp
 *				./wallclok.cpp
 *				array/array.cpp
 *				basic/basic_contexts.cpp
 *				coll/functional.cpp
 *				coll/hash_map.cpp
 *				coll/hashrank.cpp
 *				cpputils/chunkedptr.cpp
 *				cpputils/countlist.cpp
 *				cpputils/safepointer.cpp
 *				cpputils/stat_ref_ok.cpp
 *				cpputils/static_init.cpp
 *				cpputils/stl_allocator.cpp
 *				dsbuffer/dsbuffer.cpp
 *				dtoa/dtoa.cpp
 *				dtoa/fpc.cpp
 *				dtoa/g_fmt.cpp
 *				err/error_context.cpp
 *				excepts/exception.cpp
 *				excepts/internalexcept.cpp
 *				excepts/throwable.cpp
 *				excepts/userexcept.cpp
 *				ghash/ghash.cpp
 *				gtable/gtable.cpp
 *				hashtool/hashtool.cpp
 *				icuext/icuruntime.cpp
 *				icuext/uconv.cpp
 *				icuext/uctype.cpp
 *				icuext/uhash.cpp
 *				icuext/umisc.cpp
 *				icuext/urecognize.cpp
 *				icuext/uspecial.cpp
 *				icuext/ustdio.cpp
 *				icuext/ustring.cpp
 *				icuext/utf.cpp
 *				icuext/utf8str.cpp
 *				icuext/xfacade.cpp
 *				ihash/ihash.cpp
 *				interval/fsi.cpp
 *				libm/cmath1.cpp
 *				libm/double_scalar.cpp
 *				libm/double_vector.cpp
 *				libm/emath.cpp
 *				libm/fdlibm.cpp
 *				libm/libm_ext.cpp
 *				libm/remmod.cpp
 *				libm/v4rands.cpp
 *				libm/v5rands.cpp
 *				linebuf/linebuf.cpp
 *				mem/memory_context.cpp
 *				memmgr/freestore.cpp
 *				memmgr/mem32.cpp
 *				memmgr/mem32aligned.cpp
 *				memmgr/memalloc.cpp
 *				memmgr/memcache.cpp
 *				memmgr/memcount.cpp
 *				memmgr/memdebug.cpp
 *				memmgr/memutil.cpp
 *				memmgr/mmm_lexer.cpp
 *				msg/message_context.cpp
 *				nh/namehash.cpp
 *				nh/symtab.cpp
 *				parsetools/qs_tokenizer.cpp
 *				platform/unix.cpp
 *				profile/profile.cpp
 *				sort/qsort.cpp
 *				strbuf/string_buffer.cpp
 *				threads/atomic.cpp
 *				threads/mwbarrier.cpp
 *				threads/mwcondition.cpp
 *				threads/mwcountedbody.cpp
 *				threads/mwcountedpointer.cpp
 *				threads/mwevent.cpp
 *				threads/mwmonitor.cpp
 *				threads/mwmutexlock.cpp
 *				threads/mwobjmgr.cpp
 *				threads/mwpointer.cpp
 *				threads/mwrcrsvmtx.cpp
 *				threads/mwsemaphore.cpp
 *				threads/mwsingleton.cpp
 *				threads/mwthread.cpp
 *				threads/ut_thread.cpp
 *				tse/tse.cpp
 *				warn/warning_context.cpp
 *				warn/warnmgr.cpp
 */

#ifndef mwutil_h
#define mwutil_h


/*
 * Copyright 1984-2003 The MathWorks, Inc.
 * All Rights Reserved.
 */



/* Copyright 2003 The MathWorks, Inc. */

/*
 * Prevent g++ from making copies of vtable and typeinfo data
 * in every compilation unit.  By allowing for only one, we can
 * save space and prevent some situations where the linker fails
 * to coalesce them properly into a single entry.
 *
 * References:
 *    http://gcc.gnu.org/onlinedocs/gcc/Vague-Linkage.html#Vague%20Linkage
 *    http://gcc.gnu.org/onlinedocs/gcc/C---Interface.html
 */

#ifdef __cplusplus
#  ifdef __linux__
#    pragma interface
#  endif
#endif



/* $Revision: 1.16.4.3 $ */

#ifndef msg_typedefs_h
#define msg_typedefs_h

#ifdef __cplusplus
    extern "C" {
#endif

typedef int (*fn_puts)(const char *s, void *x);
typedef void (*fn_void)(void);

#define _element(X) X,

#define ut_define_module_mnemonics(m) \
  enum { m##_START=m##_INDEX<<16, m##_message_mnemonics(_element) m##_END}

#define _message_mnemonic(mnemonic, string) mnemonic,
#define _message_string(mnemonic, string) string,
#define _message_mnemonic_string(mnemonic, string) #mnemonic,

#define _concat(X, Y, Z) X##Y##Z

#define _define_module_tables_(language, table, m) \
static int const _concat(table,_codes_,m)[] \
  = {  _concat(m,language,messages)(_message_mnemonic) -1}; \
static _string const _concat(table,_strings_,m)[] \
  = {  _concat(m,language,messages)(_message_string) };

#define _define_module_code_strings_(language, table, m) \
static _string const _concat(table,_code_strings_,m)[] \
  = {  _concat(m,language,messages)(_message_mnemonic_string) }; \

#define _first(X, Y) X
#define _second(X, Y) Y

#define _define_module_tables(language_and_table, m) \
  _define_module_tables_(_first language_and_table, _second language_and_table, m)
#define _define_module_code_strings(language_and_table, m) \
  _define_module_code_strings_(_first language_and_table, _second language_and_table, m)

#define _table_element_(language, table, m) _concat(table,_strings_,m),

#define _table_element(language_and_table, m) \
  _table_element_(_first language_and_table, _second language_and_table, m)

#define _values_element_(language, table, m) _concat(table,_codes_,m),

#define _values_element(language_and_table, m) \
  _values_element_(_first language_and_table, _second language_and_table, m)

#define _values_string_element_(language, table, m) _concat(table,_code_strings_,m),

#define _values_string_element(language_and_table, m) \
  _values_string_element_(_first language_and_table, _second language_and_table, m)

#define _max_code_element(table, m) m##_END - m##_START - 1,

#define _component_element(table, m) #m


#define _module_element(Y,X) X##_INDEX,

#define ut_define_language_tables(language, table) \
  message_modules(_define_module_tables, (language, table)) \
  static int const table##_modules[] \
    = { message_modules(_module_element, table) -1 }; \
  static _int_table const table##_codes[] \
    = { message_modules(_values_element, (language, table)) }; \
  static _string_table const table##_strings[] \
    = { message_modules(_table_element, (language, table)) }; \
  static int const table##_code_count[] \
    = { message_modules(_max_code_element, table) }

#define ut_define_primary_messages(table) \
  message_module(_define_module_tables,(_,table)) \
  message_module(_define_module_code_strings,(_,table)) \
  static _primary_table const table \
    = { message_module(_max_code_element, table) \
        message_module(_module_element, table) \
        message_module(_values_element,(_,table)) \
        message_module(_values_string_element,(_,table)) \
        message_module(_table_element,(_,table)) \
        message_module(_component_element,(_,table)) }

#define ut_define_secondary_messages(language, table) \
  ut_define_language_tables(_##language##_, table); \
  static _language_table const table \
    = { table##_modules, \
        table##_codes, \
        table##_strings, \
        table##_code_count }

#define msg_INDEX 0
typedef const char *_string;
typedef _string const *_string_table;
typedef int const *_int_table;

typedef struct {
  int const *modules;
  _int_table const *codes;
  _string_table const *strings;
  _int_table code_count;
} _language_table;

typedef struct {
  int code_count;
  int module;
  _int_table codes;
  _string_table code_strings;
  _string_table strings;
  _string component_string;
} _primary_table;

typedef const _language_table *language_table;
typedef const _primary_table *primary_table;

#include <stddef.h>  /* This has size_t */
#include <stdio.h>   /* required for FILE */
#include <stdarg.h>  /* required for va_list, etc. */

/*
 * _hole_type enumerator identifies the hole type (%s and %U)
 */
typedef enum {
    STANDARD_HOLE_TYPE,          /* ID for the standard hole types */
    STRING_HOLE_TYPE,            /* ID for %s string holes */
    FUNCTION_HOLE_TYPE           /* ID for %U holes */
} _hole_type;

/*
 * _hole_seen enumerator identifes the 'seen' status of a hole
 */
typedef enum {
    HOLE_NOT_SEEN,
    HOLE_SEEN
} _hole_seen;

/*
 * _hole_info - information associated with a hole - char * for a
 * string hole, a va_list for a function hole
 */
typedef struct __hole_info {
    _hole_type   hole_type;      /* the type of this hole */
    union {
	/*
	 * fields used only when adding secondary strings
	 */
        _hole_seen hole_seen;    /* seen status, used to mark this hole as visited */
	
	/*
	 * fields used only when processing messages
	 */
	char    *hole_string;    /* string for %s fields */
	va_list  hole_ap;        /* arglist for %U fields */
    } hole;
} _hole_info;

typedef struct _message_context {
  int highest_module;          /* The maximum used module index for the items in the strings_list */
  int max_module;              /* The current allocation for items in the strings_list */
  int *code_count;
  int *ref_count;
  _string_table *code_strings; /* table with mneumonic code strings */
  _string * component_string;  /* name of component as a string */
  int current_language;        /* The currently active language index */
  int max_holes;
  int max_specification;
  int max_hole_text;
  char *specification;         /* specifications for non-%s fields */
  _hole_info *hole_infos;      /* information for hole fields */
  char *hole_text;             /* text for non-%s fields */
  int secondary_count;
  const char **keys;
                               /* The 0 index is the primary table,
                                * 1..secondary_count are for secondary languages
                                */
  _string_table **strings_list;
} _message_context, *message_context;

typedef unsigned long message_code;

/* function types */
typedef void *(*fn_malloc)(size_t);
typedef void *(*fn_realloc)(void *p, size_t);
typedef void (*fn_free)(void *p);

/*
 * This is the type of a functional argument to printm.
 * Its job is to "print" a string of n characters (in practice,
 * either to a file or to message buffer).
 * Characters to print _may_ include null bytes!
 */
typedef
int (*fn_putsn)(  /* Returns number of characters printed >= 0, else some error */
  void *x,        /* "Destination" info, e.g., FILE *, or &buffer */
  const char *s,  /* Source string (ptr to chars to print) */ 
  int n           /* Number of chars to print from s */
  );
/*
 * This is the type of a function that asks whether a putsn is "hot",
 * i.e., whether it is capable of handling hot-links to files.
 * The x argument is the same as the x argument to a fn_putsn.
 */
typedef
bool (*fn_is_hot)(
  void *x
  );

/*
 * typedef for the custom format specifier formatting function
 */
typedef
int (*fn_fmtfcn)(      /* returns the number of chars putsn'd after processing*/
  fn_putsn putsn,
  void *x,             /* destination info, e.g., FILE *, or &buffer */
  va_list *ap);        /* var args list to custom format specifier, on return
                          this is advanced past the custom format varargs */

/*
 * Below are a typedef and a function conforming to the fn_puts typedef that 
 * in turn calls a fn_putsn function, stored in the putsn_to_puts_args structure.
 */
typedef struct _putsn_to_puts_args
{
  fn_putsn putsn;
  void *   x;
} _putsn_to_puts_args, * putsn_to_puts_args;

typedef struct _puts_to_putsn_args
{
  fn_puts puts;
  void *   x;
} _puts_to_putsn_args, * puts_to_putsn_args;


typedef void (*fn_handler)( void *x, message_code code, ... );

#ifdef __cplusplus
    }	/* extern "C" */
#endif

#endif /* msg_typedefs_h */


/* $Revision: 1.3.6.4 $ */

#ifndef exception_typedefs_h
#define exception_typedefs_h


/*
 * setjmp/longjmp macros: To set a longjmp target for a body of code use the
 * BEGIN_SETJMP macro, code following this macro is always executed.  Use the
 * ELSE_SETJMP macro to bound the always executed code and start the code
 * that will be executed only in the event of a longjmp.  Use the END_SETJMP
 * to finish off the whole thing.  
 *
 *	BEGIN_SETJMP
 *
 *	code that is always executed
 *
 *	ELSE_SETJMP
 *
 *	code that is only executed if there is a longjump
 *
 *	END_SETJMP
 */
#ifdef __cplusplus
    extern "C" {
#endif

#include <setjmp.h>
#include <string.h>

extern void utResetFPU(void);

#ifdef UNIX
/*
 * Save signal masks as part of our context
 */
typedef sigjmp_buf ut_jmp_buf;
#define ut_setjmp(env) sigsetjmp(env,1)
#define ut_longjmp(env,val) (utResetFPU(), siglongjmp(env,val))

#else
/*
 * Plain vanilla setjmp
 */
typedef jmp_buf ut_jmp_buf;
#define ut_setjmp(env) setjmp(env)
#define ut_longjmp(env,val) (utResetFPU(), longjmp(env,val))
#endif

#define USING_CPP_EXCEPTIONS   /* uncomment to enable exception handleing*/ 

#ifdef __cplusplus
    }	/* extern "C" */
#endif

#if  defined(__cplusplus)
// Use C++ exception handling
// Any changes to these will require parallel changes to the transitional macros below
#define		BEGIN_SETJMP                                             \
                {utCleanupControl cbuf;                                  \
                sigset_t SavedSignalState;                               \
                utSaveSignals(&SavedSignalState);                        \
                 try {
                    
#define		ELSE_SETJMP	} catch (utException &E) {               \
                (void)E;     /*prevent E is unused warning*/	         \
                utRestoreSignals(&SavedSignalState);
                
#define		END_SETJMP   }   }

#ifdef UNIX
#define		BEGIN_SEGV_SETJMP                                             \
{               utCleanupControl cbuf;                                     \
                sigset_t SavedSignalState;                                  \
                utSaveSignals(&SavedSignalState);                           \
                ut_jmp_buf	local_copy;                                 \
                try {                                                       \
	            (void)memcpy(&local_copy, utGetSetjmpData(), sizeof(ut_jmp_buf)); \
  	            if (!ut_setjmp(*utGetSetjmpData())) {
                    
#define		ELSE_SEGV_SETJMP                                            \
                } else {ut_error(utGetErrorContext(), ERR_SIGNAL_INTERRUPT);}\
                    } catch (utException &E) {               \
                (void)E;     /*prevent E is unused warning*/	         \
                utRestoreSignals(&SavedSignalState);
                
#define		END_SEGV_SETJMP                                             \
                }  	                                                    \
                (void)memcpy(utGetSetjmpData(), &local_copy, sizeof(ut_jmp_buf));  \
                }  
/* This routine is used only from c++ code with exceptions on
*  code inside the perens can segv or ctrl-c and the longjump will be caught
*  and an exception will be thrown */   
#define     THROW_SEGV_LONGJMP(_X)                                        \
{        volatile bool error=false;                                       \
        ut_jmp_buf      local_copy;                                       \
        utCleanupControl cbuf;                                            \
        (void)memcpy(&local_copy, utGetSetjmpData(), sizeof(ut_jmp_buf)); \
        if (!ut_setjmp(*utGetSetjmpData())) {                             \
            _X;                                                           \
        } else {                                                          \
            error=true;                                                   \
        }                                                                 \
        (void)memcpy(utGetSetjmpData(), &local_copy, sizeof(ut_jmp_buf)); \
        if (error) ut_error(utGetErrorContext(), ERR_SIGNAL_INTERRUPT);   \
        }
        
#else  // Not unix (windows)
#define         THROW_SEGV_LONGJMP(_X)          (_X)
#define		BEGIN_SEGV_SETJMP	BEGIN_SETJMP
#define		ELSE_SEGV_SETJMP	ELSE_SETJMP
#define		END_SEGV_SETJMP 	END_SETJMP
#endif

/*     Transitional macros for use while changeing to full cpp implementation
*      BEGIN_TRY_CONTEXT and END_TRY_CONTEXT must be used together and must not be mixed with
*      BEGIN or END SETJMP.  However ELSE_SETJMP may still be used if it is not used then CATCH_CLEANUP 
*      will probably be needed.  i.e.:
*      CATCH_CLEANUP must be used in any catch block where signal state must be restored
*      it probably should not be used outside of the try/catch block and will 
*      not work outside of the TRY_CONTEXT

BEGIN_TRY_CONTEXT
...
try {
  ...
ELSE_SETJMP
  ...
  throw // if desired
} // end of else
...
END_TRY_CONTEXT

******************

Or 
BEGIN_TRY_CONTEXT
...
try {
  ...
} catch (utException &E) {
  ...
  throw // if desired.  CATCH_CLEANUP is probably unneeded becuse next catch will cleanup...
  CATCH_CLEANUP;
} // end of else
...
END_TRY_CONTEXT

  

*/
         
#define         BEGIN_TRY_CONTEXT                                        \
                {utCleanupControl cbuf;                                  \
                sigset_t SavedSignalState;                               \
                utSaveSignals(&SavedSignalState);  

#define         END_TRY_CONTEXT      }                                   
                                      
//  Add this line in each catch clause that is used instead of ELSE_SETJMP
#define         CATCH_CLEANUP   utRestoreSignals(&SavedSignalState);         



#else /* Not using CPP exceptions */
#if 0 /* not quite ready two files need chageing in compiler */
#define		BEGIN_SETJMP                                              \
#error Try-Catch blocks require C++  
#define		ELSE_SETJMP                                               \
#error Try-Catch blocks require C++  
#define		END_SETJMP                                                \
#error Try-Catch blocks require C++  
#else
#define		BEGIN_SETJMP                                              \
{                                                                         \
	ut_jmp_buf	local_copy;                                       \
        ExceptionFcn    local_fcn;                                        \
        local_fcn = utSetExceptionFcn(utLongjmpFcn);                      \
                                                                          \
        ut_prevent_further_cleanup( utGetErrorContext() )                 \
	(void)memcpy(&local_copy, utGetSetjmpData(), sizeof(ut_jmp_buf)); \
                                                                          \
	if (!ut_setjmp(*utGetSetjmpData())) {

#define		ELSE_SETJMP \
			    \
	} else {

#define		END_SETJMP                                                \
                                                                          \
	}                                                                 \
        utSetExceptionFcn(local_fcn);                                     \
        ut_allow_further_cleanup( utGetErrorContext() )                   \
	(void)memcpy(utGetSetjmpData(), &local_copy, sizeof(ut_jmp_buf)); \
}
/* NEEDED for bridging untill exceptions are on on all platforms */
#define         THROW_SEGV_LONGJMP(_X)          (_X)
#define		BEGIN_SEGV_SETJMP	BEGIN_SETJMP
#define		ELSE_SEGV_SETJMP	ELSE_SETJMP
#define		END_SEGV_SETJMP 	END_SETJMP
#endif
#endif  /* exception handling */

#define		BEGIN_SETJUMP	BEGIN_SETJMP
#define		ELSE_SETJUMP	ELSE_SETJMP
#define		END_SETJUMP	END_SETJMP

#endif /* exception_typedefs_h */



/* $Revision: 1.17.4.5 $ */

#ifndef err_typedefs_h
#define err_typedefs_h

#ifndef exception_typedefs_h
#include "exception_typedefs.h"
#endif

#define err_INDEX 1
#define ERR_NO_ERROR 0

/* types */
#ifdef __cplusplus
extern "C" {
#endif
typedef void (*fn_protectv)(void *);
typedef void (*fn_protectxv)( void *, void *);
#ifdef __cplusplus
}
#endif

#define ut_declare_protect_function(f, t) void (*f)(t)
#define ut_declare_protectx_function(f, t1, t2) void (*f)(t1, t2)

#define _protect_list_common_fields(t) \
  struct _generic_protect_list *next; /* should come first for more efficient reference */ \
  t *p;

#define _protect_list_common( t, t1)  { \
  _protect_list_common_fields(t) \
  ut_declare_protect_function(f, t1); \
}

typedef struct _generic_protect_list _protect_list_common( void *, void *)
  *generic_protect_list;

#define _protect_list(t, t1) struct _protect_list_common( t, t1)

/* The f field is deliberately put in a different position in the the following type,
   to maximize catastrophe if the wrong type is used.  */
#define _protectx_list(t, t1, t2) struct { \
  _protect_list_common_fields(t) \
  t1 x; /* the first argument to f */ \
  ut_declare_protectx_function(f, t1, t2); \
}

typedef _protectx_list(void *, void *, void *) *generic_protectx_list;

#ifdef __cplusplus
extern "C" {
#endif
typedef void (*fn_error_handler)(void *x, const char * id, int code);
#ifdef __cplusplus
}
#endif

typedef struct _error_context {
  generic_protect_list top; /* should come first for more efficient reference */
  struct _try_catch_list *try_catch_top;
  struct _try_catch_list *active_catch;
  message_context msg;
  fn_putsn putsn;
  void *x; /* the first argument to putsn and is_hot */
  fn_is_hot is_hot;
  fn_error_handler error_handler;
  void *xerr; /* The first argument to error_handler */
} _error_context, *error_context;

#ifdef __cplusplus
extern "C" {
#endif
typedef void (*try_function)(error_context err, void *p);
typedef int (*catch_function)(error_context err, void *p, message_code code, va_list ap);
typedef int (*catch_function_id)(error_context err, void *p, const char * id, 
                                 message_code code, va_list ap);
#ifdef __cplusplus
}
#endif

typedef struct _try_catch_list {
  struct _try_catch_list *next;
  generic_protect_list top;
  void *p;
  catch_function catch_fcn;
  catch_function_id catch_fcn_id;
  message_code code;
} _try_catch_list; 
typedef _try_catch_list *try_catch_list;

/* macros */

#define ut_errassertalways(err, condition) (condition) ? (void)0 : ut_fault(err, #condition, __FILE__, __LINE__) 

#ifndef NDEBUG
#define ut_assert_fault(err, condition) ut_fault(err, condition, __FILE__, __LINE__)
#define ut_errassert(err, condition) (condition) ? (void)0 : ut_assert_fault(err, #condition)
#define NNDEBUGC(X) X,
#define NNDEBUG(X) X
#define YNDEBUG(X)
#define YNNDEBUG(X) 
#else
#define ut_assert_fault(err, condition) ((void) err)
#define ut_errassert( err, condition ) ((void) err)
#define NNDEBUGC(X)
#define NNDEBUG(X)
#define YNDEBUG(X) X
#define YNNDEBUG(X) X, 
#endif


#if (defined(DEBUG) || (defined(DEBUG_ERROR_CONTEXT) && DEBUG_ERROR_CONTEXT != 0))
#undef DEBUG_ERROR_CONTEXT
#define DEBUG_ERROR_CONTEXT(X) X
#else
#undef DEBUG_ERROR_CONTEXT
#define DEBUG_ERROR_CONTEXT(X)
#endif

#define _protect_value_common(err, type, value, protectfn, _list, tag)   \
  typedef void (*ut_fn_protect_##tag)(type);                             \
  DEBUG_ERROR_CONTEXT(generic_protect_list _local_top##tag;)             \
  _list _error_context_link##tag;                                        \
  _error_context_link##tag.next = (err)->top;                            \
  _error_context_link##tag.p = value;                                    \
  ut_errassert(err, sizeof(type)==sizeof(void *));                       \
  _error_context_link##tag.f = protectfn;

#define _protect_common(err, type, name, value, protectfn, _list, tag)  \
  type name = value;                                                    \
  _protect_value_common(err, type, &name, protectfn, _list, tag)

#define LOCAL_TOP(tag) DEBUG_ERROR_CONTEXT(_local_top##tag =)

#define ut_protect(err, type, name, value, protectfn) {                                 \
  _protect_common(err, type, name, value, protectfn, _protect_list(type, type), name )  \
  (err)->top = LOCAL_TOP(name) (generic_protect_list)&_error_context_link##name;

#define ut_protectv(err, type, name, value, protectfn) {                                 \
  _protect_common(err, type, name, value, protectfn, _protect_list(type, void *), name ) \
  (err)->top = LOCAL_TOP(name) (generic_protect_list)&_error_context_link##name;

#define ut_protectx(err, type, name, value, protectfn, typex, protectx) {                  \
  _protect_common(err, type, name, value,                                                  \
                  protectfn, _protectx_list(type, typex, type),name)                       \
  _error_context_link##name.x = protectx;                                                  \
  (err)->top                                                                               \
    = LOCAL_TOP(name) (generic_protect_list)((unsigned long)&_error_context_link##name | 1);

#define ut_protectxv(err, type, name, value, protectfn, typex, protectx) {              \
  _protect_common(err, type, name, value,                                               \
                  protectfn, _protectx_list(type, typex, void *), name)                 \
  _error_context_link##name.x = protectx;                                               \
  (err)->top = LOCAL_TOP(name)                                                          \
                 (generic_protect_list)((unsigned long)&_error_context_link##name | 1);

#define ut_protect_value(err, type, value, protectfn) {                                    \
  _protect_value_common(err, type, &(value), protectfn, _protect_list(type, type), value ) \
  (err)->top = LOCAL_TOP(value) (generic_protect_list)&_error_context_link##value;

#define ut_protectv_value(err, type, value, protectfn) {                                \
  _protect_value_common(err, type, &(value),                                            \
                        protectfn, _protect_list(type, void *), value )                 \
  (err)->top = LOCAL_TOP(value) (generic_protect_list)&_error_context_link##value;

#define ut_protectx_value(err, type, value, protectfn, typex, protectx) {                \
  _protect_value_common(err, type, &(value), protectfn,                                  \
                        _protectx_list(type, typex, type), value)                        \
  _error_context_link##value.x = protectx;                                               \
  (err)->top = LOCAL_TOP(value)                                                          \
                 (generic_protect_list)((unsigned long)&_error_context_link##value | 1);

#define ut_protectxv_value(err, type, value, protectfn, typex, protectx) {               \
  _protect_value_common(err, type, &(value),                                             \
                        protectfn, _protectx_list(type, typex, void *), value)           \
  _error_context_link##value.x = protectx;                                               \
  (err)->top = LOCAL_TOP(value)                                                          \
                 (generic_protect_list)((unsigned long)&_error_context_link##value | 1);

#define ut_protect_value_tag(err, type, value, protectfn, tag) {                         \
  _protect_value_common(err, type, &(value), protectfn, _protect_list(type, type), tag ) \
 (err)->top = LOCAL_TOP(tag) (generic_protect_list)&_error_context_link##tag;

#define ut_protectv_value_tag(err, type, value, protectfn, tag) {                          \
  _protect_value_common(err, type, &(value), protectfn, _protect_list(type, void *), tag ) \
  (err)->top = LOCAL_TOP(tag) (generic_protect_list)&_error_context_link##tag;

#define ut_protectx_value_tag(err, type, value, protectfn, typex, protectx, tag) {        \
  _protect_value_common(err, type, &(value),                                              \
                        protectfn, _protectx_list(type, typex, type), tag)                \
  _error_context_link##tag.x = protectx;                                                  \
 (err)->top                                                                               \
   = LOCAL_TOP(tag) (generic_protect_list)((unsigned long)&_error_context_link##tag | 1);

#define ut_protectxv_value_tag(err, type, value, protectfn, typex, protectx, tag) {       \
 _protect_value_common(err, type, &(value),                                               \
                       protectfn, _protectx_list(type, typex, void *), tag)               \
 _error_context_link##tag.x = protectx;                                                   \
 (err)->top                                                                               \
   = LOCAL_TOP(tag) (generic_protect_list)((unsigned long)&_error_context_link##tag | 1);

#define ut_cast_to_generic_protectx_list(p) (generic_protectx_list)((unsigned long)(p) ^ 1)

#define ut_preserve(err,tag) (err)->top = (err)->top->next
#define ut_destroy(err,tag) { \
  register error_context err_ = err; \
  err_->top->f(*(err_->top->p)); \
  ut_preserve(err_,tag); \
  } (void)0
#define ut_preservex(err,tag) (err)->top = (ut_cast_to_generic_protectx_list((err)->top))->next
#define ut_destroyx(err,tag) { \
  register generic_protectx_list px = ut_cast_to_generic_protectx_list((err)->top); \
  (err)->top = px->next; \
  px->f(px->x, *(px->p)); \
  } (void)0

#define _fast_ut_preserve(err,tag)
#define _fast_ut_destroy(err,tag) _error_context_link##tag.f(*_error_context_link##tag.p);
#define _fast_ut_preservex(err,tag)
#define _fast_ut_destroyx(err,tag) \
  _error_context_link##tag.f(_error_context_link##tag.x, *(_error_context_link##tag.p));
#define _incorrect_magic(err,tag) \
  if (_local_top##tag != (err)->top) { \
    (err)->top = _local_top##tag; \
    ut_error(err, INCORRECT_MAGIC, __FILE__, __LINE__); \
  }

#define ut_unprotect_unreachable } 

#define ut_unprotect(err, tag, magic) \
  DEBUG_ERROR_CONTEXT(_incorrect_magic(err,tag)) \
  (err)->top = _error_context_link##tag.next; \
  _fast_##magic(err,tag) \
}

#define ut_unprotect_and_return(err, tag, magic, expr) \
  DEBUG_ERROR_CONTEXT(_incorrect_magic(err,tag)) \
  (err)->top = _error_context_link##tag.next; \
  _fast_##magic(err,tag) \
  return expr; \
}

#define ut_protect_f _error_context_link.f

#define ut_prevent_further_cleanup(err) { \
  _try_catch_list _link; \
  ut_prevent_further_cleanup_fcn(err, &_link);

#define ut_allow_further_cleanup(err) \
  ut_allow_further_cleanup_fcn(err, &_link); \
}
 
#endif /* err_typedefs_h */

#ifdef __cplusplus
extern "C" {
#endif
/*
 * load library into memory
 */
extern void *utLoadLibrary(
    const char	*fullname,	/* _full_ library path name */
    int		*errorStatus	/* return variable for error code */
    );
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
/*
 * lookup symbol in a loaded library
 */
extern void *utFindSymbolInLibrary(
    void        *handle,	/* handle returned by utLoadLibrary */
    const char  *symbol         /* symbol name to look up */
    );
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
/*
 * unload a previously loaded library
 */
extern int utUnloadLibrary(
    void        *handle		/* handle returned by utLoadLibrary */
    );
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
/*
 * Retrieve last error in dynamic loader utility routines
 */
extern const char *utLastLibraryError(void);
#ifdef __cplusplus
}
#endif


#include <limits.h>

typedef int FP_NumericFormat;


typedef int FP_ByteOrder;
#define FLITTLE_ENDIAN 0
#define FBIG_ENDIAN    1

#define ut_GET_LO(l,x) \
{                      \
    ieee_double_T d_u; \
    d_u.value = (x);   \
    (l) = d_u.words.lw;\
}

#define ut_SET_LO(x,l) \
{                      \
    ieee_double_T d_u; \
    d_u.value = (x);   \
    d_u.words.lw = (l);\
    (x) = d_u.value;   \
}

#define ut_SET_LOp(p,l)\
{                      \
    ieee_double_T d_u; \
    d_u.value = *(p);  \
    d_u.words.lw = (l);\
    *(p) = d_u.value;  \
}

#define ut_GET_HI(h,x) \
{                      \
    ieee_double_T d_u; \
    d_u.value = (x);   \
    (h) = d_u.words.hw;\
}

#define ut_SET_HI(x,h) \
{                      \
    ieee_double_T d_u; \
    d_u.value = (x);   \
    d_u.words.hw = (h);\
    (x) = d_u.value;   \
}

#define ut_SET_HIp(p,h)\
{                      \
    ieee_double_T d_u; \
    d_u.value = *(p);  \
    d_u.words.hw = (h);\
    *(p) = d_u.value;  \
}

#define ut_GET_BOTH(h,l,x)\
{                         \
    ieee_double_T d_u;    \
    d_u.value = (x);      \
    (h) = d_u.words.hw;   \
    (l) = d_u.words.lw;   \
}

#define ut_SET_BOTH(x,h,l)\
{                         \
    ieee_double_T d_u;    \
    d_u.words.hw = (h);   \
    d_u.words.lw = (l);   \
    (x) = d_u.value;      \
}


/* Macros to implement relational floating point comparisons
 * with zeros when the comparee might be NaN.
 * This is a work around for a PC compiler bug in both Microsoft VC++
 * and WATCOM. 
 * -- CBM, 9/22/97.
 *
 * The comparsion values on the PC when the comparee is a NaN are:
 * 
 *	1. NaN < 0  <== true
 *      2. NaN <= 0 <== true
 *      3. NaN > 0  <== false
 *      4. NaN >= 0 <== false
 *      5. NaN == 0 <== true
 *      6. NaN != 0 <== false
 * 
 * When comparing with NaNs, except the != operation all others should 
 * be false. However, this is not the case on the PC. So we have the 
 * following macros that work around this problem for cases 1,2,5 and 6.
 * -- NBM 9/26/97
 */

/*
 * MSVC++ 7.0 now complies with IEEE rules for comparisons with NaN.
 */
#if defined(MSWIND) && (_MSC_VER < 1300)
#define utNEZero(x) (((x) < 0.0) || ((x) > 0.0))
#define utEQZero(x) (((x) >= 0.0) && ((x) <= 0.0))
#define utLTZero(x) (((x) < 0.0) && !utIsNaN(x))
#define utLEZero(x) (((x) <= 0.0) && !utIsNaN(x))

#else
#define utNEZero(x) ((x) != 0.0)
#define utEQZero(x) ((x) == 0.0)
#define utLTZero(x) ((x) < 0.0)
#define utLEZero(x) ((x) <= 0.0)
#endif

/* Since the > and >= are correct for the NaN case it is
 * outside the ifdef code. Cleve and I decided to add them
 * to maintain the consistency of syntax.
 */
#define utGTZero(x) ((x) > 0.0)
#define utGEZero(x) ((x) >= 0.0)

#ifdef __cplusplus
extern "C" {
#endif
/*
 * Predicate to determine whether a double is an int.
 * -0 is not considered an int, because converting it back
 * does not yield the same double.
 */
extern bool utDblIsInt(double x);
#ifdef __cplusplus
}
#endif




/*
 * Use unique NaNs as flags for special values
 * These values should never be generated by Matlab as valid NaNs.
 *
 * The low-order word is all zeros.
 */

#define UT_SPECIAL_NAN 0x7ff5c5c0

#define UT_NAN_NEVER_TOUCHED (UT_SPECIAL_NAN + 0x1)
#define UT_NAN_FORLOOP_EMPTY (UT_SPECIAL_NAN + 0x2)


#define UT_SET_NAN_VALUE(lval, jqnan) ut_SET_BOTH(lval, jqnan, 0)

/*
 * since the x86 fpu can change the leading mastissa bit on QNaNs, we check for
 * equality with and without the bit set.
 */
#define UT_QNAN_BITMASK 0x00080000
#define UT_IS_NAN_VALUE(val, jqnan)                                                                     \
    (*(((int*)&(val))+(CPU_NUM_FORMAT==FIEEE_BE)) == 0x0 &&                                             \
     (*(((int*)&(val))+(CPU_NUM_FORMAT==FIEEE_LE))|UT_QNAN_BITMASK) == ((jqnan)|UT_QNAN_BITMASK))



#ifdef __cplusplus
    extern "C" {
#endif

#ifdef __cplusplus
    }	/* extern "C" */
#endif


# define utAssert(test)              /* do nothing */
# define utAssertStr(test, message)  /* do nothing */
# define utAssertAlways(message)     /* do nothing */


#include "tmwtypes.h"


#ifndef CPU_NUM_FORMAT
#if defined(_M_IX86) || defined(_M_AMD64) || \
    defined(__i386__) || defined(__x86_64__) || defined(__ia64__)
#define CPU_NUM_FORMAT FIEEE_LE
#else
#define CPU_NUM_FORMAT FIEEE_BE
#endif /* if defined */
#endif /* if ndef CPU */

#define FIEEE_LE 0
#define FIEEE_BE 1
#define FVAXD    2
#define FVAXG    3
#define FCRAY    4
#define UNKNOWN  5



#define UTIL_IEEE_FLOAT_EXISTS

#if CPU_NUM_FORMAT==FIEEE_LE
/* Little-endian */
typedef union 
{
    double value;
    struct { uint32_T lw;
             uint32_T hw;
           } words;
} ieee_double_T;

#if 0 /* make PUBLIC later when name conflicts in Amath go away */
/* Little-endian */
typedef union 
{
    float value;
    struct { uint16_T lw;
             uint16_T hw;
           } words;
} ieee_float_T;
#endif

#elif CPU_NUM_FORMAT==FIEEE_BE
/* Big-endian */
typedef union 
{
    double value;
    struct { uint32_T hw;
	     uint32_T lw;
           } words;
} ieee_double_T;

#if 0 /* make PUBLIC later when name conflicts in Amath go away */
/* Big-endian */
typedef union 
{
    float value;
    struct { uint16_T hw;
	     uint16_T lw;
           } words;
} ieee_float_T;
#endif

#else
#error CPU_NUM_FORMAT must be FIEEE_LE or FIEEE_BE
#endif

#ifdef __cplusplus
extern "C" {
#endif
/*
 * Function that returns IEEE infinity
 */
extern double utGetInf(void);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
/*
 * Function that returns IEEE -infinity
 */
extern double utGetMinusInf(void);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
/*
 * Function that returns IEEE nan inderterminate
 */
extern double utGetNaN(void);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
/*
 * Function that returns Eps value
 */
extern double utGetEps(void);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
/*
 * Function that returns PI value
 */
extern double utGetPI(void);
#ifdef __cplusplus
}
#endif


#ifndef __cplusplus
/*
 * Is this double a NaN? function
 */
bool utIsNaN(double a);
#endif /* __cplusplus */


#ifndef __cplusplus
/*
 * Is this double infinite? function
 */
bool utIsInf(double a);
#endif /* __cplusplus */


#ifndef __cplusplus
/*
 * Is this double plus infinity? function
 */
bool utIsPlusInf(double a);
#endif /* __cplusplus */


#ifndef __cplusplus
/*
 * Is this double minus infinity? function
 */
bool utIsMinusInf(double a);
#endif /* __cplusplus */


#ifdef __cplusplus
/*
 * Query Functions
 */

/*
 * Is this double a NaN? function
 */
inline bool utIsNaN(double a)
{ /* Begin utIsNaN */
#if (defined(_MSC_VER) && (_MSC_VER < 1300)) || defined(__BORLANDC__)
    ieee_double_T tem;
    tem.value = a;
    return (bool)((((tem.words.hw & 0x7fffffff) == 0x7ff00000) && (tem.words.lw != 0)) 
              || ((tem.words.hw == 0xfff80000) && (tem.words.lw == 0)));
#else 
    return (bool)((a) != (a));
#endif /* if MSC_VER */
} /* End utIsNaN */

/*
 * Is this double infinite? function
 */
inline bool utIsInf(double a)
{ /* Begin utIsInf */
    ieee_double_T tem;
    tem.value = a;
    return (bool) (((tem.words.hw & 0x7fffffff) == 0x7ff00000) &&\
                   ( tem.words.lw == 0));
}/* End utIsInf */

/*
 * Is this double plus infinity? function
 */
inline bool utIsPlusInf(double a)
{ /* Begin utIsPlusInf */  
    ieee_double_T tem;
    tem.value = a;
    return (bool) ((tem.words.hw == 0x7ff00000) && ( tem.words.lw == 0));
}/* End utIsPlusInf */

/*
 * Is this double minus infinity? function
 */
inline bool utIsMinusInf(double a)
{  /* Begin utIsMinusInf */ 
    ieee_double_T tem;
    tem.value = a;
    return (bool) ((tem.words.hw == 0xfff00000) && ( tem.words.lw == 0));
   
} /* End utIsMinusInf */
#endif /*End __cplusplus*/


#if defined(_MSC_VER) && defined(_M_IX86)
#pragma warning( disable : 4514 ) /*  unreferenced inline function has been removed */
#pragma warning( disable : 4035 ) /*  no return value for utIsNaN */
#if _MSC_VER > 1100
__forceinline bool utIsNaNW(double a) 
{
    __asm fld a
    __asm fcomp st(0)
    __asm fnstsw  ax
    __asm and eax,0x100
    __asm shr eax,8
}

__forceinline bool utIsInfW(double a) 
{
    __asm fld a
    __asm fxam
    __asm fnstsw  ax
    __asm fstp st(0)
    __asm and eax,0x500
    __asm shr eax,2
    __asm shr al,6
    __asm and al,ah
}
#else 
__inline bool utIsNaNW(double a) 
{
    __asm fld a
    __asm fcomp st(0)
    __asm fnstsw  ax
    __asm and eax,0x100
    __asm shr eax,8
}

__inline bool utIsInfW(double a) 
{
    __asm fld a
    __asm fxam
    __asm fnstsw  ax
    __asm fstp st(0)
    __asm and eax,0x500
    __asm shr eax,2
    __asm shr al,6
    __asm and al,ah
}
#endif /* if > 1000 */
#define utIsNaN(a) utIsNaNW(a)
#define utIsInf(a) utIsInfW(a)
#endif /* End _MSV_VER */
/* floor(a) */
#define utDoubleScalarFloor(a)  utFdlibm_floor(a)

#ifdef __cplusplus
extern "C" {
#endif
/* round(a) */
extern double utDoubleScalarRound(double a);
#ifdef __cplusplus
}
#endif


#if !defined(_MSC_VER) && !defined(__BORLANDC__)

#define utIsNaN(a)	((bool)((a) != (a)))

#endif /* _MSC_VER */

/* fix(a) */ 
#define utDoubleScalarFix(a) ((a) < 0.0 ? utFdlibm_ceil(a) : utFdlibm_floor(a))

/* a + b */
#define utDoubleScalarPlus(a,b)	((a) + (b))

/* a - b */
#define utDoubleScalarMinus(a,b) ((a) - (b))

/* -a  */
#define utDoubleScalarUminus(a) (-(a))

/* +a */
#define utDoubleScalarUplus(a)	 (a)

/* a * b */
#define utDoubleScalarTimes(a,b) ((a) * (b))

/* a/b and a./b */
/* A warning 'Divide by zero' should be issued by users for b = 0 */
#define utDoubleScalarRdivide(a,b)  ((a)/(b))    

/* a\b and a.\b */
/* A warning 'Divide by zero' should be issued by users for a = 0 */
#define utDoubleScalarLdivide(a,b)  ((b)/(a))

#if defined(_MSC_VER) && (_MSC_VER < 1300)

/* a < b */                 
#define utDoubleScalarLt(a,b) (utIsNaN(a) || utIsNaN(b) ? false : ((a) < (b) ))

/* a > b */
#define utDoubleScalarGt(a,b) (utIsNaN(a) || utIsNaN(b) ? false : ((a) > (b) ))

/* a <= b */
#define utDoubleScalarLe(a,b) (utIsNaN(a) || utIsNaN(b) ? false : ((a) <= (b)))

/* a >= b */
#define utDoubleScalarGe(a,b) (utIsNaN(a) || utIsNaN(b) ? false : ((a) >= (b)))

/* eq(a,b) and a == b */
#define utDoubleScalarEq(a,b) (utIsNaN(a) || utIsNaN(b) ? false : ((a) == (b)))

/* a ~= b */
#define utDoubleScalarNe(a,b) (utIsNaN(a) || utIsNaN(b) ? true : ((a) != (b) ))

#else /* !defined(_MSC_VER) || (_MSC_VER >= 1300) */

/* a < b */ 
#define utDoubleScalarLt(a,b) ((a) < (b) )
			       
/* a > b */
#define utDoubleScalarGt(a,b) ((a) > (b) )
	               
/* a <= b */
#define utDoubleScalarLe(a,b) ((a) <= (b) )
		       
/* a >= b */
#define utDoubleScalarGe(a,b) ((a) >= (b) )
		       
/* a = b */
#define utDoubleScalarEq(a,b) ((a) == (b) )
		      
/* a ~= b */
#define utDoubleScalarNe(a,b) ((a) != (b) )                 

#endif /* !defined(_MSC_VER) || (_MSC_VER >= 1300) */

/* a | b  */
/* An error message should be issued by users for a or b = NaN */
#define utDoubleScalarOr(a,b) ((a) != 0.0 || (b) != 0.0)

/*  ~a  */
/* An error message should be issued by users for a or b = NaN */
#define utDoubleScalarNot(a) ((a) == 0.0)
 
/* a' */		
#define utDoubleScalarCtranspose(a)  (a)

/* a.' */			
#define utDoubleScalarTranspose(a)  (a)

/* abs(a) */	
#define utDoubleScalarAbs(a)  fabs(a)
	
/* acos(a) */
#define utDoubleScalarAcos(a)  utFdlibm_acos(a)

/* acosh(a) */
#define utDoubleScalarAcosh(a) utFdlibm_acosh(a)
	
/* acot(a) */
#define utDoubleScalarAcot(a)  utFdlibm_atan(1.0/(a))

/* ascs(a) */
#define utDoubleScalarAcsc(a)  utFdlibm_asin(1.0/(a))

/* ascsh(a) */
#define utDoubleScalarAcsch(a) utFdlibm_asinh(1.0/(a))

/* all(a) */
#define utDoubleScalarAll(a) (utIsNaN(a) || (a != 0.0))

/* a & b */
/*  An error message should be issued by users for a or b = NaN */
#define utDoubleScalarAnd(a,b) ((a) != 0.0 &&  (b) != 0.0)

/* any(a) */
#define utDoubleScalarAny(a) (utIsNaN(a) || (a != 0.0))

/* angle(a) */
#define utDoubleScalarAngle(a) utIsNaN(a)                                \
                                       ? utGetNaN()                      \
                                       : 0.0+utGetPI()*((a) < 0.0)
/* asec(a) */
#define utDoubleScalarAsec(a)  utFdlibm_acos(1.0/(a))

/* asech(a) */
#define utDoubleScalarAsech(a) utFdlibm_acosh(1.0/(a))

/* asin(a) */
#define utDoubleScalarAsin(a)  utFdlibm_asin(a)

/* asinh(a) */
#define utDoubleScalarAsinh(a) utFdlibm_asinh(a)

/* atan(a) */
#define utDoubleScalarAtan(a)  utFdlibm_atan(a)

/* atanh(a) */
#define utDoubleScalarAtanh(a) 	utFdlibm_atanh(a)

/* ceil(a) */
#define utDoubleScalarCeil(a)  utFdlibm_ceil(a)

/* cos(a) */
#define utDoubleScalarCos(a) utFdlibm_cos(a)

/* cosh(a) */
#define utDoubleScalarCosh(a) utFdlibm_cosh(a)

/* cot(a) */
/* A warning 'Divide by zero' should be issued by users for a = 0 */
#define utDoubleScalarCot(a) 1.0/utFdlibm_tan(a)
	
/* coth(a) */
/*A warning 'Divide by zero' should be issued by users for a = 0 */
#define utDoubleScalarCoth(a) 1.0/utFdlibm_tanh(a)
			
/* csc(a) */
/*A warning 'Divide by zero' should be issued by users for a = 0 */
#define utDoubleScalarCsc(a) 1.0/utFdlibm_sin(a)

/* csch(a) */
/*A warning 'Divide by zero' should be issued by users for a = 0 */
#define utDoubleScalarCsch(a) 1.0/utFdlibm_sinh(a)

/* dot(a,b) */
#define utDoubleScalarDot(a,b) ((a)*(b))

/* double(a) */
#define utDoubleScalarDouble(a) (a)

/* exp(a) */	
#define utDoubleScalarExp(a)  utFdlibm_exp(a)

/* full(a) */
#define utDoubleScalarFull(a)  (a)

/* imag(a) */
#define utDoubleScalarImag(a)  0.0

/* int8(a) */
#define utDoubleScalarInt8(a)  ( utIsNaN(a)                             \
                                         ? 0.0                          \
                                         : ( (a) > 127.                 \
                                              ? 127.                    \
                                              : ( (a) <= -128.          \
                                                   ? -128.              \
                                                   :  (char)(a))))

/* int16(a) */
#define utDoubleScalarInt16(a)  ( utIsNaN(a)                            \
                                          ? 0.0                         \
                                          : ( (a) > 32767.              \
                                               ?  32767.                \
                                               : ( (a) <= -32768.       \
                                                    ? -32768.           \
                                                    : (int)(a))))

/* int32(a) */
#define utDoubleScalarInt32(a)  ( utIsNaN(a)                            \
                                          ? 0.0                         \
                                          : ( (a) > 2147483647.         \
                                               ? 2147483647.            \
                                               : ( (a) <= -2147483648.  \
                                                    ? -2147483648.      \
                                                    :  (long)(a))))

/* isequal(a,b) */
#define utDoubleScalarIsequal(a,b)  (!utIsNaN(a) && !utIsNaN(b) && (a) == (b))

/* isempty(a) */
#define utDoubleScalarIsempty(a)  false

/* isfinite(a) */
#define utDoubleScalarIsfinite(a) (!( utIsInf(a) || utIsNaN(a) ))

/* is almost zero */
#define utDoubleScalarIsAlmostZero(a)                                   \
        (fabs((a) - utDoubleScalarRound(a)) <= utGetEps() * fabs(a))

/* islogical(a) */
#define utDoubleScalarIslogical(a)  false

/* ismember(a,b) */
#define utDoubleScalarIsmember(a,b) (!utIsNaN(a) && !utIsNaN(b) &&((a) == (b)))

/* isreal(a) */
#define utDoubleScalarIsreal(a)  true

/* issparse(a) */
#define utDoubleScalarIssparse(a) false

/* length(a) */
#define utDoubleScalarLength(a)  1

/* log */
/*A warning 'Log of zero' should be issued by users for a = 0 */
#define utDoubleScalarLog(a) utFdlibm_log(a)

/* log10 */
/*A warning 'Log of zero' should be issued by users for a = 0 */
#define utDoubleScalarLog10(a) utFdlibm_log10(a)

#ifdef __cplusplus
extern "C" {
#endif
/* atan2(a,b) */
extern double utDoubleScalarAtan2(double a, double b);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
/* log2 */
/*A warning 'Log of zero' should be issued by users for a = 0 */
extern double utDoubleScalarLog2(double a);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
/* max(a,b) */

/*
	Maximum between a and b
*/
extern double utDoubleScalarMax( double a, double b);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
/* min(a,b) */

/*
	Minimum between a and b
*/
extern double utDoubleScalarMin( double a,double b);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
/*
 * C = A.^p for real A and integer p.
 * Use element-by-element repeated squaring.
 * eg. a^13 = a^1 * a^4 * a^8
 * b must be <= UINT_MAX.
 */
extern double utDoubleScalarIntPower(double a, double b);
#ifdef __cplusplus
}
#endif


/* ndims(a) */
#define utDoubleScalarNdims(a)  2.0


#define utIsIntPower(b) ((int)(b) == (b) && fabs((double)b) <= 2.0)

#define utDoubleScalarPower(a,b) \
   (utIsIntPower(b) ? utDoubleScalarIntPower(a,b) : utFdlibm_pow(a,b))


/* pow2(a) */
#define utDoubleScalarPow2(a) utFdlibm_pow(2.0,a)

/* real(a) */
#define utDoubleScalarReal(a) (a)
        
/* sec(a) */				
#define utDoubleScalarSec(a) (1.0/utFdlibm_cos(a))

/* sech(a) */
#define utDoubleScalarSech(a) (1.0/utFdlibm_cosh(a))

/* sin(a) */
#define utDoubleScalarSin(a) utFdlibm_sin(a)

/* single(a) */
#define utDoubleScalarSingle(a)  ((float)a)

/* sign(a) */
#define utDoubleScalarSign(a) (utIsNaN(a)                               \
                                       ? utGetNaN()                     \
                                       :( a == 0.0                      \
                                               ? 0.0                    \
                                               : (a < 0.0               \
                                                        ? -1.0          \
                                                           : 1.0)))

/* sinh(a) */
#define utDoubleScalarSinh(a) utFdlibm_sinh(a)

/* sqrt(a) */
#define utDoubleScalarSqrt(a) ( utIsNaN(a) || a < 0.0 ?  utGetNaN() : sqrt(a))

/* tan(a) */
#define utDoubleScalarTan(a) utFdlibm_tan(a)

/* tanh(a) */
#define utDoubleScalarTanh(a) utFdlibm_tanh(a)
		
/* uint8(a) */
#define utDoubleScalarUint8(a)  ( utIsNaN(a)                            \
                                  ? 0.0                                 \
                                  : ( (a) > 255.                        \
                                       ?  255.                          \
                                       : ( (a) < 0.0                    \
                                            ? 0.0                       \
                                            : (unsigned char)(a))))

/* uint16(a) */
#define utDoubleScalarUint16(a)  ( utIsNaN(a)                           \
                                   ? 0.0                                \
                                   :( (a) > 65535.                      \
                                       ? 65535.                         \
                                       : ((a) < 0.0                     \
                                           ? 0.0                        \
                                           :  (unsigned int)(a))))

/* uint32(a) */
#define utDoubleScalarUint32(a)  ( utIsNaN(a)                           \
                                   ? 0.0                                \
                                   : ((a) > 4294967295.                 \
                                       ? 4294967295.                    \
                                       : ((a) < 0.0                     \
                                           ? 0.0                        \
                                           : (unsigned long)(a))))

/* xor(a,b) */
/*An error message should be issued by users if a or b = NaN */
#define utDoubleScalarXor(a,b)                             \
        ((a) == 0.0                                        \
          ? ((b) == 0.0                                    \
              ? 0.0                                        \
              : 1.0)                                       \
          : ((b) == 0.0                                    \
              ? 1.0                                        \
              : 0.0))


#ifdef __cplusplus
extern "C" {
#endif
/* mod(a,b) */
extern double utDoubleScalarMod(double a, double b);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
extern double utDoubleScalarRem(double a, double b);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
/*
 * Function that returns single Eps value
 */
extern float utGetSingleEps(void);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
/* 
 * convert a double to an signed integer
 *      returns INT_MAX on positive overflow or NaN conversion
 *      returns INT_MIN on negative overflow
 * 
 *      sets errno to ERANGE on overflow
 *      sets errno to EDOM on domain error (NaN conversion)
 */
extern int utDbl2Int(double x);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
/* 
 * convert a double to an unsigned integer
 *      returns UINT_MAX on positive overflow or NaN conversion
 * 
 *      sets errno to ERANGE on overflow
 *      sets errno to EDOM on domain error (NaN conversion)
 */
extern unsigned int utDbl2UInt(double x);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
/*
 * floor(x)
 * Return x rounded toward -inf to integral value
 */
extern double utFdlibm_floor(double x);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
/*
 * ceil(x)
 * Return x rounded toward -inf to integral value
 */
extern double utFdlibm_ceil(double x);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
/*
 * For non-zero x 
 *	x = frexp(arg,&exp);
 * returns a double fp quantity x such that 0.5 <= |x| <1.0
 * and the corresponding binary exponent "exp". That is
 *	arg = x*2^exp.
 * If arg is inf, 0.0, or NaN, then frexp(arg,&exp) returns arg 
 * with *exp=0. 
 */
extern double utFdlibm_frexp(double x, int *eptr);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
/*
 * ilogb(double x)
 * returns the binary exponent of non-zero x
 * ilogb(0) = 0x80000001
 * ilogb(inf/NaN) = 0x7fffffff (no signal is raised)
 */
extern int utFdlibm_ilogb(double x);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
/* 
 * scalbn (double x, int n)
 * scalbn(x,n) returns x* 2**n  computed by  exponent  
 * manipulation rather than by actually performing an 
 * exponentiation or a multiplication.
 */
extern double utFdlibm_scalbn (double x, int n);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
/*
 * double logb(x)
 * IEEE 754 logb. Included to pass IEEE test suite. Not recommend.
 * Use ilogb instead.
 */
extern double utFdlibm_logb(double x);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
/*
 * modf(double x, double *iptr) 
 * returns fraction part of x, and return x's integral part in *iptr.
 */
extern double utFdlibm_modf(double x, double *iptr);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
/*
 * nextafter(x,y)
 * return the next machine floating-point number of x in the
 * direction toward y.
 */
extern double utFdlibm_nextafter(double x, double y);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
/*
 * rint(x)
 * Return x rounded to integral value according to the prevailing
 * rounding mode.
 */
extern double utFdlibm_rint(double x);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
extern double utFdlibm_expm1(double x);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
extern double utFdlibm_log1p(double x);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
extern double utFdlibm_exp(double x);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
extern double utFdlibm_log(double x);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
extern double utFdlibm_log10(double x);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
extern double utFdlibm_acos(double x);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
extern double utFdlibm_acosh(double x);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
extern double utFdlibm_asin(double x);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
extern double utFdlibm_atan(double x);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
extern double utFdlibm_atan2(double y, double x);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
extern double utFdlibm_atanh(double x);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
extern double utFdlibm_cosh(double x);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
extern double utFdlibm_fmod(double x, double y);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
extern double utFdlibm_hypot(double x, double y);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
extern double utFdlibm_pow(double x, double y);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
extern double utFdlibm_remainder(double x, double p);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
extern double utFdlibm_sinh(double x);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
extern double utFdlibm_asinh(double x);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
extern double utFdlibm_cos(double x);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
extern double utFdlibm_sin(double x);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
extern double utFdlibm_tan(double x);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
extern double utFdlibm_tanh(double x);
#ifdef __cplusplus
}
#endif

#endif /* mwutil_h */
