blob: e54eaa703bafb16cd7daa262e83172b0c29a8bd5 [file] [log] [blame]
Bi-Ruei, Chiu3e2de692017-10-19 00:41:15 +08001#include <stdio.h>
2#include <stdlib.h>
Lev Walkincb4cd5b2006-03-14 15:23:06 +00003#include "asn1fix_internal.h"
Lev Walkinaa7f5302006-03-14 15:53:59 +00004#include "asn1fix_cws.h"
Lev Walkin9d542d22006-03-14 16:31:37 +00005
Lev Walkind370e9f2006-03-16 10:03:35 +00006static int _asn1f_parse_class_object_data(arg_t *, asn1p_expr_t *eclass,
7 struct asn1p_ioc_row_s *row, asn1p_wsyntx_t *syntax,
Lev Walkinea6635b2017-08-06 23:23:04 -07008 const uint8_t *buf, const uint8_t *bend,
Lev Walkind357f3d2017-08-10 17:40:37 -07009 int optional_mode, const uint8_t **newpos, int counter);
10static int _asn1f_assign_cell_value(arg_t *arg, struct asn1p_ioc_cell_s *cell, const uint8_t *buf, const uint8_t *bend, int counter);
Lev Walkinea6635b2017-08-06 23:23:04 -070011static asn1p_wsyntx_chunk_t *asn1f_next_literal_chunk(asn1p_wsyntx_t *syntax, asn1p_wsyntx_chunk_t *chunk, const uint8_t *buf);
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +080012
13int
14asn1f_check_class_object(arg_t *arg) {
15 asn1p_expr_t *expr = arg->expr;
16 asn1p_expr_t *eclass;
17 asn1p_ioc_row_t *row;
18 int ret;
19
Lev Walkinea6635b2017-08-06 23:23:04 -070020 if(expr->meta_type != AMT_VALUESET
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +080021 || expr->expr_type != A1TC_REFERENCE
22 || !expr->value
Lev Walkinea6635b2017-08-06 23:23:04 -070023 || expr->value->type != ATV_UNPARSED) {
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +080024 return 0;
Lev Walkinea6635b2017-08-06 23:23:04 -070025 }
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +080026
27 eclass = asn1f_find_terminal_type(arg, expr);
28 if(!eclass
29 || eclass->meta_type != AMT_OBJECTCLASS
30 || eclass->expr_type != A1TC_CLASSDEF) {
31 return 0;
32 }
33
34 if(!eclass->with_syntax) {
35 DEBUG("Can't process classes without %s just yet",
36 "WITH SYNTAX");
37 return 0;
38 }
39
40 row = asn1p_ioc_row_new(eclass);
41 assert(row);
42
43 ret = _asn1f_parse_class_object_data(arg, eclass, row,
44 eclass->with_syntax,
45 expr->value->value.string.buf + 1,
46 expr->value->value.string.buf
47 + expr->value->value.string.size - 1,
Lev Walkind357f3d2017-08-10 17:40:37 -070048 0, 0, 0);
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +080049
50 asn1p_ioc_row_delete(row);
51
52 return ret;
53}
Lev Walkin9d542d22006-03-14 16:31:37 +000054
Lev Walkinea6635b2017-08-06 23:23:04 -070055static int
Lev Walkin4dcf8362017-08-07 20:10:05 -070056_asn1f_is_ioc_row_duplicate(asn1p_ioc_table_t *it, asn1p_ioc_row_t *row) {
57 if(!it) {
58 return 0;
59 }
60
61 for(size_t i = 0; i < it->rows; i++) {
62 switch(asn1p_ioc_row_match(it->row[i], row)) {
Lev Walkinea6635b2017-08-06 23:23:04 -070063 default:
64 case -1:
65 return -1;
66 case 1:
67 continue;
68 case 0:
69 return 1; /* Duplicate! */
70 }
71 }
72 return 0;
73}
74
75struct parse_object_key {
76 arg_t *arg;
77 asn1p_expr_t *expr; /* InformationObjectSet */
78 asn1p_expr_t *eclass; /* CLASS */
Lev Walkind357f3d2017-08-10 17:40:37 -070079 int sequence; /* Sequence counter */
Lev Walkinea6635b2017-08-06 23:23:04 -070080};
81
Lev Walkin4dcf8362017-08-07 20:10:05 -070082/*
83 * Add to the IoC table if the row is unique.
84 */
Lev Walkinea6635b2017-08-06 23:23:04 -070085static int
Lev Walkin4dcf8362017-08-07 20:10:05 -070086_asn1f_add_unique_row(arg_t *arg, asn1p_expr_t *expr, asn1p_ioc_row_t *row) {
Lev Walkin53a28a22017-08-23 09:56:53 -070087 assert(expr->ioc_table);
Lev Walkinea6635b2017-08-06 23:23:04 -070088
Lev Walkin53a28a22017-08-23 09:56:53 -070089 /* Look for duplicates */
90 switch(_asn1f_is_ioc_row_duplicate(expr->ioc_table, row)) {
91 case -1:
92 DEBUG("Found Information Object Duplicate in %s", expr->Identifier,
93 expr->_lineno);
94 return -1;
95 case 0:
96 /* Not a duplicate */
97 break;
98 case 1:
99 /* Proper duplicate detected; ignore */
100 asn1p_ioc_row_delete(row);
101 return 0;
Lev Walkin4dcf8362017-08-07 20:10:05 -0700102 }
Lev Walkinea6635b2017-08-06 23:23:04 -0700103
Lev Walkin4dcf8362017-08-07 20:10:05 -0700104 asn1p_ioc_table_add(expr->ioc_table, row);
Lev Walkinea6635b2017-08-06 23:23:04 -0700105
106 return 0;
107}
108
109/*
110 * Given a single blob of unparsed Information Object specification, parse it
111 * into a given InformationObjectSet.
112 */
113static int
114_asn1f_parse_object_cb(const uint8_t *buf, size_t size, void *keyp) {
115 struct parse_object_key *key = keyp;
116 arg_t *arg = key->arg;
117 asn1p_expr_t *expr = key->expr;
118 asn1p_expr_t *eclass = key->eclass;
119 asn1p_ioc_row_t *row;
120 int ret;
121
Lev Walkind357f3d2017-08-10 17:40:37 -0700122 key->sequence++;
123
Lev Walkinea6635b2017-08-06 23:23:04 -0700124 row = asn1p_ioc_row_new(eclass);
125 assert(row);
126
127 ret = _asn1f_parse_class_object_data(arg, eclass, row, eclass->with_syntax,
Lev Walkind357f3d2017-08-10 17:40:37 -0700128 buf, buf + size, 0, 0, key->sequence);
Lev Walkinea6635b2017-08-06 23:23:04 -0700129 if(ret) {
Lev Walkin48e82d12017-10-19 03:06:35 -0700130 LOG(ret, "Cannot parse %s of CLASS %s found at line %d",
131 expr->Identifier, eclass->Identifier, expr->_lineno);
132 asn1p_ioc_row_delete(row);
Lev Walkinea6635b2017-08-06 23:23:04 -0700133 return ret;
134 }
135
136 /* Add object to a CLASS. */
Lev Walkin4dcf8362017-08-07 20:10:05 -0700137 if(_asn1f_add_unique_row(arg, eclass, row) != 0)
Lev Walkinea6635b2017-08-06 23:23:04 -0700138 return -1;
139
140 /*
141 * Add a copy of the object to the Information Object Set.
142 */
143 row = asn1p_ioc_row_new(eclass);
144 assert(row);
145 ret = _asn1f_parse_class_object_data(arg, eclass, row, eclass->with_syntax,
Lev Walkind357f3d2017-08-10 17:40:37 -0700146 buf, buf + size, 0, 0, key->sequence);
Lev Walkinea6635b2017-08-06 23:23:04 -0700147 assert(ret == 0);
148
Lev Walkin4dcf8362017-08-07 20:10:05 -0700149 if(_asn1f_add_unique_row(arg, expr, row) != 0)
Lev Walkinea6635b2017-08-06 23:23:04 -0700150 return -1;
151
152 return 0;
153}
154
155static int
156_asn1f_foreach_unparsed_union(const asn1p_constraint_t *ct_union,
157 int (*process)(const uint8_t *buf, size_t size,
158 void *key),
159 void *key) {
160 assert(ct_union->type == ACT_CA_UNI);
161
162 for(size_t j = 0; j < ct_union->el_count; j++) {
163 const asn1p_constraint_t *ct2 = ct_union->elements[j];
164 if(ct2->type == ACT_EL_VALUE && ct2->value->type == ATV_UNPARSED) {
165 if(process
166 && process(ct2->value->value.string.buf + 1,
167 ct2->value->value.string.size - 2, key)
168 != 0) {
169 return -1;
170 }
171 continue;
172 }
173 return -1;
174 }
175
176 return 0;
177}
178
179static int
Lev Walkin53a28a22017-08-23 09:56:53 -0700180_asn1f_foreach_unparsed(arg_t *arg, const asn1p_constraint_t *ct,
Lev Walkinea6635b2017-08-06 23:23:04 -0700181 int (*process)(const uint8_t *buf, size_t size,
182 void *key),
Lev Walkinade508c2017-08-23 10:19:30 -0700183 void *keyp) {
184 struct parse_object_key *key = keyp;
Lev Walkinea6635b2017-08-06 23:23:04 -0700185 if(!ct) return -1;
Lev Walkin53a28a22017-08-23 09:56:53 -0700186
187 switch(ct->type) {
188 default:
Lev Walkinade508c2017-08-23 10:19:30 -0700189 DEBUG("Constraint is of unknown type %d for CWS", ct->type);
Lev Walkin53a28a22017-08-23 09:56:53 -0700190 return -1;
191 case ACT_EL_EXT: /* ... */
Lev Walkinade508c2017-08-23 10:19:30 -0700192 if(key) {
193 key->expr->ioc_table->extensible = 1;
194 }
Lev Walkin53a28a22017-08-23 09:56:53 -0700195 return 0;
196 case ACT_CA_UNI: /* | */
Lev Walkinade508c2017-08-23 10:19:30 -0700197 return _asn1f_foreach_unparsed_union(ct, process, keyp);
Lev Walkin53a28a22017-08-23 09:56:53 -0700198 case ACT_CA_CSV: /* , */
199 break;
Bi-Ruei, Chiu3e2de692017-10-19 00:41:15 +0800200 case ACT_EL_VALUE:
201 return 0;
Lev Walkinea6635b2017-08-06 23:23:04 -0700202 }
Lev Walkinea6635b2017-08-06 23:23:04 -0700203
204 for(size_t i = 0; i < ct->el_count; i++) {
205 const asn1p_constraint_t *ct1 = ct->elements[i];
Lev Walkinade508c2017-08-23 10:19:30 -0700206 if(_asn1f_foreach_unparsed(arg, ct1, process, keyp) != 0) {
Lev Walkinea6635b2017-08-06 23:23:04 -0700207 return -1;
208 }
209 }
210
211 return 0;
212}
213
214static int
Lev Walkin53a28a22017-08-23 09:56:53 -0700215_asn1f_constraint_looks_like_object_set(arg_t *arg,
216 const asn1p_constraint_t *ct) {
217 return 0 == _asn1f_foreach_unparsed(arg, ct, NULL, NULL);
Lev Walkinea6635b2017-08-06 23:23:04 -0700218}
219
Lev Walkind370e9f2006-03-16 10:03:35 +0000220int
221asn1f_parse_class_object(arg_t *arg) {
222 asn1p_expr_t *expr = arg->expr;
223 asn1p_expr_t *eclass;
Lev Walkinea6635b2017-08-06 23:23:04 -0700224 enum {
225 FROM_VALUE,
226 FROM_CONSTRAINT,
227 } source = FROM_VALUE;
Lev Walkind370e9f2006-03-16 10:03:35 +0000228
Lev Walkinea6635b2017-08-06 23:23:04 -0700229 if(expr->meta_type == AMT_VALUE
230 && expr->expr_type == A1TC_REFERENCE
231 && expr->value && expr->value->type == ATV_UNPARSED) {
232 source = FROM_VALUE;
233 } else if(expr->meta_type != AMT_VALUESET
234 || expr->expr_type != A1TC_REFERENCE) {
235 return 0;
236 } else if(expr->value && expr->value->type == ATV_UNPARSED) {
237 source = FROM_VALUE;
238 } else if(!expr->value) {
Lev Walkin53a28a22017-08-23 09:56:53 -0700239 if(_asn1f_constraint_looks_like_object_set(arg, expr->constraints)) {
Lev Walkinea6635b2017-08-06 23:23:04 -0700240 source = FROM_CONSTRAINT;
241 } else {
242 return 0;
243 }
244 } else {
245 return 0;
246 }
Lev Walkin9d542d22006-03-14 16:31:37 +0000247
Lev Walkind370e9f2006-03-16 10:03:35 +0000248 /*
249 * Find the governing class.
250 */
251 eclass = asn1f_find_terminal_type(arg, expr);
252 if(!eclass
253 || eclass->meta_type != AMT_OBJECTCLASS
254 || eclass->expr_type != A1TC_CLASSDEF) {
255 return 0;
256 }
257
258 DEBUG("Value %s of CLASS %s found at line %d",
259 expr->Identifier, eclass->Identifier, expr->_lineno);
260
261 if(!eclass->with_syntax) {
Lev Walkinfaf35a82006-03-16 13:37:03 +0000262 DEBUG("Can't process classes without %s just yet",
263 "WITH SYNTAX");
Lev Walkind370e9f2006-03-16 10:03:35 +0000264 return 0;
265 }
266
Lev Walkinea6635b2017-08-06 23:23:04 -0700267 struct parse_object_key key = {
268 .arg = arg,
269 .expr = expr,
270 .eclass = eclass,
Lev Walkind357f3d2017-08-10 17:40:37 -0700271 .sequence = 0
Lev Walkinea6635b2017-08-06 23:23:04 -0700272 };
Lev Walkind370e9f2006-03-16 10:03:35 +0000273
Lev Walkin53a28a22017-08-23 09:56:53 -0700274 if(!expr->ioc_table) {
275 expr->ioc_table = asn1p_ioc_table_new();
276 }
277
278 if(!eclass->ioc_table) {
279 eclass->ioc_table = asn1p_ioc_table_new();
280 }
281
Lev Walkinea6635b2017-08-06 23:23:04 -0700282 switch(source) {
283 case FROM_VALUE:
284 if(_asn1f_parse_object_cb(expr->value->value.string.buf + 1,
285 expr->value->value.string.size - 2, &key)
286 != 0) {
287 return -1;
288 }
289 break;
290 case FROM_CONSTRAINT:
Lev Walkin53a28a22017-08-23 09:56:53 -0700291 if(_asn1f_foreach_unparsed(arg, expr->constraints,
292 _asn1f_parse_object_cb, &key)
Lev Walkinea6635b2017-08-06 23:23:04 -0700293 != 0) {
294 return -1;
295 }
296 }
Lev Walkin9d542d22006-03-14 16:31:37 +0000297
298 return 0;
299}
Lev Walkind370e9f2006-03-16 10:03:35 +0000300
301#define SKIPSPACES for(; buf < bend && isspace(*buf); buf++)
302
303static int
304_asn1f_parse_class_object_data(arg_t *arg, asn1p_expr_t *eclass,
305 struct asn1p_ioc_row_s *row, asn1p_wsyntx_t *syntax,
Lev Walkinea6635b2017-08-06 23:23:04 -0700306 const uint8_t *buf, const uint8_t *bend,
Lev Walkind357f3d2017-08-10 17:40:37 -0700307 int optional_mode, const uint8_t **newpos, int counter) {
Lev Walkind370e9f2006-03-16 10:03:35 +0000308 struct asn1p_wsyntx_chunk_s *chunk;
309 int ret;
310
311 TQ_FOR(chunk, (&syntax->chunks), next) {
312 switch(chunk->type) {
313 case WC_LITERAL: {
314 int token_len = strlen(chunk->content.token);
315 SKIPSPACES;
316 if(bend - buf < token_len
317 || memcmp(buf, chunk->content.token, token_len)) {
318 if(!optional_mode) {
319 FATAL("While parsing object class value %s at line %d: Expected: \"%s\", found: \"%s\"",
320 arg->expr->Identifier, arg->expr->_lineno, chunk->content.token, buf);
321 }
322 if(newpos) *newpos = buf;
323 return -1;
324 }
325 buf += token_len;
326 } break;
327 case WC_WHITESPACE: break; /* Ignore whitespace */
328 case WC_FIELD: {
329 struct asn1p_ioc_cell_s *cell;
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800330 asn1p_wsyntx_chunk_t *next_literal;
Lev Walkinea6635b2017-08-06 23:23:04 -0700331 const uint8_t *buf_old = buf;
332 const uint8_t *p = 0;
Lev Walkinfaf35a82006-03-16 13:37:03 +0000333
334 SKIPSPACES;
335
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800336 next_literal = asn1f_next_literal_chunk(syntax, chunk, buf);
337 if(!next_literal) {
338 p += (bend - p);
339 } else {
Lev Walkinea6635b2017-08-06 23:23:04 -0700340 p = (uint8_t *)strstr((const char *)buf, (const char *)next_literal->content.token);
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800341 if(!p) {
342 if (!optional_mode)
343 FATAL("Next literal \"%s\" not found !", next_literal->content.token);
344
345 if(newpos) *newpos = buf_old;
346 return -1;
Lev Walkind370e9f2006-03-16 10:03:35 +0000347 }
348 }
Lev Walkind370e9f2006-03-16 10:03:35 +0000349 cell = asn1p_ioc_row_cell_fetch(row,
350 chunk->content.token);
351 if(cell == NULL) {
352 FATAL("Field reference %s found in WITH SYNAX {} clause does not match actual field in Object Class %s",
353 chunk->content.token,
354 eclass->Identifier, eclass->_lineno);
355 if(newpos) *newpos = buf;
356 return -1;
357 }
358 DEBUG("Reference %s satisfied by %s (%d)",
359 chunk->content.token,
360 buf, p - buf);
Lev Walkind357f3d2017-08-10 17:40:37 -0700361 ret = _asn1f_assign_cell_value(arg, cell, buf, p, counter);
Lev Walkindc4376d2006-03-16 11:04:55 +0000362 if(ret) return ret;
Lev Walkind370e9f2006-03-16 10:03:35 +0000363 buf = p;
Lev Walkindc4376d2006-03-16 11:04:55 +0000364 if(newpos) *newpos = buf;
Lev Walkind370e9f2006-03-16 10:03:35 +0000365 } break;
366 case WC_OPTIONALGROUP: {
Lev Walkinea6635b2017-08-06 23:23:04 -0700367 const uint8_t *np = 0;
Lev Walkind370e9f2006-03-16 10:03:35 +0000368 SKIPSPACES;
369 ret = _asn1f_parse_class_object_data(arg, eclass, row,
Lev Walkind357f3d2017-08-10 17:40:37 -0700370 chunk->content.syntax, buf, bend, 1, &np, counter);
Lev Walkind370e9f2006-03-16 10:03:35 +0000371 if(newpos) *newpos = np;
372 if(ret && np != buf)
373 return ret;
Lev Walkindc4376d2006-03-16 11:04:55 +0000374 buf = np;
Lev Walkind370e9f2006-03-16 10:03:35 +0000375 } break;
376 }
377 }
378
379
380 if(newpos) *newpos = buf;
381 return 0;
382}
383
384
385static int
Lev Walkin4dcf8362017-08-07 20:10:05 -0700386_asn1f_assign_cell_value(arg_t *arg, struct asn1p_ioc_cell_s *cell,
Lev Walkind357f3d2017-08-10 17:40:37 -0700387 const uint8_t *buf, const uint8_t *bend, int counter) {
Lev Walkinea6635b2017-08-06 23:23:04 -0700388 asn1p_expr_t *expr = (asn1p_expr_t *)NULL;
Lev Walkind357f3d2017-08-10 17:40:37 -0700389 char *mivr; /* Most Immediate Value Representation */
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800390 int new_ref = 1;
391 asn1p_t *asn;
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800392 asn1p_expr_t *type_expr = (asn1p_expr_t *)NULL;
393 int i, ret = 0, psize;
394 char *pp;
Lev Walkind370e9f2006-03-16 10:03:35 +0000395
396 if((bend - buf) <= 0) {
397 FATAL("Assignment warning: empty string is being assigned into %s for %s at line %d",
398 cell->field->Identifier,
399 arg->expr->Identifier, arg->expr->_lineno);
400 return -1;
401 }
402
Lev Walkind357f3d2017-08-10 17:40:37 -0700403 mivr = malloc(bend - buf + 1);
404 assert(mivr);
405 memcpy(mivr, buf, bend - buf);
406 mivr[bend - buf] = '\0';
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800407 /* remove trailing space */
Lev Walkind357f3d2017-08-10 17:40:37 -0700408 for (i = bend - buf - 1; (i > 0) && isspace(mivr[i]); i--)
409 mivr[i] = '\0';
Lev Walkind370e9f2006-03-16 10:03:35 +0000410
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800411 /* This value 100 should be larger than following formatting string */
412 psize = bend - buf + 100;
Bi-Ruei, Chiu3e2de692017-10-19 00:41:15 +0800413 pp = calloc(1, psize);
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800414 if(pp == NULL) {
Lev Walkind357f3d2017-08-10 17:40:37 -0700415 free(mivr);
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800416 return -1;
417 }
Lev Walkind370e9f2006-03-16 10:03:35 +0000418
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800419 if(cell->field->expr_type == A1TC_CLASSFIELD_TFS) {
420 ret = snprintf(pp, psize,
421 "M DEFINITIONS ::=\nBEGIN\n"
422 "V ::= %s\n"
423 "END\n",
Lev Walkind357f3d2017-08-10 17:40:37 -0700424 mivr
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800425 );
426 } else if(cell->field->expr_type == A1TC_CLASSFIELD_FTVFS) {
427 type_expr = TQ_FIRST(&(cell->field->members));
428 ret = snprintf(pp, psize,
429 "M DEFINITIONS ::=\nBEGIN\n"
430 "v %s ::= %s\n"
431 "END\n",
432 type_expr->reference ?
433 type_expr->reference->components[0].name :
434 _asn1p_expr_type2string(type_expr->expr_type),
Lev Walkind357f3d2017-08-10 17:40:37 -0700435 mivr
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800436 );
Lev Walkind370e9f2006-03-16 10:03:35 +0000437 } else {
Lev Walkind357f3d2017-08-10 17:40:37 -0700438 WARNING("asn1c only be able to parse TypeFieldSpec and FixedTypeValueFieldSpec. Failed when parsing %s at line %d\n", mivr, arg->expr->_lineno);
439 free(mivr);
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800440 free(pp);
441 return -1;
442 }
Lev Walkinea6635b2017-08-06 23:23:04 -0700443 DEBUG("ASN.1:\n\n%s\n", pp);
Bi-Ruei, Chiu3dcf05b2017-05-04 21:45:05 +0800444
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800445 assert(ret < psize);
446 psize = ret;
447
Lev Walkinbe518fa2017-09-07 02:05:28 -0700448 asn = asn1p_parse_buffer(pp, psize,
449 arg->expr->module->source_file_name, arg->expr->_lineno, A1P_NOFLAGS);
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800450 free(pp);
451 if(asn == NULL) {
452 FATAL("Cannot parse Setting token %s "
453 "at line %d",
Lev Walkind357f3d2017-08-10 17:40:37 -0700454 mivr,
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800455 arg->expr->_lineno
456 );
Lev Walkind357f3d2017-08-10 17:40:37 -0700457 free(mivr);
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800458 return -1;
459 } else {
Lev Walkin1a49ced2017-11-06 00:07:00 -0800460 asn1p_module_t *mod = TQ_FIRST(&(asn->modules));
461 assert(mod);
462
463 /* This member removal is safe with respect to members hash since the
464 * entire asn module will be deleted down below.
465 */
466 expr = TQ_REMOVE(&(mod->members), next);
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800467 assert(expr);
468
Lev Walkinea6635b2017-08-06 23:23:04 -0700469 expr->parent_expr = NULL;
470 asn1p_expr_set_source(expr, arg->expr->module, arg->expr->_lineno);
Lev Walkind357f3d2017-08-10 17:40:37 -0700471 expr->_type_unique_index = counter;
472 DEBUG("Parsed identifier %s, mivr [%s], reference [%s] value [%s]",
473 expr->Identifier, mivr, asn1p_ref_string(expr->reference),
474 asn1f_printable_value(expr->value));
475 free(expr->Identifier);
476 if(expr->value) {
477 expr->Identifier = strdup(asn1f_printable_value(expr->value));
478 } else if (expr->reference) {
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800479 expr->Identifier = strdup(expr->reference->components[expr->reference->comp_count - 1].name);
480 } else {
Lev Walkind357f3d2017-08-10 17:40:37 -0700481 expr->Identifier = mivr;
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800482 }
483 asn1p_delete(asn);
484 }
485
486 if(expr->reference &&
Lev Walkinc0e03b92017-08-22 01:48:23 -0700487 !asn1f_lookup_symbol(arg, expr->rhs_pspecs, expr->reference)) {
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800488
489 asn1p_ref_free(expr->reference);
490 new_ref = 0;
491 expr->reference = type_expr->reference;
492 if (asn1f_value_resolve(arg, expr, 0)) {
493 expr->reference = 0;
494 asn1p_expr_free(expr);
Lev Walkind370e9f2006-03-16 10:03:35 +0000495 FATAL("Cannot find %s referenced by %s at line %d",
Lev Walkind357f3d2017-08-10 17:40:37 -0700496 mivr, arg->expr->Identifier,
Lev Walkind370e9f2006-03-16 10:03:35 +0000497 arg->expr->_lineno);
Lev Walkind357f3d2017-08-10 17:40:37 -0700498 free(mivr);
Lev Walkind370e9f2006-03-16 10:03:35 +0000499 return -1;
500 }
501 }
502
503 DEBUG("Field %s assignment of %s got %s",
Lev Walkind357f3d2017-08-10 17:40:37 -0700504 cell->field->Identifier, mivr, expr->Identifier);
Lev Walkind370e9f2006-03-16 10:03:35 +0000505
506 cell->value = expr;
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800507 cell->new_ref = new_ref;
Lev Walkind370e9f2006-03-16 10:03:35 +0000508
Lev Walkind357f3d2017-08-10 17:40:37 -0700509 if(expr->Identifier != mivr) {
510 free(mivr);
Lev Walkin4dcf8362017-08-07 20:10:05 -0700511 }
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800512
Lev Walkind370e9f2006-03-16 10:03:35 +0000513 return 0;
514}
515
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800516static asn1p_wsyntx_chunk_t *
Lev Walkinea6635b2017-08-06 23:23:04 -0700517asn1f_next_literal_chunk(asn1p_wsyntx_t *syntax, asn1p_wsyntx_chunk_t *chunk, const uint8_t *buf)
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800518{
519 asn1p_wsyntx_chunk_t *next_chunk;
520
521 next_chunk = TQ_NEXT(chunk, next);
522 do {
523 if(next_chunk == (struct asn1p_wsyntx_chunk_s *)0) {
524 if(!syntax->parent)
525 break;
526 next_chunk = TQ_NEXT(syntax->parent, next);
527 } else if(next_chunk->type == WC_LITERAL) {
Lev Walkinea6635b2017-08-06 23:23:04 -0700528 if(strstr((const char *)buf, (char *)next_chunk->content.token))
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800529 break;
530 if(!syntax->parent)
531 break;
532 next_chunk = TQ_NEXT(syntax->parent, next);
533 } else if(next_chunk->type == WC_WHITESPACE) {
534 next_chunk = TQ_NEXT(next_chunk, next);
535 } else if(next_chunk->type == WC_OPTIONALGROUP) {
536 syntax = next_chunk->content.syntax;
537 next_chunk = TQ_FIRST(((&next_chunk->content.syntax->chunks)));
538 } else
539 break;
540 } while (next_chunk);
541
542 return next_chunk;
543}