blob: aef26c0b2fd6576a01f8b204d7dc59e11becb299 [file] [log] [blame]
Lev Walkinf15320b2004-06-03 03:38:44 +00001#include "asn1fix_internal.h"
2
3static int asn1f_check_same_children(arg_t *arg, asn1p_expr_t *a, asn1p_expr_t *b);
4
5/*
6 * Check that the expressions given are compatible in their type.
7 * ORDER DOES MATTER! (See .h).
8 */
9int
10asn1f_check_type_compatibility(arg_t *arg, asn1p_expr_t *a, asn1p_expr_t *b) {
11 asn1p_expr_type_e atype, btype;
12
13 atype = a->expr_type;
14 btype = b->expr_type;
15
16 DEBUG("%s(%s:%x@%d, %s:%x@%d)", __func__,
17 a->Identifier, atype, a->_lineno,
18 b->Identifier, btype, b->_lineno);
19
20 /*
21 * Expected terminal type!
22 */
23 assert(atype != A1TC_REFERENCE);
24 assert(btype != A1TC_REFERENCE);
25
26 if(atype != btype) {
27 /*
28 * Limited compatibility.
29 */
30 if((atype == A1TC_UNIVERVAL && btype == ASN_BASIC_INTEGER)
31 || (atype == A1TC_UNIVERVAL && btype == ASN_BASIC_ENUMERATED)
32 )
33 return 0;
34 DEBUG("\t%s and %s are not compatible",
35 a->Identifier, b->Identifier);
36 return -1; /* Fairly obviously */
37 }
38
39 if(a == b)
40 return 0; /* Fairly obviously */
41
42 switch(atype) {
43 case ASN_BASIC_INTEGER:
44 /* All integers are compatible */
45 return 0;
46 case ASN_BASIC_ENUMERATED:
47 /*
48 * Enumerations are not compatible
49 * unless their definitions are the same.
50 */
51 if(asn1f_check_same_children(arg, a, b)) {
52 DEBUG("\tEnumerations are different %s and %s",
53 a->Identifier, b->Identifier);
54 return -1;
55 }
56 return 0;
57 default:
58 /* Compatibility is not defined yet */
59 DEBUG("\tCompatibility rule is not defined for %s and %s",
60 a->Identifier, b->Identifier);
61 return -1;
62 }
63
64 return 0;
65}
66
67/*
68 * Check that the children are exactly same.
69 */
70static int
71asn1f_check_same_children(arg_t *arg, asn1p_expr_t *a, asn1p_expr_t *b) {
72 asn1p_expr_t *achild;
73 asn1p_expr_t *bchild;
74
75 achild = TQ_FIRST(&(a->members));
76 bchild = TQ_FIRST(&(b->members));
77
78 while(1) {
79 if(achild->expr_type != bchild->expr_type)
80 return -1;
81
82 if(achild->Identifier && bchild->Identifier) {
83 if(strcmp(achild->Identifier, bchild->Identifier))
84 return -1;
85 } else if(!(!achild->Identifier && !bchild->Identifier)) {
86 return -1;
87 }
88
89 if(achild->value && bchild->value) {
90 if(achild->value->type != bchild->value->type)
91 return -1;
92 switch(achild->value->type) {
93 case ATV_INTEGER:
94 if(achild->value->value.v_integer
95 != bchild->value->value.v_integer)
96 return -1;
97 break;
98 case ATV_REFERENCED:
99 default:
100 DEBUG("Value %s at lines %d and "
101 "%d cannot be used in "
102 "semantical equality check",
103 asn1f_printable_value(achild->value),
104 achild->value->value.reference->_lineno,
105 bchild->value->value.reference->_lineno
106 );
107 return -1;
108 }
109 } else if(!(!achild->value && !bchild->value)) {
110 /* One of values is defined, and another is not */
111 return -1;
112 }
113
114 achild = TQ_NEXT(achild, next);
115 bchild = TQ_NEXT(bchild, next);
116
117 if(achild && bchild)
118 continue;
119 else if(!achild && !bchild)
120 break;
121 else
122 return -1;
123 }
124
125 DEBUG("\t%s:%x@%d and %s:%x@%d are semantically equivalent",
126 a->Identifier, a->expr_type, a->_lineno,
127 b->Identifier, b->expr_type, b->_lineno);
128
129 return 0;
130}
131
132