1 /* $OpenBSD: test.h,v 1.6 2012/04/13 10:15:49 guenther Exp $ */ 2 3 #ifndef _h_test_ 4 #define _h_test_ 5 6 #include <stdio.h> 7 #include <stdlib.h> 8 #include <signal.h> 9 #include <errno.h> 10 #include <string.h> 11 #include <stdarg.h> 12 #include <unistd.h> 13 14 static void __vpanic(const char *, const char *, const char *, 15 int, const char *, va_list) __attribute__((__noreturn__)); 16 static void __panic(const char *, const char *, const char *, 17 int, const char *, ...) __attribute__((__noreturn__)); 18 19 #if defined(__OpenBSD__) || defined(__FreeBSD__) 20 #include <pthread.h> 21 #include <pthread_np.h> 22 void _thread_dump_info(void); 23 int _thread_sys_write(int, const char*, size_t); 24 void _thread_sys__exit(int) __attribute__((__noreturn__)); 25 #define SET_NAME(x) pthread_set_name_np(pthread_self(), x) 26 #define DUMP_INFO() _thread_dump_info() 27 #else 28 #define _thread_sys_write(fd,buf,len) write(fd,buf,len) 29 #define _thread_sys__exit(ret) _exit(ret) 30 #define strlcat(dst,src,siz) strcat(dst,src) 31 #define SET_NAME(x) /* nada */ 32 #define DUMP_INFO() /* nada */ 33 #endif 34 35 static void 36 __vpanic(type, errstr, filenm, lineno, fmt, ap) 37 const char *type; 38 const char *errstr; 39 const char *filenm; 40 int lineno; 41 const char *fmt; 42 va_list ap; 43 { 44 char buf[1024]; 45 46 /* "<type> at <filenm>:<lineno>: <fmt ap...>:<errstr>" */ 47 snprintf(buf, sizeof buf, "%s at %s:%d\n", type, filenm, lineno); 48 _thread_sys_write(2, buf, strlen(buf)); 49 vsnprintf(buf, sizeof buf, fmt, ap); 50 if (errstr != NULL) { 51 strlcat(buf, ": ", sizeof buf); 52 strlcat(buf, errstr, sizeof buf); 53 } 54 strlcat(buf, "\n", sizeof buf); 55 _thread_sys_write(2, buf, strlen(buf)); 56 57 DUMP_INFO(); 58 _thread_sys__exit(1); 59 60 _thread_sys_write(2, "[locking]\n", 10); 61 while(1); 62 } 63 64 static void 65 __panic(type, errstr, filenm, lineno, fmt) 66 const char *type; 67 const char *errstr; 68 const char *filenm; 69 int lineno; 70 const char *fmt; 71 { 72 va_list ap; 73 74 va_start(ap, fmt); 75 __vpanic(type, errstr, filenm, lineno, fmt, ap); 76 va_end(ap); 77 } 78 79 #define DIE(e, m, args...) \ 80 __panic("died", strerror(e), __FILE__, __LINE__, m , ## args) 81 82 #define PANIC(m, args...) \ 83 __panic("panic", NULL, __FILE__, __LINE__, m, ## args) 84 85 #define ASSERT(x) do { \ 86 if (!(x)) \ 87 __panic("assert failed", NULL, __FILE__, __LINE__, "%s", #x); \ 88 } while(0) 89 90 #define ASSERTe(x,rhs) do { \ 91 int _x; \ 92 _x = (x); \ 93 if (!(_x rhs)) { \ 94 if (_x > 0) \ 95 __panic("assert failed", strerror(_x), __FILE__, __LINE__, \ 96 "%s %s", #x, #rhs); \ 97 else \ 98 __panic("assert failed", NULL, __FILE__, __LINE__, \ 99 "%s [=%d] %s", #x, _x, #rhs); \ 100 } \ 101 } while(0) 102 103 #define _T(x) __builtin_classify_type(x) 104 105 #define _CHECK(x, rhs, efn) do { \ 106 typeof(x) _x; \ 107 _x = (x); \ 108 if (!(_x rhs)) \ 109 __panic("check failed", efn, __FILE__, __LINE__, \ 110 ((_T(0) == _T(_x) )? "failed check %s (=%d) %s " : \ 111 (_T("") == _T(_x) )? "failed check %s (=%s) %s " : \ 112 (_T('x') == _T(_x) )? "failed check %s (=%c) %s " : \ 113 (_T(0L) == _T(_x) )? "failed check %s (=%ld) %s " : "?") \ 114 , #x, _x, #rhs); \ 115 } while(0) 116 117 #define CHECKr(x) _CHECK(x, == 0, strerror(_x)) 118 #define CHECKe(x) _CHECK(x, != -1, strerror(errno)) 119 #define CHECKn(x) _CHECK(x, != 0, strerror(errno)) 120 #define CHECKhn(x) _CHECK(x, != 0, hstrerror(h_errno)) 121 122 #define SUCCEED exit(0) 123 124 #define OK (0) 125 #define NOTOK (-1) 126 127 #endif /* _h_test_ */ 128