1 #include "asn1fix_internal.h"
3 static int asn1f_check_same_children(arg_t *arg, asn1p_expr_t *a, asn1p_expr_t *b);
6 * Check that the expressions given are compatible in their type.
7 * ORDER DOES MATTER! (See .h).
10 asn1f_check_type_compatibility(arg_t *arg, asn1p_expr_t *a, asn1p_expr_t *b) {
11 asn1p_expr_type_e atype, btype;
16 DEBUG("(%s:%x@%d, %s:%x@%d)",
17 a->Identifier, atype, a->_lineno,
18 b->Identifier, btype, b->_lineno);
21 * Expected terminal type!
23 assert(atype != A1TC_REFERENCE);
24 assert(btype != A1TC_REFERENCE);
27 return 0; /* Fairly obviously */
31 * Limited cross-compatibility of integer types.
33 if((atype == A1TC_UNIVERVAL && btype == ASN_BASIC_INTEGER)
34 || (atype == A1TC_UNIVERVAL && btype == ASN_BASIC_ENUMERATED)
38 /* Limited cross-compatibility of string types */
39 if((atype & ASN_STRING_MASK)
40 && (btype & ASN_STRING_MASK)) {
42 int akm = (atype & ASN_STRING_KM_MASK)
43 || atype == ASN_STRING_UTF8String;
44 int bkm = (btype & ASN_STRING_KM_MASK)
45 || btype == ASN_STRING_UTF8String;
46 return (akm == bkm) ? 0 : -1;
49 DEBUG("\t%s and %s are not compatible",
50 a->Identifier, b->Identifier);
51 return -1; /* Fairly obviously */
55 case ASN_BASIC_INTEGER:
56 /* All integers are compatible, X.680, B.4.5 */
58 case ASN_BASIC_ENUMERATED:
60 * Enumerations are not compatible
61 * unless their definitions are the same.
63 if(asn1f_check_same_children(arg, a, b)) {
64 DEBUG("\tEnumerations are different %s and %s",
65 a->Identifier, b->Identifier);
70 if((atype & ASN_STRING_MASK)
71 && (btype & ASN_STRING_MASK)) {
72 /* String type is compatible with the same type */
75 /* Compatibility is not defined yet */
76 DEBUG("\tCompatibility rule is not defined for %s and %s",
77 a->Identifier, b->Identifier);
85 * Check that the children are exactly same.
88 asn1f_check_same_children(arg_t *arg, asn1p_expr_t *a, asn1p_expr_t *b) {
92 achild = TQ_FIRST(&(a->members));
93 bchild = TQ_FIRST(&(b->members));
96 if(achild->expr_type != bchild->expr_type)
99 if(achild->Identifier && bchild->Identifier) {
100 if(strcmp(achild->Identifier, bchild->Identifier))
102 } else if(!(!achild->Identifier && !bchild->Identifier)) {
106 if(achild->value && bchild->value) {
107 if(achild->value->type != bchild->value->type)
109 switch(achild->value->type) {
111 if(achild->value->value.v_integer
112 != bchild->value->value.v_integer)
117 DEBUG("Value %s at lines %d and "
118 "%d cannot be used in "
119 "semantical equality check",
120 asn1f_printable_value(achild->value),
121 achild->value->value.reference->_lineno,
122 bchild->value->value.reference->_lineno
126 } else if(!(!achild->value && !bchild->value)) {
127 /* One of values is defined, and another is not */
131 achild = TQ_NEXT(achild, next);
132 bchild = TQ_NEXT(bchild, next);
136 else if(!achild && !bchild)
142 DEBUG("\t%s:%x@%d and %s:%x@%d are semantically equivalent",
143 a->Identifier, a->expr_type, a->_lineno,
144 b->Identifier, b->expr_type, b->_lineno);