blob: 035ccf7a3c403a5b8c244902f28b66e13882c8fa [file] [log] [blame]
Lev Walkincb4cd5b2006-03-14 15:23:06 +00001#include "asn1fix_internal.h"
Lev Walkinaa7f5302006-03-14 15:53:59 +00002#include "asn1fix_cws.h"
Lev Walkin9d542d22006-03-14 16:31:37 +00003
Lev Walkind370e9f2006-03-16 10:03:35 +00004static int _asn1f_parse_class_object_data(arg_t *, asn1p_expr_t *eclass,
5 struct asn1p_ioc_row_s *row, asn1p_wsyntx_t *syntax,
Lev Walkinea6635b2017-08-06 23:23:04 -07006 const uint8_t *buf, const uint8_t *bend,
Lev Walkind357f3d2017-08-10 17:40:37 -07007 int optional_mode, const uint8_t **newpos, int counter);
8static 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 -07009static 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 +080010
11int
12asn1f_check_class_object(arg_t *arg) {
13 asn1p_expr_t *expr = arg->expr;
14 asn1p_expr_t *eclass;
15 asn1p_ioc_row_t *row;
16 int ret;
17
Lev Walkinea6635b2017-08-06 23:23:04 -070018 if(expr->meta_type != AMT_VALUESET
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +080019 || expr->expr_type != A1TC_REFERENCE
20 || !expr->value
Lev Walkinea6635b2017-08-06 23:23:04 -070021 || expr->value->type != ATV_UNPARSED) {
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +080022 return 0;
Lev Walkinea6635b2017-08-06 23:23:04 -070023 }
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +080024
25 eclass = asn1f_find_terminal_type(arg, expr);
26 if(!eclass
27 || eclass->meta_type != AMT_OBJECTCLASS
28 || eclass->expr_type != A1TC_CLASSDEF) {
29 return 0;
30 }
31
32 if(!eclass->with_syntax) {
33 DEBUG("Can't process classes without %s just yet",
34 "WITH SYNTAX");
35 return 0;
36 }
37
38 row = asn1p_ioc_row_new(eclass);
39 assert(row);
40
41 ret = _asn1f_parse_class_object_data(arg, eclass, row,
42 eclass->with_syntax,
43 expr->value->value.string.buf + 1,
44 expr->value->value.string.buf
45 + expr->value->value.string.size - 1,
Lev Walkind357f3d2017-08-10 17:40:37 -070046 0, 0, 0);
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +080047
48 asn1p_ioc_row_delete(row);
49
50 return ret;
51}
Lev Walkin9d542d22006-03-14 16:31:37 +000052
Lev Walkinea6635b2017-08-06 23:23:04 -070053static int
Lev Walkin4dcf8362017-08-07 20:10:05 -070054_asn1f_is_ioc_row_duplicate(asn1p_ioc_table_t *it, asn1p_ioc_row_t *row) {
55 if(!it) {
56 return 0;
57 }
58
59 for(size_t i = 0; i < it->rows; i++) {
60 switch(asn1p_ioc_row_match(it->row[i], row)) {
Lev Walkinea6635b2017-08-06 23:23:04 -070061 default:
62 case -1:
63 return -1;
64 case 1:
65 continue;
66 case 0:
67 return 1; /* Duplicate! */
68 }
69 }
70 return 0;
71}
72
73struct parse_object_key {
74 arg_t *arg;
75 asn1p_expr_t *expr; /* InformationObjectSet */
76 asn1p_expr_t *eclass; /* CLASS */
Lev Walkind357f3d2017-08-10 17:40:37 -070077 int sequence; /* Sequence counter */
Lev Walkinea6635b2017-08-06 23:23:04 -070078};
79
Lev Walkin4dcf8362017-08-07 20:10:05 -070080/*
81 * Add to the IoC table if the row is unique.
82 */
Lev Walkinea6635b2017-08-06 23:23:04 -070083static int
Lev Walkin4dcf8362017-08-07 20:10:05 -070084_asn1f_add_unique_row(arg_t *arg, asn1p_expr_t *expr, asn1p_ioc_row_t *row) {
Lev Walkin53a28a22017-08-23 09:56:53 -070085 assert(expr->ioc_table);
Lev Walkinea6635b2017-08-06 23:23:04 -070086
Lev Walkin53a28a22017-08-23 09:56:53 -070087 /* Look for duplicates */
88 switch(_asn1f_is_ioc_row_duplicate(expr->ioc_table, row)) {
89 case -1:
90 DEBUG("Found Information Object Duplicate in %s", expr->Identifier,
91 expr->_lineno);
92 return -1;
93 case 0:
94 /* Not a duplicate */
95 break;
96 case 1:
97 /* Proper duplicate detected; ignore */
98 asn1p_ioc_row_delete(row);
99 return 0;
Lev Walkin4dcf8362017-08-07 20:10:05 -0700100 }
Lev Walkinea6635b2017-08-06 23:23:04 -0700101
Lev Walkin4dcf8362017-08-07 20:10:05 -0700102 asn1p_ioc_table_add(expr->ioc_table, row);
Lev Walkinea6635b2017-08-06 23:23:04 -0700103
104 return 0;
105}
106
107/*
108 * Given a single blob of unparsed Information Object specification, parse it
109 * into a given InformationObjectSet.
110 */
111static int
112_asn1f_parse_object_cb(const uint8_t *buf, size_t size, void *keyp) {
113 struct parse_object_key *key = keyp;
114 arg_t *arg = key->arg;
115 asn1p_expr_t *expr = key->expr;
116 asn1p_expr_t *eclass = key->eclass;
117 asn1p_ioc_row_t *row;
118 int ret;
119
Lev Walkind357f3d2017-08-10 17:40:37 -0700120 key->sequence++;
121
Lev Walkinea6635b2017-08-06 23:23:04 -0700122 row = asn1p_ioc_row_new(eclass);
123 assert(row);
124
125 ret = _asn1f_parse_class_object_data(arg, eclass, row, eclass->with_syntax,
Lev Walkind357f3d2017-08-10 17:40:37 -0700126 buf, buf + size, 0, 0, key->sequence);
Lev Walkinea6635b2017-08-06 23:23:04 -0700127 if(ret) {
128 LOG((int)(ret < 0),
129 "Cannot parse %s of CLASS %s found at line %d",
130 expr->Identifier, eclass->Identifier, expr->_lineno);
131 asn1p_ioc_row_delete(row);
132 return ret;
133 }
134
135 /* Add object to a CLASS. */
Lev Walkin4dcf8362017-08-07 20:10:05 -0700136 if(_asn1f_add_unique_row(arg, eclass, row) != 0)
Lev Walkinea6635b2017-08-06 23:23:04 -0700137 return -1;
138
139 /*
140 * Add a copy of the object to the Information Object Set.
141 */
142 row = asn1p_ioc_row_new(eclass);
143 assert(row);
144 ret = _asn1f_parse_class_object_data(arg, eclass, row, eclass->with_syntax,
Lev Walkind357f3d2017-08-10 17:40:37 -0700145 buf, buf + size, 0, 0, key->sequence);
Lev Walkinea6635b2017-08-06 23:23:04 -0700146 assert(ret == 0);
147
Lev Walkin4dcf8362017-08-07 20:10:05 -0700148 if(_asn1f_add_unique_row(arg, expr, row) != 0)
Lev Walkinea6635b2017-08-06 23:23:04 -0700149 return -1;
150
151 return 0;
152}
153
154static int
155_asn1f_foreach_unparsed_union(const asn1p_constraint_t *ct_union,
156 int (*process)(const uint8_t *buf, size_t size,
157 void *key),
158 void *key) {
159 assert(ct_union->type == ACT_CA_UNI);
160
161 for(size_t j = 0; j < ct_union->el_count; j++) {
162 const asn1p_constraint_t *ct2 = ct_union->elements[j];
163 if(ct2->type == ACT_EL_VALUE && ct2->value->type == ATV_UNPARSED) {
164 if(process
165 && process(ct2->value->value.string.buf + 1,
166 ct2->value->value.string.size - 2, key)
167 != 0) {
168 return -1;
169 }
170 continue;
171 }
172 return -1;
173 }
174
175 return 0;
176}
177
178static int
Lev Walkin53a28a22017-08-23 09:56:53 -0700179_asn1f_foreach_unparsed(arg_t *arg, const asn1p_constraint_t *ct,
Lev Walkinea6635b2017-08-06 23:23:04 -0700180 int (*process)(const uint8_t *buf, size_t size,
181 void *key),
Lev Walkinade508c2017-08-23 10:19:30 -0700182 void *keyp) {
183 struct parse_object_key *key = keyp;
Lev Walkinea6635b2017-08-06 23:23:04 -0700184 if(!ct) return -1;
Lev Walkin53a28a22017-08-23 09:56:53 -0700185
186 switch(ct->type) {
187 default:
Lev Walkinade508c2017-08-23 10:19:30 -0700188 DEBUG("Constraint is of unknown type %d for CWS", ct->type);
Lev Walkin53a28a22017-08-23 09:56:53 -0700189 return -1;
190 case ACT_EL_EXT: /* ... */
Lev Walkinade508c2017-08-23 10:19:30 -0700191 if(key) {
192 key->expr->ioc_table->extensible = 1;
193 }
Lev Walkin53a28a22017-08-23 09:56:53 -0700194 return 0;
195 case ACT_CA_UNI: /* | */
Lev Walkinade508c2017-08-23 10:19:30 -0700196 return _asn1f_foreach_unparsed_union(ct, process, keyp);
Lev Walkin53a28a22017-08-23 09:56:53 -0700197 case ACT_CA_CSV: /* , */
198 break;
Lev Walkinea6635b2017-08-06 23:23:04 -0700199 }
Lev Walkinea6635b2017-08-06 23:23:04 -0700200
201 for(size_t i = 0; i < ct->el_count; i++) {
202 const asn1p_constraint_t *ct1 = ct->elements[i];
Lev Walkinade508c2017-08-23 10:19:30 -0700203 if(_asn1f_foreach_unparsed(arg, ct1, process, keyp) != 0) {
Lev Walkinea6635b2017-08-06 23:23:04 -0700204 return -1;
205 }
206 }
207
208 return 0;
209}
210
211static int
Lev Walkin53a28a22017-08-23 09:56:53 -0700212_asn1f_constraint_looks_like_object_set(arg_t *arg,
213 const asn1p_constraint_t *ct) {
214 return 0 == _asn1f_foreach_unparsed(arg, ct, NULL, NULL);
Lev Walkinea6635b2017-08-06 23:23:04 -0700215}
216
Lev Walkind370e9f2006-03-16 10:03:35 +0000217int
218asn1f_parse_class_object(arg_t *arg) {
219 asn1p_expr_t *expr = arg->expr;
220 asn1p_expr_t *eclass;
Lev Walkinea6635b2017-08-06 23:23:04 -0700221 enum {
222 FROM_VALUE,
223 FROM_CONSTRAINT,
224 } source = FROM_VALUE;
Lev Walkind370e9f2006-03-16 10:03:35 +0000225
Lev Walkinea6635b2017-08-06 23:23:04 -0700226 if(expr->meta_type == AMT_VALUE
227 && expr->expr_type == A1TC_REFERENCE
228 && expr->value && expr->value->type == ATV_UNPARSED) {
229 source = FROM_VALUE;
230 } else if(expr->meta_type != AMT_VALUESET
231 || expr->expr_type != A1TC_REFERENCE) {
232 return 0;
233 } else if(expr->value && expr->value->type == ATV_UNPARSED) {
234 source = FROM_VALUE;
235 } else if(!expr->value) {
Lev Walkin53a28a22017-08-23 09:56:53 -0700236 if(_asn1f_constraint_looks_like_object_set(arg, expr->constraints)) {
Lev Walkinea6635b2017-08-06 23:23:04 -0700237 source = FROM_CONSTRAINT;
238 } else {
239 return 0;
240 }
241 } else {
242 return 0;
243 }
Lev Walkin9d542d22006-03-14 16:31:37 +0000244
Lev Walkind370e9f2006-03-16 10:03:35 +0000245 /*
246 * Find the governing class.
247 */
248 eclass = asn1f_find_terminal_type(arg, expr);
249 if(!eclass
250 || eclass->meta_type != AMT_OBJECTCLASS
251 || eclass->expr_type != A1TC_CLASSDEF) {
252 return 0;
253 }
254
255 DEBUG("Value %s of CLASS %s found at line %d",
256 expr->Identifier, eclass->Identifier, expr->_lineno);
257
258 if(!eclass->with_syntax) {
Lev Walkinfaf35a82006-03-16 13:37:03 +0000259 DEBUG("Can't process classes without %s just yet",
260 "WITH SYNTAX");
Lev Walkind370e9f2006-03-16 10:03:35 +0000261 return 0;
262 }
263
Lev Walkinea6635b2017-08-06 23:23:04 -0700264 struct parse_object_key key = {
265 .arg = arg,
266 .expr = expr,
267 .eclass = eclass,
Lev Walkind357f3d2017-08-10 17:40:37 -0700268 .sequence = 0
Lev Walkinea6635b2017-08-06 23:23:04 -0700269 };
Lev Walkind370e9f2006-03-16 10:03:35 +0000270
Lev Walkin53a28a22017-08-23 09:56:53 -0700271 if(!expr->ioc_table) {
272 expr->ioc_table = asn1p_ioc_table_new();
273 }
274
275 if(!eclass->ioc_table) {
276 eclass->ioc_table = asn1p_ioc_table_new();
277 }
278
Lev Walkinea6635b2017-08-06 23:23:04 -0700279 switch(source) {
280 case FROM_VALUE:
281 if(_asn1f_parse_object_cb(expr->value->value.string.buf + 1,
282 expr->value->value.string.size - 2, &key)
283 != 0) {
284 return -1;
285 }
286 break;
287 case FROM_CONSTRAINT:
Lev Walkin53a28a22017-08-23 09:56:53 -0700288 if(_asn1f_foreach_unparsed(arg, expr->constraints,
289 _asn1f_parse_object_cb, &key)
Lev Walkinea6635b2017-08-06 23:23:04 -0700290 != 0) {
291 return -1;
292 }
293 }
Lev Walkin9d542d22006-03-14 16:31:37 +0000294
295 return 0;
296}
Lev Walkind370e9f2006-03-16 10:03:35 +0000297
298#define SKIPSPACES for(; buf < bend && isspace(*buf); buf++)
299
300static int
301_asn1f_parse_class_object_data(arg_t *arg, asn1p_expr_t *eclass,
302 struct asn1p_ioc_row_s *row, asn1p_wsyntx_t *syntax,
Lev Walkinea6635b2017-08-06 23:23:04 -0700303 const uint8_t *buf, const uint8_t *bend,
Lev Walkind357f3d2017-08-10 17:40:37 -0700304 int optional_mode, const uint8_t **newpos, int counter) {
Lev Walkind370e9f2006-03-16 10:03:35 +0000305 struct asn1p_wsyntx_chunk_s *chunk;
306 int ret;
307
308 TQ_FOR(chunk, (&syntax->chunks), next) {
309 switch(chunk->type) {
310 case WC_LITERAL: {
311 int token_len = strlen(chunk->content.token);
312 SKIPSPACES;
313 if(bend - buf < token_len
314 || memcmp(buf, chunk->content.token, token_len)) {
315 if(!optional_mode) {
316 FATAL("While parsing object class value %s at line %d: Expected: \"%s\", found: \"%s\"",
317 arg->expr->Identifier, arg->expr->_lineno, chunk->content.token, buf);
318 }
319 if(newpos) *newpos = buf;
320 return -1;
321 }
322 buf += token_len;
323 } break;
324 case WC_WHITESPACE: break; /* Ignore whitespace */
325 case WC_FIELD: {
326 struct asn1p_ioc_cell_s *cell;
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800327 asn1p_wsyntx_chunk_t *next_literal;
Lev Walkinea6635b2017-08-06 23:23:04 -0700328 const uint8_t *buf_old = buf;
329 const uint8_t *p = 0;
Lev Walkinfaf35a82006-03-16 13:37:03 +0000330
331 SKIPSPACES;
332
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800333 next_literal = asn1f_next_literal_chunk(syntax, chunk, buf);
334 if(!next_literal) {
335 p += (bend - p);
336 } else {
Lev Walkinea6635b2017-08-06 23:23:04 -0700337 p = (uint8_t *)strstr((const char *)buf, (const char *)next_literal->content.token);
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800338 if(!p) {
339 if (!optional_mode)
340 FATAL("Next literal \"%s\" not found !", next_literal->content.token);
341
342 if(newpos) *newpos = buf_old;
343 return -1;
Lev Walkind370e9f2006-03-16 10:03:35 +0000344 }
345 }
Lev Walkind370e9f2006-03-16 10:03:35 +0000346 cell = asn1p_ioc_row_cell_fetch(row,
347 chunk->content.token);
348 if(cell == NULL) {
349 FATAL("Field reference %s found in WITH SYNAX {} clause does not match actual field in Object Class %s",
350 chunk->content.token,
351 eclass->Identifier, eclass->_lineno);
352 if(newpos) *newpos = buf;
353 return -1;
354 }
355 DEBUG("Reference %s satisfied by %s (%d)",
356 chunk->content.token,
357 buf, p - buf);
Lev Walkind357f3d2017-08-10 17:40:37 -0700358 ret = _asn1f_assign_cell_value(arg, cell, buf, p, counter);
Lev Walkindc4376d2006-03-16 11:04:55 +0000359 if(ret) return ret;
Lev Walkind370e9f2006-03-16 10:03:35 +0000360 buf = p;
Lev Walkindc4376d2006-03-16 11:04:55 +0000361 if(newpos) *newpos = buf;
Lev Walkind370e9f2006-03-16 10:03:35 +0000362 } break;
363 case WC_OPTIONALGROUP: {
Lev Walkinea6635b2017-08-06 23:23:04 -0700364 const uint8_t *np = 0;
Lev Walkind370e9f2006-03-16 10:03:35 +0000365 SKIPSPACES;
366 ret = _asn1f_parse_class_object_data(arg, eclass, row,
Lev Walkind357f3d2017-08-10 17:40:37 -0700367 chunk->content.syntax, buf, bend, 1, &np, counter);
Lev Walkind370e9f2006-03-16 10:03:35 +0000368 if(newpos) *newpos = np;
369 if(ret && np != buf)
370 return ret;
Lev Walkindc4376d2006-03-16 11:04:55 +0000371 buf = np;
Lev Walkind370e9f2006-03-16 10:03:35 +0000372 } break;
373 }
374 }
375
376
377 if(newpos) *newpos = buf;
378 return 0;
379}
380
381
382static int
Lev Walkin4dcf8362017-08-07 20:10:05 -0700383_asn1f_assign_cell_value(arg_t *arg, struct asn1p_ioc_cell_s *cell,
Lev Walkind357f3d2017-08-10 17:40:37 -0700384 const uint8_t *buf, const uint8_t *bend, int counter) {
Lev Walkinea6635b2017-08-06 23:23:04 -0700385 asn1p_expr_t *expr = (asn1p_expr_t *)NULL;
Lev Walkind357f3d2017-08-10 17:40:37 -0700386 char *mivr; /* Most Immediate Value Representation */
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800387 int new_ref = 1;
388 asn1p_t *asn;
389 asn1p_module_t *mod;
390 asn1p_expr_t *type_expr = (asn1p_expr_t *)NULL;
391 int i, ret = 0, psize;
392 char *pp;
Lev Walkind370e9f2006-03-16 10:03:35 +0000393
394 if((bend - buf) <= 0) {
395 FATAL("Assignment warning: empty string is being assigned into %s for %s at line %d",
396 cell->field->Identifier,
397 arg->expr->Identifier, arg->expr->_lineno);
398 return -1;
399 }
400
Lev Walkind357f3d2017-08-10 17:40:37 -0700401 mivr = malloc(bend - buf + 1);
402 assert(mivr);
403 memcpy(mivr, buf, bend - buf);
404 mivr[bend - buf] = '\0';
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800405 /* remove trailing space */
Lev Walkind357f3d2017-08-10 17:40:37 -0700406 for (i = bend - buf - 1; (i > 0) && isspace(mivr[i]); i--)
407 mivr[i] = '\0';
Lev Walkind370e9f2006-03-16 10:03:35 +0000408
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800409 /* This value 100 should be larger than following formatting string */
410 psize = bend - buf + 100;
411 pp = malloc(psize);
412 if(pp == NULL) {
Lev Walkind357f3d2017-08-10 17:40:37 -0700413 free(mivr);
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800414 return -1;
415 }
Lev Walkind370e9f2006-03-16 10:03:35 +0000416
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800417 if(cell->field->expr_type == A1TC_CLASSFIELD_TFS) {
418 ret = snprintf(pp, psize,
419 "M DEFINITIONS ::=\nBEGIN\n"
420 "V ::= %s\n"
421 "END\n",
Lev Walkind357f3d2017-08-10 17:40:37 -0700422 mivr
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800423 );
424 } else if(cell->field->expr_type == A1TC_CLASSFIELD_FTVFS) {
425 type_expr = TQ_FIRST(&(cell->field->members));
426 ret = snprintf(pp, psize,
427 "M DEFINITIONS ::=\nBEGIN\n"
428 "v %s ::= %s\n"
429 "END\n",
430 type_expr->reference ?
431 type_expr->reference->components[0].name :
432 _asn1p_expr_type2string(type_expr->expr_type),
Lev Walkind357f3d2017-08-10 17:40:37 -0700433 mivr
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800434 );
Lev Walkind370e9f2006-03-16 10:03:35 +0000435 } else {
Lev Walkind357f3d2017-08-10 17:40:37 -0700436 WARNING("asn1c only be able to parse TypeFieldSpec and FixedTypeValueFieldSpec. Failed when parsing %s at line %d\n", mivr, arg->expr->_lineno);
437 free(mivr);
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800438 free(pp);
439 return -1;
440 }
Lev Walkinea6635b2017-08-06 23:23:04 -0700441 DEBUG("ASN.1:\n\n%s\n", pp);
Bi-Ruei, Chiu3dcf05b2017-05-04 21:45:05 +0800442
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800443 assert(ret < psize);
444 psize = ret;
445
Lev Walkinbe518fa2017-09-07 02:05:28 -0700446 asn = asn1p_parse_buffer(pp, psize,
447 arg->expr->module->source_file_name, arg->expr->_lineno, A1P_NOFLAGS);
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800448 free(pp);
449 if(asn == NULL) {
450 FATAL("Cannot parse Setting token %s "
451 "at line %d",
Lev Walkind357f3d2017-08-10 17:40:37 -0700452 mivr,
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800453 arg->expr->_lineno
454 );
Lev Walkind357f3d2017-08-10 17:40:37 -0700455 free(mivr);
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800456 return -1;
457 } else {
458 mod = TQ_FIRST(&(asn->modules));
459 assert(mod);
460 expr = TQ_REMOVE(&(mod->members), next);
461 assert(expr);
462
Lev Walkinea6635b2017-08-06 23:23:04 -0700463 expr->parent_expr = NULL;
464 asn1p_expr_set_source(expr, arg->expr->module, arg->expr->_lineno);
Lev Walkind357f3d2017-08-10 17:40:37 -0700465 expr->_type_unique_index = counter;
466 DEBUG("Parsed identifier %s, mivr [%s], reference [%s] value [%s]",
467 expr->Identifier, mivr, asn1p_ref_string(expr->reference),
468 asn1f_printable_value(expr->value));
469 free(expr->Identifier);
470 if(expr->value) {
471 expr->Identifier = strdup(asn1f_printable_value(expr->value));
472 } else if (expr->reference) {
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800473 expr->Identifier = strdup(expr->reference->components[expr->reference->comp_count - 1].name);
474 } else {
Lev Walkind357f3d2017-08-10 17:40:37 -0700475 expr->Identifier = mivr;
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800476 }
477 asn1p_delete(asn);
478 }
479
480 if(expr->reference &&
Lev Walkinc0e03b92017-08-22 01:48:23 -0700481 !asn1f_lookup_symbol(arg, expr->rhs_pspecs, expr->reference)) {
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800482
483 asn1p_ref_free(expr->reference);
484 new_ref = 0;
485 expr->reference = type_expr->reference;
486 if (asn1f_value_resolve(arg, expr, 0)) {
487 expr->reference = 0;
488 asn1p_expr_free(expr);
Lev Walkind370e9f2006-03-16 10:03:35 +0000489 FATAL("Cannot find %s referenced by %s at line %d",
Lev Walkind357f3d2017-08-10 17:40:37 -0700490 mivr, arg->expr->Identifier,
Lev Walkind370e9f2006-03-16 10:03:35 +0000491 arg->expr->_lineno);
Lev Walkind357f3d2017-08-10 17:40:37 -0700492 free(mivr);
Lev Walkind370e9f2006-03-16 10:03:35 +0000493 return -1;
494 }
495 }
496
497 DEBUG("Field %s assignment of %s got %s",
Lev Walkind357f3d2017-08-10 17:40:37 -0700498 cell->field->Identifier, mivr, expr->Identifier);
Lev Walkind370e9f2006-03-16 10:03:35 +0000499
500 cell->value = expr;
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800501 cell->new_ref = new_ref;
Lev Walkind370e9f2006-03-16 10:03:35 +0000502
Lev Walkind357f3d2017-08-10 17:40:37 -0700503 if(expr->Identifier != mivr) {
504 free(mivr);
Lev Walkin4dcf8362017-08-07 20:10:05 -0700505 }
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800506
Lev Walkind370e9f2006-03-16 10:03:35 +0000507 return 0;
508}
509
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800510static asn1p_wsyntx_chunk_t *
Lev Walkinea6635b2017-08-06 23:23:04 -0700511asn1f_next_literal_chunk(asn1p_wsyntx_t *syntax, asn1p_wsyntx_chunk_t *chunk, const uint8_t *buf)
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800512{
513 asn1p_wsyntx_chunk_t *next_chunk;
514
515 next_chunk = TQ_NEXT(chunk, next);
516 do {
517 if(next_chunk == (struct asn1p_wsyntx_chunk_s *)0) {
518 if(!syntax->parent)
519 break;
520 next_chunk = TQ_NEXT(syntax->parent, next);
521 } else if(next_chunk->type == WC_LITERAL) {
Lev Walkinea6635b2017-08-06 23:23:04 -0700522 if(strstr((const char *)buf, (char *)next_chunk->content.token))
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800523 break;
524 if(!syntax->parent)
525 break;
526 next_chunk = TQ_NEXT(syntax->parent, next);
527 } else if(next_chunk->type == WC_WHITESPACE) {
528 next_chunk = TQ_NEXT(next_chunk, next);
529 } else if(next_chunk->type == WC_OPTIONALGROUP) {
530 syntax = next_chunk->content.syntax;
531 next_chunk = TQ_FIRST(((&next_chunk->content.syntax->chunks)));
532 } else
533 break;
534 } while (next_chunk);
535
536 return next_chunk;
537}