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