blob: e83b2f8f55bdeab42f1cdcfabc9e148e3250be05 [file] [log] [blame]
Lev Walkinf15320b2004-06-03 03:38:44 +00001#include <stdio.h>
2#include <stdlib.h>
Lev Walkina00d6b32006-03-21 03:40:38 +00003#include <string.h>
Lev Walkinf15320b2004-06-03 03:38:44 +00004#include <errno.h>
5#include <assert.h>
6
7#include "asn1parser.h"
8
Lev Walkinea6635b2017-08-06 23:23:04 -07009void
10asn1p_constraint_set_source(asn1p_constraint_t *ct,
11 struct asn1p_module_s *module, int lineno) {
12 if(ct) {
13 ct->module = module;
14 ct->_lineno = lineno;
15 asn1p_value_set_source(ct->containedSubtype,module,lineno);
16 asn1p_value_set_source(ct->value,module,lineno);
17 asn1p_value_set_source(ct->range_start,module,lineno);
18 asn1p_value_set_source(ct->range_stop,module,lineno);
19 for(size_t i = 0; i < ct->el_count; i++) {
20 asn1p_constraint_set_source(ct->elements[i], module, lineno);
21 }
22 }
23}
24
25int asn1p_constraint_compare(const asn1p_constraint_t *a,
26 const asn1p_constraint_t *b) {
Lev Walkin62d95d22017-08-06 23:41:11 -070027 (void)a;
28 (void)b;
Lev Walkinea6635b2017-08-06 23:23:04 -070029 assert(!"Constraint comparison is not implemented");
30 return -1;
31}
32
Lev Walkinf15320b2004-06-03 03:38:44 +000033asn1p_constraint_t *
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +080034asn1p_constraint_new(int _lineno, asn1p_module_t *mod) {
Lev Walkinf15320b2004-06-03 03:38:44 +000035 asn1p_constraint_t *ct;
36
37 ct = calloc(1, sizeof(*ct));
38 if(ct) {
39 ct->_lineno = _lineno;
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +080040 ct->module = mod;
Lev Walkinf15320b2004-06-03 03:38:44 +000041 }
42
43 return ct;
44}
45
46
47void
48asn1p_constraint_free(asn1p_constraint_t *ct) {
49 if(ct) {
50
Markus Elfring671eb9a2016-03-14 17:07:26 +010051 asn1p_value_free(ct->containedSubtype);
52 asn1p_value_free(ct->value);
53 asn1p_value_free(ct->range_start);
54 asn1p_value_free(ct->range_stop);
Lev Walkinf15320b2004-06-03 03:38:44 +000055
56 if(ct->elements) {
57 while(ct->el_count--) {
58 asn1p_constraint_free(
59 ct->elements[ct->el_count]);
60 }
61 free(ct->elements);
62 }
63
64 free(ct);
65 }
66}
67
68asn1p_constraint_t *
69asn1p_constraint_clone(asn1p_constraint_t *src) {
Lev Walkina00d6b32006-03-21 03:40:38 +000070 return asn1p_constraint_clone_with_resolver(src, 0, 0);
71}
72
73asn1p_constraint_t *
74asn1p_constraint_clone_with_resolver(asn1p_constraint_t *src,
75 asn1p_value_t *(*vr)(asn1p_value_t *, void *varg), void *varg) {
Lev Walkinf15320b2004-06-03 03:38:44 +000076 asn1p_constraint_t *clone;
77
Lev Walkina00d6b32006-03-21 03:40:38 +000078#define CLONE(field, func) do { if(src->field) { \
79 clone->field = func(src->field, vr, varg); \
80 if(clone->field == NULL) { \
81 asn1p_constraint_free(clone); \
82 return NULL; \
83 } \
Lev Walkinf15320b2004-06-03 03:38:44 +000084 } } while(0)
85
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +080086 clone = asn1p_constraint_new(src->_lineno, src->module);
Lev Walkinf15320b2004-06-03 03:38:44 +000087 if(clone) {
Lev Walkine972d932004-09-05 10:40:28 +000088 unsigned int i;
Lev Walkin26b6e042004-08-13 12:35:29 +000089
Lev Walkinf15320b2004-06-03 03:38:44 +000090 clone->type = src->type;
Lev Walkin26b6e042004-08-13 12:35:29 +000091 clone->presence = src->presence;
Lev Walkina00d6b32006-03-21 03:40:38 +000092 CLONE(containedSubtype, asn1p_value_clone_with_resolver);
93 CLONE(value, asn1p_value_clone_with_resolver);
94 CLONE(range_start, asn1p_value_clone_with_resolver);
95 CLONE(range_stop, asn1p_value_clone_with_resolver);
Lev Walkin26b6e042004-08-13 12:35:29 +000096
97 for(i = 0; i < src->el_count; i++) {
98 asn1p_constraint_t *t;
Lev Walkina00d6b32006-03-21 03:40:38 +000099 t = asn1p_constraint_clone_with_resolver(src->elements[i], vr, varg);
Lev Walkin26b6e042004-08-13 12:35:29 +0000100 if(!t) {
101 asn1p_constraint_free(clone);
102 return NULL;
103 }
104 if(asn1p_constraint_insert(clone, t)) {
105 asn1p_constraint_free(clone);
106 asn1p_constraint_free(t);
107 return NULL;
108 }
109 }
110 assert(clone->el_count == src->el_count);
111 clone->_lineno = src->_lineno;
Lev Walkinf15320b2004-06-03 03:38:44 +0000112 }
113
114 return clone;
115}
116
Lev Walkina00d6b32006-03-21 03:40:38 +0000117/*
118 * Make sure there's enough space to add an element.
119 */
120static int
121asn1p_constraint_make_memory(asn1p_constraint_t *ct) {
122 if(ct->el_count == ct->el_size) {
123 unsigned int newsize = ct->el_size ? ct->el_size << 2 : 4;
124 void *p;
125 p = realloc(ct->elements, newsize * sizeof(ct->elements[0]));
126 if(p) {
127 ct->elements = p;
128 ct->el_size = newsize;
129 } else {
130 return -1;
131 }
132 }
133 return 0;
134}
135
Lev Walkinf15320b2004-06-03 03:38:44 +0000136int
137asn1p_constraint_insert(asn1p_constraint_t *into, asn1p_constraint_t *what) {
138 assert(into);
139 assert(what);
140
Lev Walkina00d6b32006-03-21 03:40:38 +0000141 if(asn1p_constraint_make_memory(into))
142 return -1;
Lev Walkinf15320b2004-06-03 03:38:44 +0000143
144 into->elements[into->el_count++] = what;
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800145 what->parent_ct = into;
Lev Walkinf15320b2004-06-03 03:38:44 +0000146
147 return 0;
148}
Lev Walkinf59d0752004-08-18 04:59:12 +0000149
Lev Walkina00d6b32006-03-21 03:40:38 +0000150int
151asn1p_constraint_prepend(asn1p_constraint_t *before, asn1p_constraint_t *what) {
152 assert(before);
153 assert(what);
154
155 if(asn1p_constraint_make_memory(before))
156 return -1;
157
158 memmove(&before->elements[1], &before->elements[0],
159 before->el_count * sizeof(before->elements[0]));
160
161 before->elements[0] = what;
162 before->el_count++;
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800163 what->parent_ct = before;
Lev Walkina00d6b32006-03-21 03:40:38 +0000164
165 return 0;
166}
167
Lev Walkinf59d0752004-08-18 04:59:12 +0000168
Lev Walkinfc4f37a2017-07-31 19:57:45 -0700169const char *
Lev Walkinf59d0752004-08-18 04:59:12 +0000170asn1p_constraint_type2str(enum asn1p_constraint_type_e type) {
171 switch(type) {
172 case ACT_INVALID:
173 return "INVALID";
Lev Walkinff7dd142005-03-20 12:58:00 +0000174 case ACT_EL_TYPE:
175 return "ContainedSubtype";
Lev Walkinf59d0752004-08-18 04:59:12 +0000176 case ACT_EL_VALUE:
177 return "SingleValue";
178 case ACT_EL_RANGE:
179 case ACT_EL_LLRANGE:
180 case ACT_EL_RLRANGE:
181 case ACT_EL_ULRANGE:
182 return "ValueRange";
183 case ACT_EL_EXT:
184 return "...";
185 case ACT_CT_SIZE:
186 return "SizeConstraint";
187 case ACT_CT_FROM:
188 return "PermittedAlphabet";
189 case ACT_CT_WCOMP:
190 return "SingleTypeConstraint";
191 case ACT_CT_WCOMPS:
192 return "MultipleTypeConstraints";
Lev Walkin1893ddf2005-03-20 14:28:32 +0000193 case ACT_CT_CTDBY:
194 return "UserDefinedConstraint";
Lev Walkina9532f42006-09-17 04:52:50 +0000195 case ACT_CT_CTNG:
196 return "ContentsConstraint";
Lev Walkin5c541f12006-10-18 18:40:14 +0000197 case ACT_CT_PATTERN:
198 return "PatternConstraint";
Lev Walkinf59d0752004-08-18 04:59:12 +0000199 case ACT_CA_SET:
200 return "SET";
201 case ACT_CA_CRC:
202 return "ComponentRelationConstraint";
203 case ACT_CA_CSV:
204 return "CSV";
205 case ACT_CA_UNI:
206 return "UNION";
207 case ACT_CA_INT:
208 return "INTERSECTION";
209 case ACT_CA_EXC:
210 return "EXCEPT";
Lev Walkine4861a62005-03-24 14:29:35 +0000211 case ACT_CA_AEX:
212 return "ALL EXCEPT";
Lev Walkinf59d0752004-08-18 04:59:12 +0000213 }
214 return "UNKNOWN";
215}
Lev Walkinea6635b2017-08-06 23:23:04 -0700216
217const asn1p_constraint_t *
218asn1p_get_component_relation_constraint(asn1p_constraint_t *ct) {
219 if(ct) {
220 if(ct->type == ACT_CA_CRC)
221 return ct;
222 if(ct->type == ACT_CA_SET) {
223 for(size_t i = 0; i < ct->el_count; i++) {
224 const asn1p_constraint_t *tmp =
225 asn1p_get_component_relation_constraint(ct->elements[i]);
226 if(tmp) return tmp;
227 }
228 }
229 }
230 return NULL;
231}
232