/*-
* Copyright (c) 2010 Kai Wang
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: driver.h 3074 2014-06-23 03:08:53Z kaiwang27 $
*/
#ifndef _DRIVER_H_
#define _DRIVER_H_
struct dwarf_tp {
const char *tp_name;
void (*tp_func)(void);
};
#define TS_DWARF_INIT(D,FD,DE) do { \
(D) = NULL; \
if (((FD) = open(_cur_file, O_RDONLY)) < 0) { \
tet_printf("open %s failed; %s", _cur_file, \
strerror(errno)); \
result = TET_FAIL; \
goto done; \
} \
if (dwarf_init((FD), DW_DLC_READ, NULL, NULL, &(D), &(DE)) != \
DW_DLV_OK) { \
tet_printf("dwarf_init failed: %s", dwarf_errmsg((DE)));\
result = TET_FAIL; \
goto done; \
} \
} while (0)
#define TS_DWARF_FINISH(D,DE) do { \
if (dwarf_finish((D), &(DE)) != DW_DLV_OK) { \
tet_printf("dwarf_finish failed: %s", \
dwarf_errmsg((DE))); \
result = TET_FAIL; \
} \
} while (0)
#define TS_DWARF_CU_FOREACH(D,N,DE) \
while (dwarf_next_cu_header((D), NULL, NULL, NULL, NULL, &(N), \
&(DE)) == DW_DLV_OK)
#define TS_DWARF_CU_FOREACH2(D,I,N,DE) \
while (dwarf_next_cu_header_c((D), (I), NULL, NULL, NULL, NULL, \
NULL, NULL, NULL, NULL, &(N), &(DE)) == DW_DLV_OK)
#define TS_DWARF_DIE_TRAVERSE(D,CB) \
_die_traverse((D), (CB))
#define TS_DWARF_DIE_TRAVERSE2(D,I,CB) \
_die_traverse2((D), (I), (CB))
#ifndef TCGEN
#define _TS_CHECK_VAR(X,S) do { \
struct _drv_vc *_next_vc; \
int skip = 0; \
if (strcmp(_cur_vc->var, S)) { \
tet_printf("VC var(%s) does not match %s, possibly" \
" caused by the skip of previous VCs, try finding" \
" the next var with maching name", _cur_vc->var, \
S); \
_next_vc = _cur_vc; \
do { \
_next_vc = STAILQ_NEXT(_next_vc, next); \
skip++; \
if (!strcmp(_next_vc->var, S)) \
break; \
} while (_next_vc != NULL); \
if (_next_vc != NULL) { \
tet_printf("skipped %d VC(s)\n", skip); \
_cur_vc = _next_vc; \
} \
} \
} while (0)
#define TS_CHECK_INT(X) do { \
assert(_cur_vc != NULL); \
_TS_CHECK_VAR(X,#X); \
if (X != _cur_vc->v.i64) { \
tet_printf("assertion %s(%jd) == %jd failed", \
_cur_vc->var, (intmax_t) (X), \
(intmax_t) _cur_vc->v.i64); \
result = TET_FAIL; \
} \
_cur_vc = STAILQ_NEXT(_cur_vc, next); \
} while (0)
#define TS_CHECK_UINT(X) do { \
assert(_cur_vc != NULL); \
_TS_CHECK_VAR(X,#X); \
if (X != _cur_vc->v.u64) { \
tet_printf("assertion %s(%ju) == %ju failed", \
_cur_vc->var, (uintmax_t) (X), \
(uintmax_t) _cur_vc->v.u64); \
result = TET_FAIL; \
} \
_cur_vc = STAILQ_NEXT(_cur_vc, next); \
} while (0)
#define TS_CHECK_STRING(X) do { \
assert(_cur_vc != NULL); \
_TS_CHECK_VAR(X,#X); \
if (strcmp(X, _cur_vc->v.str)) { \
tet_printf("assertion %s('%s') == '%s' failed", \
_cur_vc->var, (X), _cur_vc->v.str); \
result = TET_FAIL; \
} \
_cur_vc = STAILQ_NEXT(_cur_vc, next); \
} while (0)
#define TS_CHECK_BLOCK(B,S) do { \
assert(_cur_vc != NULL); \
_TS_CHECK_VAR(B,#B); \
if ((S) != _cur_vc->v.b.len || \
memcmp((B), _cur_vc->v.b.data, _cur_vc->v.b.len)) { \
tet_printf("assertion block %s failed\n", _cur_vc->var);\
result = TET_FAIL; \
} \
_cur_vc = STAILQ_NEXT(_cur_vc, next); \
} while (0)
#define TS_RESULT(X) tet_result(X)
#else /* !TCGEN */
#define TS_CHECK_INT(X) do { \
fprintf(_cur_fp, " %jd\n", #X, \
(intmax_t) (X)); \
} while (0)
#define TS_CHECK_UINT(X) do { \
fprintf(_cur_fp, " %ju\n", #X, \
(uintmax_t)(X)); \
} while (0)
#define TS_CHECK_STRING(X) do { \
fprintf(_cur_fp, " %s\n", #X, \
driver_string_encode(X)); \
} while (0)
#define TS_CHECK_BLOCK(B,S) do { \
char *code; \
int codesize; \
size_t wsize; \
fprintf(_cur_fp, " ", #B); \
driver_base64_encode((char *) (B), (S), &code, &codesize); \
wsize = fwrite(code, 1, (size_t) codesize, _cur_fp); \
assert(wsize == (size_t) codesize); \
fprintf(_cur_fp, "\n"); \
free(code); \
} while (0)
#define TS_RESULT(X)
#endif /* !TCGEN */
#endif /* !_DRIVER_H_ */