#ifndef _ASSERT_H_
#define _ASSERT_H_

/* Assert implementation with ideas from X++ by Sommerfeld, et al */

extern int __fail_line;
#ifdef __SABER__
extern const char *__fail_file;
extern const char *__fail_assertion;
#else
extern const char *__fail_file;
extern const char *__fail_assertion;
#endif


#ifndef NDEBUG
#ifdef __STDC__

extern int write(int, const char *, int);
#ifdef __GNUC__
extern volatile void abort(void);
#else /* __GNUC__ */
extern void abort(void);
#endif /* __GNUC__ */
#define __assert_line(line) #line
#define __assert_string(expression, lineno, fname) "Assertion failed: file " fname ": line " __assert_line(lineno) ": " #expression "\n"
#else /* __STDC__ */
extern int write();
extern void abort();
#define __assert_string(expression, lineno, fname) "Assertion failed: expression\n"
#endif /* __STDC__ */
#define assert(expression) {if(!(expression)) { \
     __fail_line=__LINE__;__fail_file=__FILE__; \
     __fail_assertion=__assert_string(expression, __LINE__, __FILE__); \
     (void)write(2,__fail_assertion, \
		 sizeof(__assert_string(expression, __LINE__, __FILE__))); \
     abort();}}
#else /* ifndef NDEBUG */
#define assert(expression) {}
#endif
#endif

