#ifndef _ATTR_H_INCLUDED_
#define _ATTR_H_INCLUDED_
#include <stdarg.h>
#include <vstream.h>
#include <vstring.h>
#include <htable.h>
#include <nvtable.h>
#include <check_arg.h>
typedef int (*ATTR_SCAN_MASTER_FN) (VSTREAM *, int,...);
typedef int (*ATTR_SCAN_SLAVE_FN) (ATTR_SCAN_MASTER_FN, VSTREAM *, int, void *);
typedef int (*ATTR_PRINT_MASTER_FN) (VSTREAM *, int,...);
typedef int (*ATTR_PRINT_SLAVE_FN) (ATTR_PRINT_MASTER_FN, VSTREAM *, int, void *);
#define ATTR_TYPE_END 0
#define ATTR_TYPE_INT 1
#define ATTR_TYPE_NUM ATTR_TYPE_INT
#define ATTR_TYPE_STR 2
#define ATTR_TYPE_HASH 3
#define ATTR_TYPE_NV 3
#define ATTR_TYPE_LONG 4
#define ATTR_TYPE_DATA 5
#define ATTR_TYPE_FUNC 6
#define ATTR_TYPE_OPEN '{'
#define ATTR_TYPE_CLOSE '}'
#define ATTR_NAME_OPEN "{"
#define ATTR_NAME_CLOSE "}"
#define ATTR_HASH_LIMIT 1024
#define SEND_ATTR_INT(name, val) ATTR_TYPE_INT, CHECK_CPTR(ATTR, char, (name)), CHECK_VAL(ATTR, int, (val))
#define SEND_ATTR_STR(name, val) ATTR_TYPE_STR, CHECK_CPTR(ATTR, char, (name)), CHECK_CPTR(ATTR, char, (val))
#define SEND_ATTR_HASH(val) ATTR_TYPE_HASH, CHECK_CPTR(ATTR, HTABLE, (val))
#define SEND_ATTR_NV(val) ATTR_TYPE_NV, CHECK_CPTR(ATTR, NVTABLE, (val))
#define SEND_ATTR_LONG(name, val) ATTR_TYPE_LONG, CHECK_CPTR(ATTR, char, (name)), CHECK_VAL(ATTR, long, (val))
#define SEND_ATTR_DATA(name, len, val) ATTR_TYPE_DATA, CHECK_CPTR(ATTR, char, (name)), CHECK_VAL(ATTR, ssize_t, (len)), CHECK_CPTR(ATTR, void, (val))
#define SEND_ATTR_FUNC(func, val) ATTR_TYPE_FUNC, CHECK_VAL(ATTR, ATTR_PRINT_SLAVE_FN, (func)), CHECK_CPTR(ATTR, void, (val))
#define RECV_ATTR_INT(name, val) ATTR_TYPE_INT, CHECK_CPTR(ATTR, char, (name)), CHECK_PTR(ATTR, int, (val))
#define RECV_ATTR_STR(name, val) ATTR_TYPE_STR, CHECK_CPTR(ATTR, char, (name)), CHECK_PTR(ATTR, VSTRING, (val))
#define RECV_ATTR_HASH(val) ATTR_TYPE_HASH, CHECK_PTR(ATTR, HTABLE, (val))
#define RECV_ATTR_NV(val) ATTR_TYPE_NV, CHECK_PTR(ATTR, NVTABLE, (val))
#define RECV_ATTR_LONG(name, val) ATTR_TYPE_LONG, CHECK_CPTR(ATTR, char, (name)), CHECK_PTR(ATTR, long, (val))
#define RECV_ATTR_DATA(name, val) ATTR_TYPE_DATA, CHECK_CPTR(ATTR, char, (name)), CHECK_PTR(ATTR, VSTRING, (val))
#define RECV_ATTR_FUNC(func, val) ATTR_TYPE_FUNC, CHECK_VAL(ATTR, ATTR_SCAN_SLAVE_FN, (func)), CHECK_PTR(ATTR, void, (val))
CHECK_VAL_HELPER_DCL(ATTR, ssize_t);
CHECK_VAL_HELPER_DCL(ATTR, long);
CHECK_VAL_HELPER_DCL(ATTR, int);
CHECK_PTR_HELPER_DCL(ATTR, void);
CHECK_PTR_HELPER_DCL(ATTR, long);
CHECK_PTR_HELPER_DCL(ATTR, int);
CHECK_PTR_HELPER_DCL(ATTR, VSTRING);
CHECK_PTR_HELPER_DCL(ATTR, NVTABLE);
CHECK_PTR_HELPER_DCL(ATTR, HTABLE);
CHECK_CPTR_HELPER_DCL(ATTR, void);
CHECK_CPTR_HELPER_DCL(ATTR, char);
CHECK_CPTR_HELPER_DCL(ATTR, NVTABLE);
CHECK_CPTR_HELPER_DCL(ATTR, HTABLE);
CHECK_VAL_HELPER_DCL(ATTR, ATTR_PRINT_SLAVE_FN);
CHECK_VAL_HELPER_DCL(ATTR, ATTR_SCAN_SLAVE_FN);
#define ATTR_FLAG_NONE 0
#define ATTR_FLAG_MISSING (1<<0)
#define ATTR_FLAG_EXTRA (1<<1)
#define ATTR_FLAG_MORE (1<<2)
#define ATTR_FLAG_STRICT (ATTR_FLAG_MISSING | ATTR_FLAG_EXTRA)
#define ATTR_FLAG_ALL (07)
#define attr_print attr_print0
#define attr_vprint attr_vprint0
#define attr_scan attr_scan0
#define attr_vscan attr_vscan0
#define attr_scan_more attr_scan_more0
extern int attr_print64(VSTREAM *, int,...);
extern int attr_vprint64(VSTREAM *, int, va_list);
extern int WARN_UNUSED_RESULT attr_scan64(VSTREAM *, int,...);
extern int WARN_UNUSED_RESULT attr_vscan64(VSTREAM *, int, va_list);
extern int WARN_UNUSED_RESULT attr_scan_more64(VSTREAM *);
extern int attr_print0(VSTREAM *, int,...);
extern int attr_vprint0(VSTREAM *, int, va_list);
extern int WARN_UNUSED_RESULT attr_scan0(VSTREAM *, int,...);
extern int WARN_UNUSED_RESULT attr_vscan0(VSTREAM *, int, va_list);
extern int WARN_UNUSED_RESULT attr_scan_more0(VSTREAM *);
extern int attr_print_plain(VSTREAM *, int,...);
extern int attr_vprint_plain(VSTREAM *, int, va_list);
extern int attr_scan_more_plain(VSTREAM *);
extern int WARN_UNUSED_RESULT attr_scan_plain(VSTREAM *, int,...);
extern int WARN_UNUSED_RESULT attr_vscan_plain(VSTREAM *, int, va_list);
#ifdef TEST
#define ATTR_NAME_INT "number"
#define ATTR_NAME_STR "string"
#define ATTR_NAME_LONG "long_number"
#define ATTR_NAME_DATA "data"
#endif
#endif