#ifndef GENERIC_FI_H
#define GENERIC_FI_H

/* Compilers may use another function within the assert macro to exit the 
 * program. QAC thus does not see an "exit" function and assumes the 
 * function returns, which it does not.
 * The below pragma tells QAC the compiler supplied function does not
 * return.
 */

/* examples - GCC, ICC, BCC 3.1, BCC 5.5, CYGWIN gcc, Watcom 1.6 */
#pragma PRQA_NO_RETURN __assert_fail
#pragma PRQA_NO_RETURN __assert_perror_fail
#pragma PRQA_NO_RETURN __assert

/* Depending on the code that the compiler maker uses within the assert macro,
 * QAC may issue warnings. It is also possible that when the NDEBUG macro is used
 * to suppress the assertion code, QAC may issue a "no side-effects" warning.
 * To eliminate these, we turn off all warnings for the assert macro.
 */
#pragma PRQA_MACRO_MESSAGES_OFF "assert"


/* Any other items that may be required in a "force-include" file should
 * be placed below.
 */

/* to avoid problems with GCC using builtin functions for va_start
 * and QAC issuing unset variable warnings.
 */
#define va_start(ap, parmN)      ((void)((ap)= &(parmN)))
#define va_arg(ap, type)         (*(type*)(ap))
#define va_end(ap)               ((void)((ap)=0))
#define va_copy(dest, src)       (dest) = (src)
#define __va_copy(dest, src)     (dest) = (src)
#pragma PRQA_MACRO_MESSAGES_OFF "va_end"
#pragma PRQA_MACRO_MESSAGES_OFF "__va_copy"

#define  __builtin_offsetof(type, member) ((size_t) &((type *)0)->member)

/* these defines are used here because GCC uses builtin functions to speed
 * the operation. The below are generic defines.
 */
#ifndef FD_SET
#define fds_bits __fds_bits
#define FD_SETSIZE      (sizeof(fd_set) * 8)
#define FD_SET(n, p)    (((fd_set *) (p))->fds_bits[0] |= (1 << ((n) % 32)))
#define FD_CLR(n, p)    (((fd_set *) (p))->fds_bits[0] &= ~(1 << ((n) % 32)))
#define FD_ISSET(n, p)  (((fd_set *) (p))->fds_bits[0] & (1 << ((n) % 32)))
#define FD_ZERO(p)      memset((p), 0, sizeof(*(p)))
#endif

/* The contents below are actually from GCC limits header but were only
 * to be used if the header was to be used with a non-GCC compiler. If
 * __GNUC__ is defined, an "include_next" directive is used which QAC does not 
 * support as yet.
 */

/* Number of bits in a 'char'.	*/
#ifndef CHAR_BIT
#define CHAR_BIT	8
#endif

#ifndef SCHAR_MIN
/* Minimum and maximum values a `signed char' can hold.  */
#define SCHAR_MIN	(-128)
#define SCHAR_MAX	127
#endif

#ifndef UCHAR_MAX
/* Maximum value an `unsigned char' can hold.  (Minimum is 0.)  */
#define UCHAR_MAX	255
#endif

/* Minimum and maximum values a `char' can hold.  */
#ifdef __CHAR_UNSIGNED__
#define CHAR_MIN	0
#define CHAR_MAX	UCHAR_MAX
#else
#define CHAR_MIN	SCHAR_MIN
#define CHAR_MAX	SCHAR_MAX
#endif

#ifndef SHRT_MIN
/* Minimum and maximum values a `signed short int' can hold.  */
#define SHRT_MIN	(-32768)
#define SHRT_MAX	32767
#endif

#ifndef USHRT_MAX
/* Maximum value an `unsigned short int' can hold.  (Minimum is 0.)  */
#define USHRT_MAX	65535
#endif

#ifndef INT_MIN
/* Minimum and maximum values a `signed int' can hold.  */
#define INT_MIN	(-INT_MAX - 1)
#define INT_MAX	2147483647
#endif

#ifndef UINT_MAX
/* Maximum value an `unsigned int' can hold.  (Minimum is 0.)  */
#define UINT_MAX	4294967295U
#endif

/* Minimum and maximum values a `signed long int' can hold.  */
#if __WORDSIZE == 64
#define LONG_MAX	9223372036854775807L
#else
#define LONG_MAX	2147483647L
#endif
#define LONG_MIN	(-LONG_MAX - 1L)

/* Maximum value an `unsigned long int' can hold.  (Minimum is 0.)  */
#if __WORDSIZE == 64
#define ULONG_MAX	18446744073709551615UL
#else
#define ULONG_MAX	4294967295UL
#endif

#ifdef __USE_ISOC99
/* Minimum and maximum values a `signed long long int' can hold.  */
#define LLONG_MAX	9223372036854775807LL
#define LLONG_MIN	(-LLONG_MAX - 1LL)

/* Maximum value an `unsigned long long int' can hold.  (Minimum is 0.)  */
#define ULLONG_MAX	18446744073709551615ULL
#endif /* ISO C99 */

/* MINGW32 fix */
#ifdef __MINGW32__
#define _fileno(__F) ((__F)->_file)
#endif

#else
#error "Multiple include"
#endif  /* ifndef GENERIC_FI_H */
