enhanced the constant value handling
This commit is contained in:
		| @ -132,6 +132,10 @@ QSE_EXPORT const qse_mchar_t* qse_mbsbasename ( | |||||||
| 	const qse_mchar_t* path | 	const qse_mchar_t* path | ||||||
| ); | ); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * The qse_substmbsbasenamedup() function creates a new string composed of | ||||||
|  |  * the base directory part of the given \a path and \a file combined. | ||||||
|  |  */ | ||||||
| QSE_EXPORT qse_mchar_t* qse_substmbsbasenamedup ( | QSE_EXPORT qse_mchar_t* qse_substmbsbasenamedup ( | ||||||
| 	const qse_mchar_t* path, | 	const qse_mchar_t* path, | ||||||
| 	const qse_mchar_t* file, | 	const qse_mchar_t* file, | ||||||
| @ -289,7 +293,10 @@ QSE_EXPORT qse_size_t qse_canonwcspath ( | |||||||
| 	int                flags | 	int                flags | ||||||
| ); | ); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * The qse_substwcsbasenamedup() function creates a new string composed of | ||||||
|  |  * the base directory part of the given \a path and \a file combined. | ||||||
|  |  */ | ||||||
| QSE_EXPORT qse_wchar_t* qse_mergewcspathdup ( | QSE_EXPORT qse_wchar_t* qse_mergewcspathdup ( | ||||||
| 	const qse_wchar_t* dir, | 	const qse_wchar_t* dir, | ||||||
| 	const qse_wchar_t* file, | 	const qse_wchar_t* file, | ||||||
|  | |||||||
| @ -39,7 +39,8 @@ typedef enum qse_raddic_opt_t qse_raddic_opt_t; | |||||||
| enum qse_raddic_trait_t | enum qse_raddic_trait_t | ||||||
| { | { | ||||||
| 	QSE_RADDIC_ALLOW_CONST_WITHOUT_ATTR = (1 << 0), | 	QSE_RADDIC_ALLOW_CONST_WITHOUT_ATTR = (1 << 0), | ||||||
| 	QSE_RADDIC_ALLOW_DUPLICATE_CONST    = (1 << 1) | 	QSE_RADDIC_ALLOW_DUPLICATE_CONST    = (1 << 1), | ||||||
|  | 	QSE_RADDIC_IGNORE_UNKNOWN_ATTR_FLAG = (1 << 2) | ||||||
| }; | }; | ||||||
| typedef enum qse_raddic_trait_t qse_raddic_trait_t; | typedef enum qse_raddic_trait_t qse_raddic_trait_t; | ||||||
|  |  | ||||||
| @ -59,24 +60,6 @@ enum qse_raddic_errnum_t | |||||||
| typedef enum qse_raddic_errnum_t qse_raddic_errnum_t; | typedef enum qse_raddic_errnum_t qse_raddic_errnum_t; | ||||||
|  |  | ||||||
|  |  | ||||||
| #if 0 |  | ||||||
| #define QSE_RADDIC_ATTR_TYPE_STRING                  0 |  | ||||||
| #define QSE_RADDIC_ATTR_TYPE_INTEGER                 1 |  | ||||||
| #define QSE_RADDIC_ATTR_TYPE_IPADDR                  2 |  | ||||||
| #define QSE_RADDIC_ATTR_TYPE_DATE                    3 |  | ||||||
| #define QSE_RADDIC_ATTR_TYPE_ABINARY                 4 |  | ||||||
| #define QSE_RADDIC_ATTR_TYPE_OCTETS                  5 |  | ||||||
| #define QSE_RADDIC_ATTR_TYPE_IFID                    6 |  | ||||||
| #define QSE_RADDIC_ATTR_TYPE_IPV6ADDR                7 |  | ||||||
| #define QSE_RADDIC_ATTR_TYPE_IPV6PREFIX              8 |  | ||||||
| #define QSE_RADDIC_ATTR_TYPE_BYTE                    9 |  | ||||||
| #define QSE_RADDIC_ATTR_TYPE_SHORT                   10 |  | ||||||
| #define QSE_RADDIC_ATTR_TYPE_ETHERNET                11 |  | ||||||
| #define QSE_RADDIC_ATTR_TYPE_SIGNED                  12 |  | ||||||
| #define QSE_RADDIC_ATTR_TYPE_COMBO_IP                13 |  | ||||||
| #define QSE_RADDIC_ATTR_TYPE_TLV                     14 |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| enum qse_raddic_attr_type_t | enum qse_raddic_attr_type_t | ||||||
| { | { | ||||||
| 	QSE_RADDIC_ATTR_TYPE_INVALID = 0, | 	QSE_RADDIC_ATTR_TYPE_INVALID = 0, | ||||||
| @ -130,20 +113,34 @@ enum qse_raddic_attr_type_t | |||||||
| }; | }; | ||||||
| typedef enum qse_raddic_attr_type_t qse_raddic_attr_type_t; | typedef enum qse_raddic_attr_type_t qse_raddic_attr_type_t; | ||||||
|  |  | ||||||
|  | enum qse_raddic_attr_flag_encrypt_t | ||||||
|  | { | ||||||
|  | 	QSE_RADDIC_ATTR_FLAG_ENCRYPT_NONE = 0, /* keep this entry on top */ | ||||||
|  |  | ||||||
|  | 	QSE_RADDIC_ATTR_FLAG_ENCRYPT_USER_PASSWORD, /* RFC2865 */ | ||||||
|  | 	QSE_RADDIC_ATTR_FLAG_ENCRYPT_TUNNEL_PASSWORD, /* RFC2868 */ | ||||||
|  | 	QSE_RADDIC_ATTR_FLAG_ENCRYPT_ASCEND_SECRET, | ||||||
|  |  | ||||||
|  | 	QSE_RADDIC_ATTR_FLAG_ENCRYPT_OTHER /* keep this entry at the bottom */ | ||||||
|  | }; | ||||||
|  | typedef enum qse_raddic_attr_flag_encrypt_t qse_raddic_attr_flag_encrypt_t; | ||||||
|  |  | ||||||
| struct qse_raddic_attr_flags_t  | struct qse_raddic_attr_flags_t  | ||||||
| { | { | ||||||
| 	unsigned int            addport : 1;  /* add NAS-Port to IP address */ | 	unsigned int            addport: 1;  /* add NAS-Port to IP address */ | ||||||
| 	unsigned int            has_tag : 1;  /* tagged attribute */ | 	unsigned int            has_tag: 1;  /* tagged attribute */ | ||||||
| 	unsigned int            do_xlat : 1;  /* strvalue is dynamic */ | 	unsigned int            unknown_attr: 1; /* not in dictionary */ | ||||||
| 	unsigned int            unknown_attr : 1; /* not in dictionary */ | 	unsigned int            array: 1; /* pack multiples into 1 attr */ | ||||||
| 	unsigned int            array : 1; /* pack multiples into 1 attr */ | 	unsigned int            concat: 1; | ||||||
| 	unsigned int            has_value : 1; /* has a value */ | 	unsigned int            internal: 1; /* internal use only */ | ||||||
| 	unsigned int            has_value_alias : 1; /* has a value alias */ | 	unsigned int            has_value: 1; /* has a value */ | ||||||
| 	unsigned int            has_tlv : 1; /* has sub attributes */ | 	unsigned int            has_tlv: 1; /* has sub attributes */ | ||||||
| 	unsigned int            is_tlv : 1; /* is a sub attribute */ | 	unsigned int            is_tlv: 1; /* is a sub attribute */ | ||||||
| 	unsigned int            encoded : 1; /* has been put into packet */ | 	qse_int8_t              tag;        /* tag for tunneled attributes */ | ||||||
| 	qse_int8_t              tag;          /* tag for tunneled attributes */ | 	qse_uint8_t             length; | ||||||
| 	qse_uint8_t             encrypt;      /* encryption method */ |  | ||||||
|  | 	qse_raddic_attr_flag_encrypt_t encrypt;      /* encryption method */ | ||||||
|  | 	 | ||||||
| }; | }; | ||||||
| typedef struct qse_raddic_attr_flags_t qse_raddic_attr_flags_t; | typedef struct qse_raddic_attr_flags_t qse_raddic_attr_flags_t; | ||||||
|  |  | ||||||
| @ -151,20 +148,43 @@ typedef struct qse_raddic_attr_t qse_raddic_attr_t; | |||||||
| struct qse_raddic_attr_t  | struct qse_raddic_attr_t  | ||||||
| { | { | ||||||
| 	qse_uint32_t            attr; | 	qse_uint32_t            attr; | ||||||
| 	int                     type; | 	qse_raddic_attr_type_t  type; | ||||||
| 	int                     vendor; | 	int                     vendor; | ||||||
| 	qse_raddic_attr_flags_t flags; | 	qse_raddic_attr_flags_t flags; | ||||||
| 	qse_raddic_attr_t*      nexta; | 	qse_raddic_attr_t*      nexta; | ||||||
| 	qse_char_t              name[1]; | 	qse_char_t              name[1]; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | typedef struct qse_raddic_const_value_t qse_raddic_const_value_t; | ||||||
|  | struct qse_raddic_const_value_t | ||||||
|  | { | ||||||
|  | 	qse_raddic_attr_type_t type; | ||||||
|  | 	union | ||||||
|  | 	{ | ||||||
|  | 		qse_uint8_t ui8; | ||||||
|  | 		qse_uint16_t ui16; | ||||||
|  | 		qse_uint32_t ui32; | ||||||
|  | 		qse_uint64_t ui64; | ||||||
|  |  | ||||||
|  | 		qse_int8_t i8; | ||||||
|  | 		qse_int16_t i16; | ||||||
|  | 		qse_int32_t i32; | ||||||
|  | 		qse_int64_t i64; | ||||||
|  |  | ||||||
|  | 		qse_flt_t f32; | ||||||
|  | 		qse_flt_t f64; | ||||||
|  | 		/* TODO: more to come like ip address */ | ||||||
|  | 	} u; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  |  | ||||||
| typedef struct qse_raddic_const_t qse_raddic_const_t; | typedef struct qse_raddic_const_t qse_raddic_const_t; | ||||||
| struct qse_raddic_const_t | struct qse_raddic_const_t | ||||||
| { | { | ||||||
| 	qse_uint32_t        attr;     /* vendor + attribute-value */ | 	qse_uint32_t             attr;     /* vendor + attribute-value */ | ||||||
| 	int                 value; | 	qse_raddic_const_value_t value; | ||||||
| 	qse_raddic_const_t* nextc; | 	qse_raddic_const_t*      nextc; | ||||||
| 	qse_char_t          name[1]; | 	qse_char_t               name[1]; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| typedef struct qse_raddic_vendor_t qse_raddic_vendor_t; | typedef struct qse_raddic_vendor_t qse_raddic_vendor_t; | ||||||
| @ -265,8 +285,6 @@ QSE_EXPORT int qse_raddic_deletevendorbyvalue ( | |||||||
| ); | ); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| QSE_EXPORT qse_raddic_attr_t* qse_raddic_findattrbyname ( | QSE_EXPORT qse_raddic_attr_t* qse_raddic_findattrbyname ( | ||||||
| 	qse_raddic_t*     dic, | 	qse_raddic_t*     dic, | ||||||
| 	const qse_char_t* name | 	const qse_char_t* name | ||||||
| @ -281,7 +299,7 @@ QSE_EXPORT qse_raddic_attr_t* qse_raddic_addattr ( | |||||||
| 	qse_raddic_t*                  dic, | 	qse_raddic_t*                  dic, | ||||||
| 	const qse_char_t*              name, | 	const qse_char_t*              name, | ||||||
| 	int                            vendor, | 	int                            vendor, | ||||||
| 	int                            type, | 	qse_raddic_attr_type_t         type, | ||||||
| 	int                            value, | 	int                            value, | ||||||
| 	const qse_raddic_attr_flags_t* flags | 	const qse_raddic_attr_flags_t* flags | ||||||
| ); | ); | ||||||
| @ -293,7 +311,7 @@ QSE_EXPORT int qse_raddic_deleteattrbyname ( | |||||||
|  |  | ||||||
| QSE_EXPORT int qse_raddic_deleteattrbyvalue ( | QSE_EXPORT int qse_raddic_deleteattrbyvalue ( | ||||||
| 	qse_raddic_t*     dic, | 	qse_raddic_t*     dic, | ||||||
| 	int               attr | 	qse_uint32_t      attr | ||||||
| ); | ); | ||||||
|  |  | ||||||
|  |  | ||||||
| @ -304,16 +322,16 @@ QSE_EXPORT qse_raddic_const_t* qse_raddic_findconstbyname ( | |||||||
| ); | ); | ||||||
|  |  | ||||||
| QSE_EXPORT qse_raddic_const_t* qse_raddic_findconstbyvalue ( | QSE_EXPORT qse_raddic_const_t* qse_raddic_findconstbyvalue ( | ||||||
| 	qse_raddic_t*     dic, | 	qse_raddic_t*                   dic, | ||||||
| 	qse_uint32_t      attr, | 	qse_uint32_t                    attr, | ||||||
| 	int               value | 	const qse_raddic_const_value_t* value | ||||||
| ); | ); | ||||||
|  |  | ||||||
| QSE_EXPORT qse_raddic_const_t* qse_raddic_addconst ( | QSE_EXPORT qse_raddic_const_t* qse_raddic_addconst ( | ||||||
| 	qse_raddic_t*     dic, | 	qse_raddic_t*                   dic, | ||||||
| 	const qse_char_t* name, | 	const qse_char_t*               name, | ||||||
| 	const qse_char_t* attrstr, | 	const qse_char_t*               attrstr, | ||||||
| 	int               value | 	const qse_raddic_const_value_t* value | ||||||
| ); | ); | ||||||
|  |  | ||||||
| QSE_EXPORT int qse_raddic_deleteconstbyname ( | QSE_EXPORT int qse_raddic_deleteconstbyname ( | ||||||
| @ -323,9 +341,9 @@ QSE_EXPORT int qse_raddic_deleteconstbyname ( | |||||||
| ); | ); | ||||||
|  |  | ||||||
| QSE_EXPORT int qse_raddic_deleteconstbyvalue ( | QSE_EXPORT int qse_raddic_deleteconstbyvalue ( | ||||||
| 	qse_raddic_t*     dic, | 	qse_raddic_t*                   dic, | ||||||
| 	qse_uint32_t      attr, | 	qse_uint32_t                    attr, | ||||||
| 	int               value | 	const qse_raddic_const_value_t* value | ||||||
| ); | ); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | |||||||
| @ -56,10 +56,6 @@ | |||||||
| #include <qse/si/sio.h> | #include <qse/si/sio.h> | ||||||
| #include <stdarg.h> | #include <stdarg.h> | ||||||
|  |  | ||||||
| #include <stdio.h> |  | ||||||
| #define fr_strerror_printf printf |  | ||||||
|  |  | ||||||
|  |  | ||||||
| typedef struct const_fixup_t const_fixup_t; | typedef struct const_fixup_t const_fixup_t; | ||||||
|  |  | ||||||
| struct const_fixup_t  | struct const_fixup_t  | ||||||
| @ -98,95 +94,82 @@ struct name_id_t | |||||||
| { | { | ||||||
| 	const qse_char_t* name; | 	const qse_char_t* name; | ||||||
| 	int               id; | 	int               id; | ||||||
|  | 	int               length; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| static const name_id_t type_table[] =  | static const name_id_t type_table[] =  | ||||||
| { | { | ||||||
| 	{ QSE_T("string"),            QSE_RADDIC_ATTR_TYPE_STRING }, | 	{ QSE_T("string"),            QSE_RADDIC_ATTR_TYPE_STRING,            -1 }, | ||||||
| 	{ QSE_T("octets"),            QSE_RADDIC_ATTR_TYPE_OCTETS }, | 	{ QSE_T("octets"),            QSE_RADDIC_ATTR_TYPE_OCTETS,            -1 }, | ||||||
|  |  | ||||||
| 	{ QSE_T("ipaddr"),            QSE_RADDIC_ATTR_TYPE_IPV4_ADDR }, | 	{ QSE_T("ipaddr"),            QSE_RADDIC_ATTR_TYPE_IPV4_ADDR,          4 }, | ||||||
| 	{ QSE_T("ipv4prefix"),        QSE_RADDIC_ATTR_TYPE_IPV4_PREFIX }, | 	{ QSE_T("ipv4prefix"),        QSE_RADDIC_ATTR_TYPE_IPV4_PREFIX,       -1 }, | ||||||
| 	{ QSE_T("ipv6addr"),          QSE_RADDIC_ATTR_TYPE_IPV6_ADDR }, | 	{ QSE_T("ipv6addr"),          QSE_RADDIC_ATTR_TYPE_IPV6_ADDR,         16 }, | ||||||
| 	{ QSE_T("ipv6prefix"),        QSE_RADDIC_ATTR_TYPE_IPV6_PREFIX }, | 	{ QSE_T("ipv6prefix"),        QSE_RADDIC_ATTR_TYPE_IPV6_PREFIX,       -1 }, | ||||||
| 	{ QSE_T("ifid"),              QSE_RADDIC_ATTR_TYPE_IFID }, | 	{ QSE_T("ifid"),              QSE_RADDIC_ATTR_TYPE_IFID,               8 }, | ||||||
| 	{ QSE_T("combo-ip"),          QSE_RADDIC_ATTR_TYPE_COMBO_IP_ADDR }, | 	{ QSE_T("combo-ip"),          QSE_RADDIC_ATTR_TYPE_COMBO_IP_ADDR,     -1 }, | ||||||
| 	{ QSE_T("combo-prefix"),      QSE_RADDIC_ATTR_TYPE_COMBO_IP_PREFIX }, | 	{ QSE_T("combo-prefix"),      QSE_RADDIC_ATTR_TYPE_COMBO_IP_PREFIX,   -1 }, | ||||||
| 	{ QSE_T("ether"),             QSE_RADDIC_ATTR_TYPE_ETHERNET }, | 	{ QSE_T("ether"),             QSE_RADDIC_ATTR_TYPE_ETHERNET,           6 }, | ||||||
|  |  | ||||||
| 	{ QSE_T("bool"),              QSE_RADDIC_ATTR_TYPE_BOOL }, | 	{ QSE_T("bool"),              QSE_RADDIC_ATTR_TYPE_BOOL,               1 }, | ||||||
|  |  | ||||||
| 	{ QSE_T("uint8"),             QSE_RADDIC_ATTR_TYPE_UINT8 }, | 	{ QSE_T("uint8"),             QSE_RADDIC_ATTR_TYPE_UINT8,              1 }, | ||||||
| 	{ QSE_T("uint16"),            QSE_RADDIC_ATTR_TYPE_UINT16 }, | 	{ QSE_T("uint16"),            QSE_RADDIC_ATTR_TYPE_UINT16,             2 }, | ||||||
| 	{ QSE_T("uint32"),            QSE_RADDIC_ATTR_TYPE_UINT32 }, | 	{ QSE_T("uint32"),            QSE_RADDIC_ATTR_TYPE_UINT32,             4 }, | ||||||
| 	{ QSE_T("uint64"),            QSE_RADDIC_ATTR_TYPE_UINT64 }, | 	{ QSE_T("uint64"),            QSE_RADDIC_ATTR_TYPE_UINT64,             8 }, | ||||||
|  |  | ||||||
| 	{ QSE_T("int8"),              QSE_RADDIC_ATTR_TYPE_INT8 }, | 	{ QSE_T("int8"),              QSE_RADDIC_ATTR_TYPE_INT8,               1 }, | ||||||
| 	{ QSE_T("int16"),             QSE_RADDIC_ATTR_TYPE_INT16 }, | 	{ QSE_T("int16"),             QSE_RADDIC_ATTR_TYPE_INT16,              2 }, | ||||||
| 	{ QSE_T("int32"),             QSE_RADDIC_ATTR_TYPE_INT32 }, | 	{ QSE_T("int32"),             QSE_RADDIC_ATTR_TYPE_INT32,              4 }, | ||||||
| 	{ QSE_T("int64"),             QSE_RADDIC_ATTR_TYPE_INT64 }, | 	{ QSE_T("int64"),             QSE_RADDIC_ATTR_TYPE_INT64,              8 }, | ||||||
|  |  | ||||||
| 	{ QSE_T("float32"),           QSE_RADDIC_ATTR_TYPE_FLOAT32 }, | 	{ QSE_T("float32"),           QSE_RADDIC_ATTR_TYPE_FLOAT32,            4 }, | ||||||
| 	{ QSE_T("float64"),           QSE_RADDIC_ATTR_TYPE_FLOAT64 }, | 	{ QSE_T("float64"),           QSE_RADDIC_ATTR_TYPE_FLOAT64,            8 }, | ||||||
|  |  | ||||||
| 	{ QSE_T("timeval"),           QSE_RADDIC_ATTR_TYPE_TIMEVAL }, | 	{ QSE_T("timeval"),           QSE_RADDIC_ATTR_TYPE_TIMEVAL,           -1 }, | ||||||
| 	{ QSE_T("date"),              QSE_RADDIC_ATTR_TYPE_DATE }, | 	{ QSE_T("date"),              QSE_RADDIC_ATTR_TYPE_DATE,               4 }, | ||||||
| 	{ QSE_T("date_milliseconds"), QSE_RADDIC_ATTR_TYPE_DATE_MILLISECONDS }, | 	{ QSE_T("date_milliseconds"), QSE_RADDIC_ATTR_TYPE_DATE_MILLISECONDS, -1 }, | ||||||
| 	{ QSE_T("date_microseconds"), QSE_RADDIC_ATTR_TYPE_DATE_MICROSECONDS }, | 	{ QSE_T("date_microseconds"), QSE_RADDIC_ATTR_TYPE_DATE_MICROSECONDS, -1 }, | ||||||
| 	{ QSE_T("date_nanoseconds"),  QSE_RADDIC_ATTR_TYPE_DATE_NANOSECONDS }, | 	{ QSE_T("date_nanoseconds"),  QSE_RADDIC_ATTR_TYPE_DATE_NANOSECONDS,  -1 }, | ||||||
|  |  | ||||||
| 	{ QSE_T("abinary"),           QSE_RADDIC_ATTR_TYPE_ABINARY }, | 	{ QSE_T("abinary"),           QSE_RADDIC_ATTR_TYPE_ABINARY,           -1 }, | ||||||
|  |  | ||||||
| 	{ QSE_T("size"),              QSE_RADDIC_ATTR_TYPE_SIZE }, | 	{ QSE_T("size"),              QSE_RADDIC_ATTR_TYPE_SIZE,               8 }, | ||||||
|  |  | ||||||
| 	{ QSE_T("tlv"),               QSE_RADDIC_ATTR_TYPE_TLV }, | 	{ QSE_T("tlv"),               QSE_RADDIC_ATTR_TYPE_TLV,               -1 }, | ||||||
| 	{ QSE_T("struct"),            QSE_RADDIC_ATTR_TYPE_STRUCT }, | 	{ QSE_T("struct"),            QSE_RADDIC_ATTR_TYPE_STRUCT,            -1 }, | ||||||
|  |  | ||||||
| 	{ QSE_T("extended"),          QSE_RADDIC_ATTR_TYPE_EXTENDED }, | 	{ QSE_T("extended"),          QSE_RADDIC_ATTR_TYPE_EXTENDED,           0 }, | ||||||
| 	{ QSE_T("long-extended"),     QSE_RADDIC_ATTR_TYPE_LONG_EXTENDED }, | 	{ QSE_T("long-extended"),     QSE_RADDIC_ATTR_TYPE_LONG_EXTENDED,      0 }, | ||||||
|  |  | ||||||
| 	{ QSE_T("vsa"),               QSE_RADDIC_ATTR_TYPE_VSA }, | 	{ QSE_T("vsa"),               QSE_RADDIC_ATTR_TYPE_VSA,               -1 }, | ||||||
| 	{ QSE_T("evs"),               QSE_RADDIC_ATTR_TYPE_EVS }, | 	{ QSE_T("evs"),               QSE_RADDIC_ATTR_TYPE_EVS,               -1 }, | ||||||
| 	{ QSE_T("vendor"),            QSE_RADDIC_ATTR_TYPE_VENDOR }, | 	{ QSE_T("vendor"),            QSE_RADDIC_ATTR_TYPE_VENDOR,            -1 }, | ||||||
|  |  | ||||||
| 	/* | 	/* | ||||||
| 	 *	Alternative names | 	 *	Alternative names | ||||||
| 	 */ | 	 */ | ||||||
| 	{ QSE_T("cidr"),              QSE_RADDIC_ATTR_TYPE_IPV4_PREFIX }, | 	{ QSE_T("cidr"),              QSE_RADDIC_ATTR_TYPE_IPV4_PREFIX,       -1 }, | ||||||
| 	{ QSE_T("byte"),              QSE_RADDIC_ATTR_TYPE_UINT8 }, | 	{ QSE_T("byte"),              QSE_RADDIC_ATTR_TYPE_UINT8,              1 }, | ||||||
| 	{ QSE_T("short"),             QSE_RADDIC_ATTR_TYPE_UINT16 }, | 	{ QSE_T("short"),             QSE_RADDIC_ATTR_TYPE_UINT16,             2 }, | ||||||
| 	{ QSE_T("integer"),           QSE_RADDIC_ATTR_TYPE_UINT32 }, | 	{ QSE_T("integer"),           QSE_RADDIC_ATTR_TYPE_UINT32,             4 }, | ||||||
| 	{ QSE_T("integer64"),         QSE_RADDIC_ATTR_TYPE_UINT64 }, | 	{ QSE_T("integer64"),         QSE_RADDIC_ATTR_TYPE_UINT64,             8 }, | ||||||
| 	{ QSE_T("decimal"),           QSE_RADDIC_ATTR_TYPE_FLOAT64 }, | 	{ QSE_T("decimal"),           QSE_RADDIC_ATTR_TYPE_FLOAT64,            8 }, | ||||||
| 	{ QSE_T("signed"),            QSE_RADDIC_ATTR_TYPE_INT32 }, | 	{ QSE_T("signed"),            QSE_RADDIC_ATTR_TYPE_INT32,              4 } | ||||||
|  |  | ||||||
| #if 0 |  | ||||||
| 	{ QSE_T("integer"),    QSE_RADDIC_ATTR_TYPE_INTEGER }, |  | ||||||
| 	{ QSE_T("string"),     QSE_RADDIC_ATTR_TYPE_STRING }, |  | ||||||
| 	{ QSE_T("ipaddr"),     QSE_RADDIC_ATTR_TYPE_IPADDR }, |  | ||||||
| 	{ QSE_T("date"),       QSE_RADDIC_ATTR_TYPE_DATE }, |  | ||||||
| 	{ QSE_T("abinary"),    QSE_RADDIC_ATTR_TYPE_ABINARY }, |  | ||||||
| 	{ QSE_T("octets"),     QSE_RADDIC_ATTR_TYPE_OCTETS }, |  | ||||||
| 	{ QSE_T("ifid"),       QSE_RADDIC_ATTR_TYPE_IFID }, |  | ||||||
| 	{ QSE_T("ipv6addr"),   QSE_RADDIC_ATTR_TYPE_IPV6ADDR }, |  | ||||||
| 	{ QSE_T("ipv6prefix"), QSE_RADDIC_ATTR_TYPE_IPV6PREFIX }, |  | ||||||
| 	{ QSE_T("byte"),       QSE_RADDIC_ATTR_TYPE_BYTE }, |  | ||||||
| 	{ QSE_T("short"),      QSE_RADDIC_ATTR_TYPE_SHORT }, |  | ||||||
| 	{ QSE_T("ether"),      QSE_RADDIC_ATTR_TYPE_ETHERNET }, |  | ||||||
| 	{ QSE_T("combo-ip"),   QSE_RADDIC_ATTR_TYPE_COMBO_IP }, |  | ||||||
| 	{ QSE_T("tlv"),        QSE_RADDIC_ATTR_TYPE_TLV }, |  | ||||||
| 	{ QSE_T("signed"),     QSE_RADDIC_ATTR_TYPE_SIGNED }, |  | ||||||
| #endif |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /* -------------------------------------------------------------------------- */ | /* -------------------------------------------------------------------------- */ | ||||||
| static int str_to_type (qse_raddic_t* dic, const qse_char_t* name) | static int str_to_type (qse_raddic_t* dic, const qse_char_t* name, int* length) | ||||||
| { | { | ||||||
| 	int i; | 	int i; | ||||||
|  |  | ||||||
| 	for (i = 0; i < QSE_COUNTOF(type_table); i++) | 	for (i = 0; i < QSE_COUNTOF(type_table); i++) | ||||||
| 	{ | 	{ | ||||||
| 		if (qse_strcmp(name, type_table[i].name) == 0) return  type_table[i].id; | 		if (qse_strcmp(name, type_table[i].name) == 0)  | ||||||
|  | 		{ | ||||||
|  | 			if (length) *length = type_table[i].length; | ||||||
|  | 			return  type_table[i].id; | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	dic->errnum = QSE_RADDIC_EINVAL; | 	dic->errnum = QSE_RADDIC_EINVAL; | ||||||
| @ -281,7 +264,10 @@ static int dict_attr_value_cmp (qse_htl_t* htl, const void* one, const void* two | |||||||
|  |  | ||||||
| 	if (a->vendor < b->vendor) return -1; | 	if (a->vendor < b->vendor) return -1; | ||||||
| 	if (a->vendor > b->vendor) return 1; | 	if (a->vendor > b->vendor) return 1; | ||||||
| 	return a->attr - b->attr; |  | ||||||
|  | 	if (a->attr < b->attr) return -1; | ||||||
|  | 	if (a->attr > b->attr) return 1; | ||||||
|  | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| /* -------------------------------------------------------------------------- */ | /* -------------------------------------------------------------------------- */ | ||||||
| @ -355,23 +341,34 @@ static int dict_const_value_cmp (qse_htl_t* htl, const void* one, const void* tw | |||||||
| 	if (a->attr < b->attr) return -1; | 	if (a->attr < b->attr) return -1; | ||||||
| 	if (a->attr > b->attr) return 1; | 	if (a->attr > b->attr) return 1; | ||||||
|  |  | ||||||
| 	return a->value - b->value; | 	if (a->value.type != b->value.type) return -2; /* cannot really compare */ | ||||||
|  |  | ||||||
|  | 	/* this function actuall requires to check equality. | ||||||
|  | 	 * it doesn't have to return greaterness or lessness. | ||||||
|  | 	 * it also assumes that the unused space in the 'value'  | ||||||
|  | 	 * union field is all initialized to zero */ | ||||||
|  | 	return QSE_MEMCMP(&a->value, &b->value, QSE_SIZEOF(a->value)); | ||||||
| } | } | ||||||
|  |  | ||||||
| /* -------------------------------------------------------------------------- */ | /* -------------------------------------------------------------------------- */ | ||||||
|  |  | ||||||
| int qse_raddic_init (qse_raddic_t* dic, qse_mmgr_t* mmgr) | int qse_raddic_init (qse_raddic_t* dic, qse_mmgr_t* mmgr) | ||||||
| { | { | ||||||
|  | 	int count = 0; | ||||||
|  |  | ||||||
| 	QSE_MEMSET (dic, 0, QSE_SIZEOF(*dic)); | 	QSE_MEMSET (dic, 0, QSE_SIZEOF(*dic)); | ||||||
| 	dic->mmgr = mmgr; | 	dic->mmgr = mmgr; | ||||||
| 	qse_raddic_seterrnum (dic, QSE_RADDIC_ENOERR); | 	qse_raddic_seterrnum (dic, QSE_RADDIC_ENOERR); | ||||||
|  |  | ||||||
| 	qse_htl_init (&dic->vendors_byname, mmgr, 1); | 	if (qse_htl_init(&dic->vendors_byname, mmgr, 1) <= -1 || (++count == 0) || | ||||||
| 	qse_htl_init (&dic->vendors_byvalue, mmgr, 1); | 	    qse_htl_init(&dic->vendors_byvalue, mmgr, 1) <= -1 || (++count == 0) || | ||||||
| 	qse_htl_init (&dic->attrs_byname, mmgr, 1); | 	    qse_htl_init(&dic->attrs_byname, mmgr, 1) <= -1 ||  (++count == 0) || | ||||||
| 	qse_htl_init (&dic->attrs_byvalue, mmgr, 1); | 	    qse_htl_init(&dic->attrs_byvalue, mmgr, 1) <= -1 ||(++count == 0) || | ||||||
| 	qse_htl_init (&dic->consts_byname, mmgr, 1); | 	    qse_htl_init(&dic->consts_byname, mmgr, 1) <= -1 || (++count == 0) || | ||||||
| 	qse_htl_init (&dic->consts_byvalue, mmgr, 1); | 	    qse_htl_init(&dic->consts_byvalue, mmgr, 1) <= -1 || (++count == 0)) | ||||||
|  | 	{ | ||||||
|  | 		goto oops; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	qse_htl_sethasher (&dic->vendors_byname, dict_vendor_name_hash); | 	qse_htl_sethasher (&dic->vendors_byname, dict_vendor_name_hash); | ||||||
| 	qse_htl_setcomper (&dic->vendors_byname, dict_vendor_name_cmp); | 	qse_htl_setcomper (&dic->vendors_byname, dict_vendor_name_cmp); | ||||||
| @ -398,18 +395,28 @@ int qse_raddic_init (qse_raddic_t* dic, qse_mmgr_t* mmgr) | |||||||
| 	/* no freeer for dic->consts_byvalue */ | 	/* no freeer for dic->consts_byvalue */ | ||||||
|  |  | ||||||
| 	return 0; | 	return 0; | ||||||
|  |  | ||||||
|  | oops: | ||||||
|  | 	if (count >= 6) qse_htl_fini (&dic->consts_byvalue); | ||||||
|  | 	if (count >= 5) qse_htl_fini (&dic->consts_byname); | ||||||
|  | 	if (count >= 4) qse_htl_fini (&dic->attrs_byvalue); | ||||||
|  | 	if (count >= 3) qse_htl_fini (&dic->attrs_byname); | ||||||
|  | 	if (count >= 2) qse_htl_fini (&dic->vendors_byvalue); | ||||||
|  | 	if (count >= 1) qse_htl_fini (&dic->vendors_byname); | ||||||
|  |  | ||||||
|  | 	return -1; | ||||||
| } | } | ||||||
|  |  | ||||||
| void qse_raddic_fini (qse_raddic_t* dic) | void qse_raddic_fini (qse_raddic_t* dic) | ||||||
| { | { | ||||||
| 	qse_raddic_clear (dic); | 	qse_raddic_clear (dic); | ||||||
|  |  | ||||||
| 	qse_htl_fini (&dic->vendors_byname); |  | ||||||
| 	qse_htl_fini (&dic->vendors_byvalue); |  | ||||||
| 	qse_htl_fini (&dic->attrs_byname); |  | ||||||
| 	qse_htl_fini (&dic->attrs_byvalue); |  | ||||||
| 	qse_htl_fini (&dic->consts_byvalue); | 	qse_htl_fini (&dic->consts_byvalue); | ||||||
| 	qse_htl_fini (&dic->consts_byname); | 	qse_htl_fini (&dic->consts_byname); | ||||||
|  | 	qse_htl_fini (&dic->attrs_byvalue); | ||||||
|  | 	qse_htl_fini (&dic->attrs_byname); | ||||||
|  | 	qse_htl_fini (&dic->vendors_byvalue); | ||||||
|  | 	qse_htl_fini (&dic->vendors_byname); | ||||||
| } | } | ||||||
|  |  | ||||||
| qse_raddic_t* qse_raddic_open (qse_mmgr_t* mmgr, qse_size_t xtnsize) | qse_raddic_t* qse_raddic_open (qse_mmgr_t* mmgr, qse_size_t xtnsize) | ||||||
| @ -727,7 +734,7 @@ qse_raddic_attr_t* qse_raddic_findattrbyvalue (qse_raddic_t* dic, qse_uint32_t a | |||||||
| 	return (qse_raddic_attr_t*)np->data; | 	return (qse_raddic_attr_t*)np->data; | ||||||
| } | } | ||||||
|  |  | ||||||
| qse_raddic_attr_t* qse_raddic_addattr (qse_raddic_t* dic, const qse_char_t* name, int vendor, int type, int value, const qse_raddic_attr_flags_t* flags) | qse_raddic_attr_t* qse_raddic_addattr (qse_raddic_t* dic, const qse_char_t* name, int vendor, qse_raddic_attr_type_t type, int value, const qse_raddic_attr_flags_t* flags) | ||||||
| { | { | ||||||
| 	qse_size_t length; | 	qse_size_t length; | ||||||
| 	qse_raddic_attr_t* dv, * old_dv; | 	qse_raddic_attr_t* dv, * old_dv; | ||||||
| @ -857,7 +864,7 @@ int qse_raddic_deleteattrbyname (qse_raddic_t* dic, const qse_char_t* name) | |||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| int qse_raddic_deleteattrbyvalue (qse_raddic_t* dic, int attr) | int qse_raddic_deleteattrbyvalue (qse_raddic_t* dic, qse_uint32_t attr) | ||||||
| { | { | ||||||
| 	qse_raddic_attr_t* dv; | 	qse_raddic_attr_t* dv; | ||||||
|  |  | ||||||
| @ -908,13 +915,13 @@ qse_raddic_const_t* qse_raddic_findconstbyname (qse_raddic_t* dic, qse_uint32_t | |||||||
| 	return (qse_raddic_const_t*)np->data; | 	return (qse_raddic_const_t*)np->data; | ||||||
| } | } | ||||||
|  |  | ||||||
| qse_raddic_const_t* qse_raddic_findconstbyvalue (qse_raddic_t* dic, qse_uint32_t attr, int value) | qse_raddic_const_t* qse_raddic_findconstbyvalue (qse_raddic_t* dic, qse_uint32_t attr, const  qse_raddic_const_value_t* value) | ||||||
| { | { | ||||||
| 	qse_htl_node_t* np; | 	qse_htl_node_t* np; | ||||||
| 	qse_raddic_const_t dval; | 	qse_raddic_const_t dval; | ||||||
|  |  | ||||||
| 	dval.attr = attr; | 	dval.attr = attr; | ||||||
| 	dval.value = value; | 	dval.value = *value; | ||||||
| 	np = qse_htl_search (&dic->consts_byvalue, &dval); | 	np = qse_htl_search (&dic->consts_byvalue, &dval); | ||||||
| 	if (!np) | 	if (!np) | ||||||
| 	{ | 	{ | ||||||
| @ -924,7 +931,7 @@ qse_raddic_const_t* qse_raddic_findconstbyvalue (qse_raddic_t* dic, qse_uint32_t | |||||||
| 	return (qse_raddic_const_t*)np->data; | 	return (qse_raddic_const_t*)np->data; | ||||||
| } | } | ||||||
|  |  | ||||||
| qse_raddic_const_t* qse_raddic_addconst (qse_raddic_t* dic, const qse_char_t* name, const qse_char_t* attrstr, int value) | qse_raddic_const_t* qse_raddic_addconst (qse_raddic_t* dic, const qse_char_t* name, const qse_char_t* attrstr, const qse_raddic_const_value_t* value) | ||||||
| { | { | ||||||
| 	qse_size_t length; | 	qse_size_t length; | ||||||
| 	qse_raddic_const_t* dval, * old_dval; | 	qse_raddic_const_t* dval, * old_dval; | ||||||
| @ -942,7 +949,7 @@ qse_raddic_const_t* qse_raddic_addconst (qse_raddic_t* dic, const qse_char_t* na | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	qse_strcpy(dval->name, name); | 	qse_strcpy(dval->name, name); | ||||||
| 	dval->value = value; | 	dval->value = *value; | ||||||
| 	dval->nextc = QSE_NULL; | 	dval->nextc = QSE_NULL; | ||||||
|  |  | ||||||
| 	/* | 	/* | ||||||
| @ -965,9 +972,9 @@ qse_raddic_const_t* qse_raddic_addconst (qse_raddic_t* dic, const qse_char_t* na | |||||||
| 	 */ | 	 */ | ||||||
| 	if (dattr)  | 	if (dattr)  | ||||||
| 	{ | 	{ | ||||||
| 		if (dattr->flags.has_value_alias)  | 		if (dattr->type != value->type) | ||||||
| 		{ | 		{ | ||||||
| 			/* cannot add a VALUE for an attribute having a VALUE_ALIAS */ | 			qse_raddic_seterrfmt (dic, QSE_RADDIC_EINVAL, QSE_T("conflicts between attribute type and constant value")); | ||||||
| 			return QSE_NULL; | 			return QSE_NULL; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @ -1046,7 +1053,8 @@ qse_raddic_const_t* qse_raddic_addconst (qse_raddic_t* dic, const qse_char_t* na | |||||||
| 		} | 		} | ||||||
| 		else  | 		else  | ||||||
| 		{ | 		{ | ||||||
| 			if ((dic->opt.trait & QSE_RADDIC_ALLOW_DUPLICATE_CONST) && ((qse_raddic_const_t*)np->data)->value == dval->value)  | 			if ((dic->opt.trait & QSE_RADDIC_ALLOW_DUPLICATE_CONST) &&  | ||||||
|  | 			    QSE_MEMCMP(&((qse_raddic_const_t*)np->data)->value, &dval->value, QSE_SIZEOF(dval->value)) == 0)  | ||||||
| 			{ | 			{ | ||||||
| 				QSE_MMGR_FREE (dic->mmgr, dval); | 				QSE_MMGR_FREE (dic->mmgr, dval); | ||||||
| 				return np->data; | 				return np->data; | ||||||
| @ -1065,7 +1073,7 @@ qse_raddic_const_t* qse_raddic_addconst (qse_raddic_t* dic, const qse_char_t* na | |||||||
| 		/* updated the existing item successfully.  | 		/* updated the existing item successfully.  | ||||||
| 		 * link the old item to the current item */ | 		 * link the old item to the current item */ | ||||||
| 		QSE_ASSERT (np->data == dval); | 		QSE_ASSERT (np->data == dval); | ||||||
| 		QSE_ASSERT (dval->value == old_dval->value); | 		QSE_ASSERT (QSE_MEMCMP(&dval->value, &old_dval->value, QSE_SIZEOF(dval->value)) == 0); | ||||||
| 		dval->nextc = old_dval; | 		dval->nextc = old_dval; | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| @ -1090,7 +1098,7 @@ int qse_raddic_deleteconstbyname (qse_raddic_t* dic, qse_uint32_t attr, const qs | |||||||
| 	if (!dv) return -1; | 	if (!dv) return -1; | ||||||
|  |  | ||||||
| 	QSE_ASSERT (attr == dv->attr); | 	QSE_ASSERT (attr == dv->attr); | ||||||
| 	dv2 = qse_raddic_findconstbyvalue(dic, attr, dv->value); | 	dv2 = qse_raddic_findconstbyvalue(dic, attr, &dv->value); | ||||||
| 	QSE_ASSERT (dv2 != QSE_NULL); | 	QSE_ASSERT (dv2 != QSE_NULL); | ||||||
|  |  | ||||||
| 	if (dv != dv2) | 	if (dv != dv2) | ||||||
| @ -1098,7 +1106,7 @@ int qse_raddic_deleteconstbyname (qse_raddic_t* dic, qse_uint32_t attr, const qs | |||||||
| 		qse_raddic_const_t* x, * y; | 		qse_raddic_const_t* x, * y; | ||||||
|  |  | ||||||
| 		QSE_ASSERT (qse_strcasecmp(dv->name, dv2->name) != 0); | 		QSE_ASSERT (qse_strcasecmp(dv->name, dv2->name) != 0); | ||||||
| 		QSE_ASSERT (dv->value == dv2->value); | 		QSE_ASSERT (QSE_MEMCMP (&dv->value, &dv2->value, QSE_SIZEOF(dv->value)) == 0); | ||||||
| 		QSE_ASSERT (dv->attr == dv2->attr); | 		QSE_ASSERT (dv->attr == dv2->attr); | ||||||
|  |  | ||||||
| 		/* when the constibute of the given name is not the first one | 		/* when the constibute of the given name is not the first one | ||||||
| @ -1130,7 +1138,7 @@ int qse_raddic_deleteconstbyname (qse_raddic_t* dic, qse_uint32_t attr, const qs | |||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| int qse_raddic_deleteconstbyvalue (qse_raddic_t* dic, qse_uint32_t attr, int value) | int qse_raddic_deleteconstbyvalue (qse_raddic_t* dic, qse_uint32_t attr, const qse_raddic_const_value_t* value) | ||||||
| { | { | ||||||
| 	qse_raddic_const_t* dv; | 	qse_raddic_const_t* dv; | ||||||
|  |  | ||||||
| @ -1178,6 +1186,7 @@ static int sscanf_i (qse_raddic_t* dic, const qse_char_t* str, int* pvalue) | |||||||
| { | { | ||||||
| 	qse_long_t v; | 	qse_long_t v; | ||||||
| 	const qse_char_t* end; | 	const qse_char_t* end; | ||||||
|  |  | ||||||
| 	QSE_STRTONUM (v, str, &end, 0); | 	QSE_STRTONUM (v, str, &end, 0); | ||||||
| 	if (*end != '\0')  | 	if (*end != '\0')  | ||||||
| 	{ | 	{ | ||||||
| @ -1188,6 +1197,41 @@ static int sscanf_i (qse_raddic_t* dic, const qse_char_t* str, int* pvalue) | |||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static int sscanf_ui32 (qse_raddic_t* dic, const qse_char_t* str, qse_uint32_t* pvalue, qse_uint32_t* pvalue2) | ||||||
|  | { | ||||||
|  | 	qse_long_t v, v2; | ||||||
|  | 	const qse_char_t* end; | ||||||
|  | 	const qse_char_t* start2 = QSE_NULL; | ||||||
|  |  | ||||||
|  | 	if (!QSE_ISDIGIT(*str) && *str != QSE_T('+'))  | ||||||
|  | 	{ | ||||||
|  | 		qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("invalid unsigned number - %s"), str); | ||||||
|  | 		return -1; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	QSE_STRTONUM (v, str, &end, 0); | ||||||
|  | 	if (pvalue2 && *end == '.') | ||||||
|  | 	{ | ||||||
|  | 		start2 = end + 1; | ||||||
|  | 		QSE_STRTONUM (v2, start2, &end, 0); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (*end != '\0') | ||||||
|  | 	{ | ||||||
|  | 		qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("invalid unsigned number - %s"), str); | ||||||
|  | 		return -1; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	*pvalue = v; | ||||||
|  | 	if (start2)  | ||||||
|  | 	{ | ||||||
|  | 		*pvalue2 = v2; | ||||||
|  | 		return (int)(end - start2); /* the value must not be very long. so i cast it to 'int' */ | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  *	Process the ATTRIBUTE command |  *	Process the ATTRIBUTE command | ||||||
|  */ |  */ | ||||||
| @ -1196,9 +1240,11 @@ static int process_attribute ( | |||||||
| 	int block_vendor, qse_raddic_attr_t* block_tlv, qse_char_t** argv, int argc) | 	int block_vendor, qse_raddic_attr_t* block_tlv, qse_char_t** argv, int argc) | ||||||
| { | { | ||||||
| 	int vendor = 0; | 	int vendor = 0; | ||||||
| 	int value; | 	unsigned int value; | ||||||
| 	int type; | 	int type; | ||||||
| 	qse_raddic_attr_flags_t flags; | 	qse_raddic_attr_flags_t flags; | ||||||
|  | 	qse_char_t* p; | ||||||
|  | 	int typelen = -1; | ||||||
|  |  | ||||||
| 	if ((argc < 3) || (argc > 4))  | 	if ((argc < 3) || (argc > 4))  | ||||||
| 	{ | 	{ | ||||||
| @ -1206,33 +1252,62 @@ static int process_attribute ( | |||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	QSE_MEMSET (&flags, 0, QSE_SIZEOF(flags)); | ||||||
|  |  | ||||||
| 	/* | 	/* | ||||||
| 	 *	Validate all entries | 	 *	Validate all entries | ||||||
| 	 */ | 	 */ | ||||||
| 	if (sscanf_i(dic, argv[1], &value) <= -1)  | 	if (sscanf_i(dic, argv[1], &value) <= -1)  | ||||||
| 	{ | 	{ | ||||||
| 		qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd]: invalid value  %s"), fn, line, argv[1]); | 		qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd]: invalid attribute value  %s"), fn, line, argv[1]); | ||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	/* | 	/* | ||||||
| 	 *	find the type of the attribute. | 	 *	find the type of the attribute. | ||||||
| 	 */ | 	 */ | ||||||
| 	type = str_to_type(dic, argv[2]); | 	p = qse_strchr(argv[2], QSE_T('[')); /* for instance, octets[20] */ | ||||||
|  | 	if (p)  | ||||||
|  | 	{ | ||||||
|  | 		qse_char_t* q; | ||||||
|  |  | ||||||
|  | 		*p = QSE_T('\0'); | ||||||
|  | 		q = qse_strchr(p + 1, QSE_T(']')); | ||||||
|  | 		if (!q || q[1] != QSE_T('\0'))  | ||||||
|  | 		{ | ||||||
|  | 			*p = QSE_T('['); | ||||||
|  | 			goto invalid_type; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		*q = QSE_T('\0'); | ||||||
|  | 		if (sscanf_i(dic, p + 1, &typelen) <= -1 || typelen <= 0 || typelen > 253) | ||||||
|  | 		{ | ||||||
|  | 			*p = QSE_T('['); | ||||||
|  | 			*q = QSE_T(']'); | ||||||
|  | 			goto invalid_type; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		flags.length = typelen; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	type = str_to_type(dic, argv[2], &typelen); | ||||||
| 	if (type < 0)  | 	if (type < 0)  | ||||||
| 	{ | 	{ | ||||||
| 		qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd]: invalid type \"%s\""), fn, line, argv[2]); | 	invalid_type: | ||||||
|  | 		qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd]: invalid attribute type \"%s\""), fn, line, argv[2]); | ||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if (flags.length <= 0 && typelen >= 0) flags.length = typelen; | ||||||
|  |  | ||||||
| 	/* | 	/* | ||||||
| 	 *	Only look up the vendor if the string | 	 *	Only look up the vendor if the string | ||||||
| 	 *	is non-empty. | 	 *	is non-empty. | ||||||
| 	 */ | 	 */ | ||||||
| 	QSE_MEMSET (&flags, 0, QSE_SIZEOF(flags)); | 	 | ||||||
| 	if (argc == 4)  | 	if (argc >= 4)  | ||||||
| 	{ | 	{ | ||||||
| 		qse_char_t* key, * next, * last; | 		qse_char_t* key, * next; | ||||||
|  |  | ||||||
| 		key = argv[3]; | 		key = argv[3]; | ||||||
| 		do  | 		do  | ||||||
| @ -1240,49 +1315,40 @@ static int process_attribute ( | |||||||
| 			next = qse_strchr(key, QSE_T(',')); | 			next = qse_strchr(key, QSE_T(',')); | ||||||
| 			if (next) *(next++) = QSE_T('\0'); | 			if (next) *(next++) = QSE_T('\0'); | ||||||
|  |  | ||||||
| 			if (qse_strcmp(key, QSE_T("has_tag")) == 0 || | 			if (qse_strcasecmp(key, QSE_T("has_tag")) == 0 || | ||||||
| 			    qse_strcmp(key, QSE_T("has_tag=1")) == 0)  | 			    qse_strcasecmp(key, QSE_T("has_tag=1")) == 0)  | ||||||
| 			{ | 			{ | ||||||
| 				/* Boolean flag, means this is a |  | ||||||
| 				   tagged attribute */ |  | ||||||
| 				flags.has_tag = 1; | 				flags.has_tag = 1; | ||||||
| 			} | 			} | ||||||
| 			else if (qse_strzcmp(key, QSE_T("encrypt="), 8) == 0)  | 			else if (qse_strzcasecmp(key, QSE_T("encrypt="), 8) == 0)  | ||||||
| 			{ | 			{ | ||||||
| 				/* Encryption method, defaults to 0 (none). | 				/* Encryption method, defaults to 0 (none). | ||||||
| 				   Currently valid is just type 2, | 				   Currently valid is just type 2, | ||||||
| 				   Tunnel-Password style, which can only | 				   Tunnel-Password style, which can only | ||||||
| 				   be applied to strings. */ | 				   be applied to strings. */ | ||||||
| 				flags.encrypt = qse_strtol(key + 8, 0); | 				unsigned int ev; | ||||||
| #if 0 | 				if (sscanf_i(dic, key + 8, &ev) <= -1 || ev < QSE_RADDIC_ATTR_FLAG_ENCRYPT_NONE || ev > QSE_RADDIC_ATTR_FLAG_ENCRYPT_OTHER) | ||||||
| 				if (*last)  |  | ||||||
| 				{ | 				{ | ||||||
| 					qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR,  QSE_T("%s[%zd] invalid option %s"), fn, line, key); | 					qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR,  QSE_T("%s[%zd] invalid option %s"), fn, line, key); | ||||||
| 					return -1; | 					return -1; | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| #endif | 				flags.encrypt = ev; | ||||||
| 			}  | 			}  | ||||||
| 			else if (qse_strcmp(key, QSE_T("array")) == 0)  | 			else if (qse_strcasecmp(key, QSE_T("array")) == 0)  | ||||||
| 			{ | 			{ | ||||||
| 				flags.array = 1; | 				flags.array = 1; | ||||||
|  | 			} | ||||||
| /* TODO: ... */ | 			else if (qse_strcasecmp(key, QSE_T("concat")) == 0)  | ||||||
| 				switch (type)  | 			{ | ||||||
| 				{ | 				flags.concat = 1; | ||||||
| 					case QSE_RADDIC_ATTR_TYPE_IPV4_ADDR: | 			} | ||||||
| 					case QSE_RADDIC_ATTR_TYPE_UINT8: | 			else if (qse_strcasecmp(key, QSE_T("internal")) == 0)  | ||||||
| 					case QSE_RADDIC_ATTR_TYPE_UINT16: | 			{ | ||||||
| 					case QSE_RADDIC_ATTR_TYPE_UINT32: | 				flags.internal = 1; | ||||||
| 					case QSE_RADDIC_ATTR_TYPE_DATE: | 			} | ||||||
| 						break; | 			else  | ||||||
|  | 			{ | ||||||
| 					default: |  | ||||||
| 						qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR,  QSE_T("%s[%zd] Only IP addresses can have the \"array\" flag set."), fn, line); |  | ||||||
| 						return -1; |  | ||||||
| 				} |  | ||||||
| 				 |  | ||||||
| 			} else { |  | ||||||
| 				qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR,  QSE_T("%s[%zd]: unknown option \"%s\""), fn, line, key); | 				qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR,  QSE_T("%s[%zd]: unknown option \"%s\""), fn, line, key); | ||||||
| 				return -1; | 				return -1; | ||||||
| 			} | 			} | ||||||
| @ -1361,7 +1427,9 @@ static int process_attribute ( | |||||||
|  |  | ||||||
| static int process_constant(qse_raddic_t* dic, const qse_char_t* fn, const qse_size_t line, qse_char_t** argv, int argc) | static int process_constant(qse_raddic_t* dic, const qse_char_t* fn, const qse_size_t line, qse_char_t** argv, int argc) | ||||||
| { | { | ||||||
| 	int value; | 	qse_raddic_const_value_t value; | ||||||
|  | 	int n; | ||||||
|  | 	qse_uint32_t v1, v2; | ||||||
|  |  | ||||||
| 	if (argc != 3)  | 	if (argc != 3)  | ||||||
| 	{ | 	{ | ||||||
| @ -1377,14 +1445,25 @@ static int process_constant(qse_raddic_t* dic, const qse_char_t* fn, const qse_s | |||||||
| 	/* | 	/* | ||||||
| 	 *	Validate all entries | 	 *	Validate all entries | ||||||
| 	 */ | 	 */ | ||||||
| 	if (sscanf_i(dic, argv[2], &value) <= -1) |  | ||||||
|  | 	if ((n = sscanf_ui32(dic, argv[2], &v1, &v2)) <= -1) | ||||||
| 	{ | 	{ | ||||||
| 		qse_strcpy (dic->errmsg2, dic->errmsg); | 		qse_strcpy (dic->errmsg2, dic->errmsg); | ||||||
| 		qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd]: invalid constant value - %s"), fn, line, dic->errmsg2); | 		qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd]: invalid constant value - %s"), fn, line, dic->errmsg2); | ||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (qse_raddic_addconst(dic, argv[1], argv[0], value) == QSE_NULL)  | 	QSE_MEMSET (&value, 0, QSE_SIZEOF(value)); | ||||||
|  | 	value.type = QSE_RADDIC_ATTR_TYPE_UINT32; | ||||||
|  | 	value.u.ui32 = v1; | ||||||
|  | 	if (n >= 1) | ||||||
|  | 	{ | ||||||
|  | 		value.type = QSE_RADDIC_ATTR_TYPE_FLOAT64; | ||||||
|  | 		value.u.f64 = (qse_flt_t)v1 + ((qse_flt_t)v2 / (pow(10, n))); /* TOOD: XXXXXXXXXXXXX device a way to prepresent this */ | ||||||
|  | 	} | ||||||
|  | 	value.type = (n == 0)? QSE_RADDIC_ATTR_TYPE_UINT32: QSE_RADDIC_ATTR_TYPE_FLOAT64; | ||||||
|  |  | ||||||
|  | 	if (qse_raddic_addconst(dic, argv[1], argv[0], &value) == QSE_NULL)  | ||||||
| 	{ | 	{ | ||||||
| 		qse_strcpy (dic->errmsg2, dic->errmsg); | 		qse_strcpy (dic->errmsg2, dic->errmsg); | ||||||
| 		qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd]: cannot add a constant - %s"), fn, line, dic->errmsg2); | 		qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd]: cannot add a constant - %s"), fn, line, dic->errmsg2); | ||||||
| @ -1508,7 +1587,7 @@ static int process_vendor (qse_raddic_t* dic, const qse_char_t* fn, const qse_si | |||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| static int load_file (qse_raddic_t* dic, const qse_char_t* dir, const qse_char_t* fn, const qse_char_t* src_file, qse_size_t src_line) | static int load_file (qse_raddic_t* dic, const qse_char_t* fn, const qse_char_t* src_file, qse_size_t src_line) | ||||||
| { | { | ||||||
| 	qse_sio_t* sio = QSE_NULL; | 	qse_sio_t* sio = QSE_NULL; | ||||||
| 	qse_char_t buf[256]; /* TODO: is this a good size? */ | 	qse_char_t buf[256]; /* TODO: is this a good size? */ | ||||||
| @ -1543,7 +1622,7 @@ static int load_file (qse_raddic_t* dic, const qse_char_t* dir, const qse_char_t | |||||||
| 		if (src_file) | 		if (src_file) | ||||||
| 			qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd]: cannot open %s"), src_file, src_line, fname); | 			qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd]: cannot open %s"), src_file, src_line, fname); | ||||||
| 		else | 		else | ||||||
| 			qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("cannot open %s"), fname); | 			qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("cannot open \"%s\""), fname); | ||||||
| 		goto oops; | 		goto oops; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @ -1568,7 +1647,7 @@ static int load_file (qse_raddic_t* dic, const qse_char_t* dir, const qse_char_t | |||||||
|  |  | ||||||
| 		if (argc == 1)  | 		if (argc == 1)  | ||||||
| 		{ | 		{ | ||||||
| 			qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR,  QSE_T("%s[%zd] invalid entry"), fname, line); | 			qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR,  QSE_T("%s[%zd] invalid entry \"%s\""), fname, line, argv[0]); | ||||||
| 			goto oops; | 			goto oops; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @ -1595,7 +1674,7 @@ static int load_file (qse_raddic_t* dic, const qse_char_t* dir, const qse_char_t | |||||||
| 		 */ | 		 */ | ||||||
| 		if (qse_strcasecmp(argv[0], QSE_T("$INCLUDE")) == 0)  | 		if (qse_strcasecmp(argv[0], QSE_T("$INCLUDE")) == 0)  | ||||||
| 		{ | 		{ | ||||||
| 			if (load_file(dic, dir, argv[1], fname, line) < 0) goto oops; | 			if (load_file(dic, argv[1], fname, line) < 0) goto oops; | ||||||
| 			continue; | 			continue; | ||||||
| 		} /* $INCLUDE */ | 		} /* $INCLUDE */ | ||||||
|  |  | ||||||
| @ -1720,5 +1799,5 @@ oops: | |||||||
|  |  | ||||||
| int qse_raddic_load (qse_raddic_t* dic, const qse_char_t* file) | int qse_raddic_load (qse_raddic_t* dic, const qse_char_t* file) | ||||||
| { | { | ||||||
| 	return load_file (dic, QSE_NULL, file, QSE_NULL, 0); | 	return load_file (dic, file, QSE_NULL, 0); | ||||||
| } | } | ||||||
|  | |||||||
| @ -187,7 +187,7 @@ static int test2 () | |||||||
| 		{ | 		{ | ||||||
| 			qse_char_t tmp[64]; | 			qse_char_t tmp[64]; | ||||||
| 			qse_strxfmt(tmp, QSE_COUNTOF(tmp), QSE_T("test-%d-%d"), j, i); | 			qse_strxfmt(tmp, QSE_COUNTOF(tmp), QSE_T("test-%d-%d"), j, i); | ||||||
| 			attr = qse_raddic_addattr (dic, tmp, j, QSE_RADDIC_ATTR_TYPE_STRING, i, &f); | 			attr = qse_raddic_addattr (dic, tmp, j, QSE_RADDIC_ATTR_TYPE_UINT32, i, &f); | ||||||
| 			_assert (attr != QSE_NULL, QSE_T("unable to add an attribute")); | 			_assert (attr != QSE_NULL, QSE_T("unable to add an attribute")); | ||||||
| 			_assert (attr->attr == QSE_RADDIC_ATTR_MAKE(j, i), QSE_T("wrong attr value")); | 			_assert (attr->attr == QSE_RADDIC_ATTR_MAKE(j, i), QSE_T("wrong attr value")); | ||||||
| 			_assert (qse_strcasecmp(attr->name, tmp) == 0, QSE_T("wrong attr name")); | 			_assert (qse_strcasecmp(attr->name, tmp) == 0, QSE_T("wrong attr name")); | ||||||
| @ -218,13 +218,13 @@ static int test2 () | |||||||
| 		{ | 		{ | ||||||
| 			qse_char_t tmp[64]; | 			qse_char_t tmp[64]; | ||||||
| 			qse_strxfmt(tmp, QSE_COUNTOF(tmp), QSE_T("testx-%d-%d"), j, i); | 			qse_strxfmt(tmp, QSE_COUNTOF(tmp), QSE_T("testx-%d-%d"), j, i); | ||||||
| 			attr = qse_raddic_addattr (dic, tmp, j, QSE_RADDIC_ATTR_TYPE_STRING, i, &f); | 			attr = qse_raddic_addattr (dic, tmp, j, QSE_RADDIC_ATTR_TYPE_UINT32, i, &f); | ||||||
| 			_assert (attr != QSE_NULL, QSE_T("unable to add an attribute")); | 			_assert (attr != QSE_NULL, QSE_T("unable to add an attribute")); | ||||||
| 			_assert (attr->attr == QSE_RADDIC_ATTR_MAKE(j, i), QSE_T("wrong attr value")); | 			_assert (attr->attr == QSE_RADDIC_ATTR_MAKE(j, i), QSE_T("wrong attr value")); | ||||||
| 			_assert (qse_strcasecmp(attr->name, tmp) == 0, QSE_T("wrong attr name")); | 			_assert (qse_strcasecmp(attr->name, tmp) == 0, QSE_T("wrong attr name")); | ||||||
|  |  | ||||||
| 			qse_strxfmt(tmp, QSE_COUNTOF(tmp), QSE_T("testy-%d-%d"), j, i); | 			qse_strxfmt(tmp, QSE_COUNTOF(tmp), QSE_T("testy-%d-%d"), j, i); | ||||||
| 			attr = qse_raddic_addattr (dic, tmp, j, QSE_RADDIC_ATTR_TYPE_STRING, i, &f); | 			attr = qse_raddic_addattr (dic, tmp, j, QSE_RADDIC_ATTR_TYPE_UINT32, i, &f); | ||||||
| 			_assert (attr != QSE_NULL, QSE_T("unable to add an attribute")); | 			_assert (attr != QSE_NULL, QSE_T("unable to add an attribute")); | ||||||
| 			_assert (attr->attr == QSE_RADDIC_ATTR_MAKE(j, i), QSE_T("wrong attr value")); | 			_assert (attr->attr == QSE_RADDIC_ATTR_MAKE(j, i), QSE_T("wrong attr value")); | ||||||
| 			_assert (qse_strcasecmp(attr->name, tmp) == 0, QSE_T("wrong attr name")); | 			_assert (qse_strcasecmp(attr->name, tmp) == 0, QSE_T("wrong attr name")); | ||||||
| @ -339,11 +339,17 @@ static int test2 () | |||||||
| 		for (i = 1; i <= 255; i++) | 		for (i = 1; i <= 255; i++) | ||||||
| 		{ | 		{ | ||||||
| 			qse_char_t constr[64], attrstr[64]; | 			qse_char_t constr[64], attrstr[64]; | ||||||
|  | 			qse_raddic_const_value_t v; | ||||||
|  |  | ||||||
|  | 			memset (&v, 0, QSE_SIZEOF(v)); | ||||||
|  | 			v.type = QSE_RADDIC_ATTR_TYPE_UINT32; | ||||||
|  | 			v.u.ui32 = 10; | ||||||
|  |  | ||||||
| 			qse_strxfmt(attrstr, QSE_COUNTOF(attrstr), QSE_T("test-%d-%d"), j, i); | 			qse_strxfmt(attrstr, QSE_COUNTOF(attrstr), QSE_T("test-%d-%d"), j, i); | ||||||
| 			qse_strxfmt(constr, QSE_COUNTOF(constr), QSE_T("const-%d-%d"), j, i); | 			qse_strxfmt(constr, QSE_COUNTOF(constr), QSE_T("const-%d-%d"), j, i); | ||||||
| 			con = qse_raddic_addconst (dic, constr, attrstr, 10); | 			con = qse_raddic_addconst (dic, constr, attrstr, &v); | ||||||
| 			_assert (con != QSE_NULL, QSE_T("unable to add an constant")); | 			_assert (con != QSE_NULL, QSE_T("unable to add an constant")); | ||||||
| 			_assert (con->value == 10, QSE_T("wrong constant value")); | 			_assert (con->value.type == QSE_RADDIC_ATTR_TYPE_UINT32 || con->value.u.ui32 == 10, QSE_T("wrong constant value")); | ||||||
| 			_assert (qse_strcasecmp(con->name, constr) == 0, QSE_T("wrong constant name")); | 			_assert (qse_strcasecmp(con->name, constr) == 0, QSE_T("wrong constant name")); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| @ -353,16 +359,22 @@ static int test2 () | |||||||
| 		for (i = 1; i <= 255; i++) | 		for (i = 1; i <= 255; i++) | ||||||
| 		{ | 		{ | ||||||
| 			qse_char_t constr[64]; | 			qse_char_t constr[64]; | ||||||
|  | 			qse_raddic_const_value_t v; | ||||||
|  |  | ||||||
|  | 			memset (&v, 0, QSE_SIZEOF(v)); | ||||||
|  | 			v.type = QSE_RADDIC_ATTR_TYPE_UINT32; | ||||||
|  | 			v.u.ui32 = 10; | ||||||
|  |  | ||||||
| 			qse_strxfmt(constr, QSE_COUNTOF(constr), QSE_T("const-%d-%d"), j, i); | 			qse_strxfmt(constr, QSE_COUNTOF(constr), QSE_T("const-%d-%d"), j, i); | ||||||
|  |  | ||||||
| 			con = qse_raddic_findconstbyname (dic, QSE_RADDIC_ATTR_MAKE(j, i), constr); | 			con = qse_raddic_findconstbyname (dic, QSE_RADDIC_ATTR_MAKE(j, i), constr); | ||||||
| 			_assert (con != QSE_NULL, QSE_T("unable to find an constant")); | 			_assert (con != QSE_NULL, QSE_T("unable to find an constant")); | ||||||
| 			_assert (con->attr == QSE_RADDIC_ATTR_MAKE(j, i), QSE_T("wrong constant value")); | 			_assert (con->attr == QSE_RADDIC_ATTR_MAKE(j, i), QSE_T("wrong constant value")); | ||||||
| 			_assert (con->value == 10, QSE_T("wrong constant value")); | 			_assert (con->value.type == QSE_RADDIC_ATTR_TYPE_UINT32 || con->value.u.ui32 == 10, QSE_T("wrong constant value")); | ||||||
|  |  | ||||||
| 			con = qse_raddic_findconstbyvalue (dic, QSE_RADDIC_ATTR_MAKE(j, i), 10); | 			con = qse_raddic_findconstbyvalue (dic, QSE_RADDIC_ATTR_MAKE(j, i), &v); | ||||||
| 			_assert (con != QSE_NULL, QSE_T("unable to find an constant")); | 			_assert (con != QSE_NULL, QSE_T("unable to find an constant")); | ||||||
| 			_assert (con->value == 10, QSE_T("wrong constant value")); | 			_assert (con->value.type == QSE_RADDIC_ATTR_TYPE_UINT32 || con->value.u.ui32 == 10, QSE_T("wrong constant value")); | ||||||
| 			_assert (con->attr == QSE_RADDIC_ATTR_MAKE(j, i), QSE_T("wrong constant value")); | 			_assert (con->attr == QSE_RADDIC_ATTR_MAKE(j, i), QSE_T("wrong constant value")); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| @ -370,19 +382,27 @@ static int test2 () | |||||||
|  |  | ||||||
| 	{ | 	{ | ||||||
| 		int n; | 		int n; | ||||||
|  | 		qse_raddic_const_value_t v; | ||||||
|  |  | ||||||
|  | 		memset (&v, 0, QSE_SIZEOF(v)); | ||||||
|  | 		v.type = QSE_RADDIC_ATTR_TYPE_UINT32; | ||||||
|  |  | ||||||
| 		n = qse_raddic_deleteconstbyname (dic, QSE_RADDIC_ATTR_MAKE(1,1), QSE_T("const-1-1")); | 		n = qse_raddic_deleteconstbyname (dic, QSE_RADDIC_ATTR_MAKE(1,1), QSE_T("const-1-1")); | ||||||
| 		_assert (n == 0, QSE_T("errorneous constant deletion failure")); | 		_assert (n == 0, QSE_T("errorneous constant deletion failure")); | ||||||
|  |  | ||||||
| 		n = qse_raddic_deleteconstbyname (dic, QSE_RADDIC_ATTR_MAKE(1,1), QSE_T("const-1-1")); | 		n = qse_raddic_deleteconstbyname (dic, QSE_RADDIC_ATTR_MAKE(1,1), QSE_T("const-1-1")); | ||||||
| 		_assert (n <= -1, QSE_T("errorneous constant deletion success")); | 		_assert (n <= -1, QSE_T("errorneous constant deletion success")); | ||||||
|  |  | ||||||
| 		n = qse_raddic_deleteconstbyvalue (dic, QSE_RADDIC_ATTR_MAKE(2,2), 20); | 		v.u.ui32 = 20; | ||||||
|  | 		n = qse_raddic_deleteconstbyvalue (dic, QSE_RADDIC_ATTR_MAKE(2,2), &v); | ||||||
| 		_assert (n <= -1, QSE_T("errorneous constant deletion success")); | 		_assert (n <= -1, QSE_T("errorneous constant deletion success")); | ||||||
|  |  | ||||||
| 		n = qse_raddic_deleteconstbyvalue (dic, QSE_RADDIC_ATTR_MAKE(2,2), 10); | 		v.u.ui32 = 10; | ||||||
|  | 		n = qse_raddic_deleteconstbyvalue (dic, QSE_RADDIC_ATTR_MAKE(2,2), &v); | ||||||
| 		_assert (n == 0, QSE_T("errorneous constant deletion success")); | 		_assert (n == 0, QSE_T("errorneous constant deletion success")); | ||||||
|  |  | ||||||
| 		n = qse_raddic_deleteconstbyvalue (dic, QSE_RADDIC_ATTR_MAKE(2,2), 10); | 		v.u.ui32 = 10; | ||||||
|  | 		n = qse_raddic_deleteconstbyvalue (dic, QSE_RADDIC_ATTR_MAKE(2,2), &v); | ||||||
| 		_assert (n <= -1, QSE_T("errorneous constant deletion success")); | 		_assert (n <= -1, QSE_T("errorneous constant deletion success")); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @ -393,6 +413,8 @@ static int test2 () | |||||||
| static int test3 () | static int test3 () | ||||||
| { | { | ||||||
| 	qse_raddic_t* dic; | 	qse_raddic_t* dic; | ||||||
|  | 	qse_raddic_vendor_t* v; | ||||||
|  | 	qse_raddic_const_t* c; | ||||||
| 	int n, trait; | 	int n, trait; | ||||||
|  |  | ||||||
| 	dic = qse_raddic_open (QSE_MMGR_GETDFL(), 0); | 	dic = qse_raddic_open (QSE_MMGR_GETDFL(), 0); | ||||||
| @ -402,9 +424,15 @@ static int test3 () | |||||||
| 	n = qse_raddic_setopt (dic, QSE_RADDIC_TRAIT, &trait); | 	n = qse_raddic_setopt (dic, QSE_RADDIC_TRAIT, &trait); | ||||||
| 	_assert (n == 0, QSE_T("cannot set trait")); | 	_assert (n == 0, QSE_T("cannot set trait")); | ||||||
|  |  | ||||||
| 	n = qse_raddic_load (dic, QSE_T("fr/dictionary")); | 	n = qse_raddic_load (dic, QSE_T("fr2/dictionary")); | ||||||
| 	_assert (n == 0, qse_raddic_geterrmsg(dic)); | 	_assert (n == 0, qse_raddic_geterrmsg(dic)); | ||||||
|  |  | ||||||
|  | 	v = qse_raddic_findvendorbyname (dic, QSE_T("cisco")); | ||||||
|  | 	_assert (v && v->vendorpec == 9, "wrong vendor value"); | ||||||
|  |  | ||||||
|  | 	c = qse_raddic_findconstbyname (dic, QSE_RADDIC_ATTR_MAKE(0,49), QSE_T("Reauthentication-Failure")); | ||||||
|  | 	_assert (c && c->value.type == QSE_RADDIC_ATTR_TYPE_UINT32 && c->value.u.ui32 == 20, QSE_T("wrong constant value")); | ||||||
|  |  | ||||||
| 	qse_raddic_close (dic); | 	qse_raddic_close (dic); | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user