/*  be safe, in case some other header had them slightly differently */
#undef container_of
#undef offsetof
#undef ARRAY_SIZE

#define container_of(ptr, type, member) ({			\
	const typeof( ((type *)0)->member ) *__mptr = (ptr);	\
	(type *)( (char *)__mptr - offsetof(type,member) );})

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))

/* the macro below relies on an externally-defined structure type */
#define DUMP_FIELD(_type, _fname) { \
	.name = #_fname ":",  \
	.type = dump_type_ ## _type, \
	.size = sizeof(_type), \
	.offset = offsetof(DUMP_STRUCT, _fname), \
}
#define DUMP_FIELD_SIZE(_type, _fname, _size) { \
	.name = #_fname ":",		\
	.type = dump_type_ ## _type, \
	.offset = offsetof(DUMP_STRUCT, _fname), \
	.size = _size, \
}

/*
 * To ease copying from header files, allow int, char and other known types.
 * Please add more type as more structures are included here
 */
enum dump_type {
	dump_type_char, /* for zero-terminated strings */
	dump_type_char_e, /* for zero-terminated strings with thw wrong
			   * endianess */
	dump_type_bina, /* for binary stull in MAC format */
	/* normal types follow */
	dump_type_uint64_t,
	dump_type_uint32_t,
	dump_type_uint16_t,
	dump_type_int,
	dump_type_unsigned,
	dump_type_unsigned_long,
	dump_type_long_long,
	dump_type_unsigned_char,
	dump_type_unsigned_short,
	dump_type_double,
	dump_type_float,
	dump_type_pointer,
	dump_type_yes_no,
	dump_type_timeval,

	/* and this is ours */
	dump_type_time,
	dump_type_ip_address,
	dump_type_sfp_flags,
	dump_type_sfp_dom_temp,
	dump_type_sfp_dom_voltage,
	dump_type_sfp_dom_bias_curr,
	dump_type_sfp_dom_tx_power,
	dump_type_sfp_dom_rx_power,
	dump_type_port_mode,
	dump_type_sensor_temp,
	/* SoftPLL's enumerations */
	dump_type_spll_mode,
	dump_type_spll_seq_state,
	dump_type_spll_align_state,
	/* rtu_filtering_entry enumerations */
	dump_type_rtu_filtering_entry_dynamic,
	dump_type_rtu_qmode,
	dump_type_array_int,
	dump_type_shmemState,
	dump_type_hal_mode,
	dump_type_hal_fsm,
	dump_type_hal_pllfsm,
	dump_type_hal_lpdc_tx_setup_fsm,
	dump_type_hal_lpdc_rx_setup_fsm,
};


/* because of the sizeof later on, we need these typedefs */
typedef void *         pointer;
typedef struct pp_time pp_time;
typedef long long      long_long;
typedef unsigned long  unsigned_long;
typedef unsigned char  unsigned_char;
typedef unsigned short unsigned_short;
typedef uint8_t        dummy; /* use the smallest */
typedef struct {unsigned char addr[4];} ip_address;
typedef uint8_t        yes_no;
typedef int            link_up_status;
typedef int            ip_addr_status;
typedef int            sensor_temp;
typedef uint32_t       sfp_flags;
typedef uint8_t        sfp_dom_temp;
typedef uint8_t        sfp_dom_voltage;
typedef uint8_t        sfp_dom_bias_curr;
typedef uint8_t        sfp_dom_tx_power;
typedef uint8_t        sfp_dom_rx_power;
typedef int            port_mode;
typedef int            rtu_filtering_entry_dynamic;
typedef uint8_t        rtu_qmode;
typedef uint8_t        array_int;
typedef struct timeval timeval;
typedef int            spll_mode;
typedef int            spll_seq_state;
typedef int            spll_align_state;
typedef int            shmemState;
typedef int            hal_mode;
typedef int            hal_fsm;
typedef int            hal_pllfsm;
typedef int            hal_lpdc_tx_setup_fsm;
typedef int            hal_lpdc_rx_setup_fsm;
/*
 * A structure to dump fields. This is meant to simplify things, see use here
 */
struct dump_info {
	char *name;
	enum dump_type type;   /* see above */
	int offset;
	int size;  /* only for strings or binary strings */
};

void dump_many_fields(void *addr, struct dump_info *info, int ninfo,
		      char *prefix);
int dump_ppsi_mem(struct wrs_shm_head *head);
