blob: 6c04282362715886f006f440e81cd807a56c7e18 [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 Walkinea6635b2017-08-06 23:23:04 -070085
Lev Walkin4dcf8362017-08-07 20:10:05 -070086 if(expr->ioc_table == NULL) {
87 expr->ioc_table = asn1p_ioc_table_new();
88 } else {
89 /* Look for duplicates */
90
91 switch(_asn1f_is_ioc_row_duplicate(expr->ioc_table, row)) {
92 case -1:
93 DEBUG("Found Information Object Duplicate in %s", expr->Identifier,
94 expr->_lineno);
95 return -1;
96 case 0:
97 /* Not a duplicate */
98 break;
99 case 1:
100 /* Proper duplicate detected; ignore */
101 asn1p_ioc_row_delete(row);
102 return 0;
103 }
Lev Walkinea6635b2017-08-06 23:23:04 -0700104 }
105
Lev Walkin4dcf8362017-08-07 20:10:05 -0700106 asn1p_ioc_table_add(expr->ioc_table, row);
Lev Walkinea6635b2017-08-06 23:23:04 -0700107
108 return 0;
109}
110
111/*
112 * Given a single blob of unparsed Information Object specification, parse it
113 * into a given InformationObjectSet.
114 */
115static int
116_asn1f_parse_object_cb(const uint8_t *buf, size_t size, void *keyp) {
117 struct parse_object_key *key = keyp;
118 arg_t *arg = key->arg;
119 asn1p_expr_t *expr = key->expr;
120 asn1p_expr_t *eclass = key->eclass;
121 asn1p_ioc_row_t *row;
122 int ret;
123
Lev Walkind357f3d2017-08-10 17:40:37 -0700124 key->sequence++;
125
Lev Walkinea6635b2017-08-06 23:23:04 -0700126 row = asn1p_ioc_row_new(eclass);
127 assert(row);
128
129 ret = _asn1f_parse_class_object_data(arg, eclass, row, eclass->with_syntax,
Lev Walkind357f3d2017-08-10 17:40:37 -0700130 buf, buf + size, 0, 0, key->sequence);
Lev Walkinea6635b2017-08-06 23:23:04 -0700131 if(ret) {
132 LOG((int)(ret < 0),
133 "Cannot parse %s of CLASS %s found at line %d",
134 expr->Identifier, eclass->Identifier, expr->_lineno);
135 asn1p_ioc_row_delete(row);
136 return ret;
137 }
138
139 /* Add object to a CLASS. */
Lev Walkin4dcf8362017-08-07 20:10:05 -0700140 if(_asn1f_add_unique_row(arg, eclass, row) != 0)
Lev Walkinea6635b2017-08-06 23:23:04 -0700141 return -1;
142
143 /*
144 * Add a copy of the object to the Information Object Set.
145 */
146 row = asn1p_ioc_row_new(eclass);
147 assert(row);
148 ret = _asn1f_parse_class_object_data(arg, eclass, row, eclass->with_syntax,
Lev Walkind357f3d2017-08-10 17:40:37 -0700149 buf, buf + size, 0, 0, key->sequence);
Lev Walkinea6635b2017-08-06 23:23:04 -0700150 assert(ret == 0);
151
Lev Walkin4dcf8362017-08-07 20:10:05 -0700152 if(_asn1f_add_unique_row(arg, expr, row) != 0)
Lev Walkinea6635b2017-08-06 23:23:04 -0700153 return -1;
154
155 return 0;
156}
157
158static int
159_asn1f_foreach_unparsed_union(const asn1p_constraint_t *ct_union,
160 int (*process)(const uint8_t *buf, size_t size,
161 void *key),
162 void *key) {
163 assert(ct_union->type == ACT_CA_UNI);
164
165 for(size_t j = 0; j < ct_union->el_count; j++) {
166 const asn1p_constraint_t *ct2 = ct_union->elements[j];
167 if(ct2->type == ACT_EL_VALUE && ct2->value->type == ATV_UNPARSED) {
168 if(process
169 && process(ct2->value->value.string.buf + 1,
170 ct2->value->value.string.size - 2, key)
171 != 0) {
172 return -1;
173 }
174 continue;
175 }
176 return -1;
177 }
178
179 return 0;
180}
181
182static int
183_asn1f_foreach_unparsed(const asn1p_constraint_t *ct,
184 int (*process)(const uint8_t *buf, size_t size,
185 void *key),
186 void *key) {
187 if(!ct) return -1;
188 if(ct->type == ACT_CA_UNI) {
189 return _asn1f_foreach_unparsed_union(ct, process, key);
190 }
191 if(ct->type != ACT_CA_CSV) return -1;
192
193 for(size_t i = 0; i < ct->el_count; i++) {
194 const asn1p_constraint_t *ct1 = ct->elements[i];
195 switch(ct1->type) {
196 case ACT_EL_EXT:
197 break;
198 case ACT_CA_UNI:
199 if(_asn1f_foreach_unparsed_union(ct1, process, key) != 0) {
200 return -1;
201 }
202 break;
203 default:
204 return -1;
205 }
206 }
207
208 return 0;
209}
210
211static int
212_asn1f_constraint_looks_like_object_set(const asn1p_constraint_t *ct) {
213 return 0 == _asn1f_foreach_unparsed(ct, NULL, NULL);
214}
215
Lev Walkind370e9f2006-03-16 10:03:35 +0000216int
217asn1f_parse_class_object(arg_t *arg) {
218 asn1p_expr_t *expr = arg->expr;
219 asn1p_expr_t *eclass;
Lev Walkinea6635b2017-08-06 23:23:04 -0700220 enum {
221 FROM_VALUE,
222 FROM_CONSTRAINT,
223 } source = FROM_VALUE;
Lev Walkind370e9f2006-03-16 10:03:35 +0000224
Lev Walkinea6635b2017-08-06 23:23:04 -0700225 if(expr->meta_type == AMT_VALUE
226 && expr->expr_type == A1TC_REFERENCE
227 && expr->value && expr->value->type == ATV_UNPARSED) {
228 source = FROM_VALUE;
229 } else if(expr->meta_type != AMT_VALUESET
230 || expr->expr_type != A1TC_REFERENCE) {
231 return 0;
232 } else if(expr->value && expr->value->type == ATV_UNPARSED) {
233 source = FROM_VALUE;
234 } else if(!expr->value) {
235 if(_asn1f_constraint_looks_like_object_set(expr->constraints)) {
236 source = FROM_CONSTRAINT;
237 } else {
238 return 0;
239 }
240 } else {
241 return 0;
242 }
Lev Walkin9d542d22006-03-14 16:31:37 +0000243
Lev Walkind370e9f2006-03-16 10:03:35 +0000244 /*
245 * Find the governing class.
246 */
247 eclass = asn1f_find_terminal_type(arg, expr);
248 if(!eclass
249 || eclass->meta_type != AMT_OBJECTCLASS
250 || eclass->expr_type != A1TC_CLASSDEF) {
251 return 0;
252 }
253
254 DEBUG("Value %s of CLASS %s found at line %d",
255 expr->Identifier, eclass->Identifier, expr->_lineno);
256
257 if(!eclass->with_syntax) {
Lev Walkinfaf35a82006-03-16 13:37:03 +0000258 DEBUG("Can't process classes without %s just yet",
259 "WITH SYNTAX");
Lev Walkind370e9f2006-03-16 10:03:35 +0000260 return 0;
261 }
262
Lev Walkinea6635b2017-08-06 23:23:04 -0700263 struct parse_object_key key = {
264 .arg = arg,
265 .expr = expr,
266 .eclass = eclass,
Lev Walkind357f3d2017-08-10 17:40:37 -0700267 .sequence = 0
Lev Walkinea6635b2017-08-06 23:23:04 -0700268 };
Lev Walkind370e9f2006-03-16 10:03:35 +0000269
Lev Walkinea6635b2017-08-06 23:23:04 -0700270 switch(source) {
271 case FROM_VALUE:
272 if(_asn1f_parse_object_cb(expr->value->value.string.buf + 1,
273 expr->value->value.string.size - 2, &key)
274 != 0) {
275 return -1;
276 }
277 break;
278 case FROM_CONSTRAINT:
279 if(_asn1f_foreach_unparsed(expr->constraints, _asn1f_parse_object_cb,
280 &key)
281 != 0) {
282 return -1;
283 }
284 }
Lev Walkin9d542d22006-03-14 16:31:37 +0000285
286 return 0;
287}
Lev Walkind370e9f2006-03-16 10:03:35 +0000288
289#define SKIPSPACES for(; buf < bend && isspace(*buf); buf++)
290
291static int
292_asn1f_parse_class_object_data(arg_t *arg, asn1p_expr_t *eclass,
293 struct asn1p_ioc_row_s *row, asn1p_wsyntx_t *syntax,
Lev Walkinea6635b2017-08-06 23:23:04 -0700294 const uint8_t *buf, const uint8_t *bend,
Lev Walkind357f3d2017-08-10 17:40:37 -0700295 int optional_mode, const uint8_t **newpos, int counter) {
Lev Walkind370e9f2006-03-16 10:03:35 +0000296 struct asn1p_wsyntx_chunk_s *chunk;
297 int ret;
298
299 TQ_FOR(chunk, (&syntax->chunks), next) {
300 switch(chunk->type) {
301 case WC_LITERAL: {
302 int token_len = strlen(chunk->content.token);
303 SKIPSPACES;
304 if(bend - buf < token_len
305 || memcmp(buf, chunk->content.token, token_len)) {
306 if(!optional_mode) {
307 FATAL("While parsing object class value %s at line %d: Expected: \"%s\", found: \"%s\"",
308 arg->expr->Identifier, arg->expr->_lineno, chunk->content.token, buf);
309 }
310 if(newpos) *newpos = buf;
311 return -1;
312 }
313 buf += token_len;
314 } break;
315 case WC_WHITESPACE: break; /* Ignore whitespace */
316 case WC_FIELD: {
317 struct asn1p_ioc_cell_s *cell;
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800318 asn1p_wsyntx_chunk_t *next_literal;
Lev Walkinea6635b2017-08-06 23:23:04 -0700319 const uint8_t *buf_old = buf;
320 const uint8_t *p = 0;
Lev Walkinfaf35a82006-03-16 13:37:03 +0000321
322 SKIPSPACES;
323
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800324 next_literal = asn1f_next_literal_chunk(syntax, chunk, buf);
325 if(!next_literal) {
326 p += (bend - p);
327 } else {
Lev Walkinea6635b2017-08-06 23:23:04 -0700328 p = (uint8_t *)strstr((const char *)buf, (const char *)next_literal->content.token);
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800329 if(!p) {
330 if (!optional_mode)
331 FATAL("Next literal \"%s\" not found !", next_literal->content.token);
332
333 if(newpos) *newpos = buf_old;
334 return -1;
Lev Walkind370e9f2006-03-16 10:03:35 +0000335 }
336 }
Lev Walkind370e9f2006-03-16 10:03:35 +0000337 cell = asn1p_ioc_row_cell_fetch(row,
338 chunk->content.token);
339 if(cell == NULL) {
340 FATAL("Field reference %s found in WITH SYNAX {} clause does not match actual field in Object Class %s",
341 chunk->content.token,
342 eclass->Identifier, eclass->_lineno);
343 if(newpos) *newpos = buf;
344 return -1;
345 }
346 DEBUG("Reference %s satisfied by %s (%d)",
347 chunk->content.token,
348 buf, p - buf);
Lev Walkind357f3d2017-08-10 17:40:37 -0700349 ret = _asn1f_assign_cell_value(arg, cell, buf, p, counter);
Lev Walkindc4376d2006-03-16 11:04:55 +0000350 if(ret) return ret;
Lev Walkind370e9f2006-03-16 10:03:35 +0000351 buf = p;
Lev Walkindc4376d2006-03-16 11:04:55 +0000352 if(newpos) *newpos = buf;
Lev Walkind370e9f2006-03-16 10:03:35 +0000353 } break;
354 case WC_OPTIONALGROUP: {
Lev Walkinea6635b2017-08-06 23:23:04 -0700355 const uint8_t *np = 0;
Lev Walkind370e9f2006-03-16 10:03:35 +0000356 SKIPSPACES;
357 ret = _asn1f_parse_class_object_data(arg, eclass, row,
Lev Walkind357f3d2017-08-10 17:40:37 -0700358 chunk->content.syntax, buf, bend, 1, &np, counter);
Lev Walkind370e9f2006-03-16 10:03:35 +0000359 if(newpos) *newpos = np;
360 if(ret && np != buf)
361 return ret;
Lev Walkindc4376d2006-03-16 11:04:55 +0000362 buf = np;
Lev Walkind370e9f2006-03-16 10:03:35 +0000363 } break;
364 }
365 }
366
367
368 if(newpos) *newpos = buf;
369 return 0;
370}
371
372
373static int
Lev Walkin4dcf8362017-08-07 20:10:05 -0700374_asn1f_assign_cell_value(arg_t *arg, struct asn1p_ioc_cell_s *cell,
Lev Walkind357f3d2017-08-10 17:40:37 -0700375 const uint8_t *buf, const uint8_t *bend, int counter) {
Lev Walkinea6635b2017-08-06 23:23:04 -0700376 asn1p_expr_t *expr = (asn1p_expr_t *)NULL;
Lev Walkind357f3d2017-08-10 17:40:37 -0700377 char *mivr; /* Most Immediate Value Representation */
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800378 int new_ref = 1;
379 asn1p_t *asn;
380 asn1p_module_t *mod;
381 asn1p_expr_t *type_expr = (asn1p_expr_t *)NULL;
382 int i, ret = 0, psize;
383 char *pp;
Lev Walkind370e9f2006-03-16 10:03:35 +0000384
385 if((bend - buf) <= 0) {
386 FATAL("Assignment warning: empty string is being assigned into %s for %s at line %d",
387 cell->field->Identifier,
388 arg->expr->Identifier, arg->expr->_lineno);
389 return -1;
390 }
391
Lev Walkind357f3d2017-08-10 17:40:37 -0700392 mivr = malloc(bend - buf + 1);
393 assert(mivr);
394 memcpy(mivr, buf, bend - buf);
395 mivr[bend - buf] = '\0';
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800396 /* remove trailing space */
Lev Walkind357f3d2017-08-10 17:40:37 -0700397 for (i = bend - buf - 1; (i > 0) && isspace(mivr[i]); i--)
398 mivr[i] = '\0';
Lev Walkind370e9f2006-03-16 10:03:35 +0000399
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800400 /* This value 100 should be larger than following formatting string */
401 psize = bend - buf + 100;
402 pp = malloc(psize);
403 if(pp == NULL) {
Lev Walkind357f3d2017-08-10 17:40:37 -0700404 free(mivr);
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800405 return -1;
406 }
Lev Walkind370e9f2006-03-16 10:03:35 +0000407
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800408 if(cell->field->expr_type == A1TC_CLASSFIELD_TFS) {
409 ret = snprintf(pp, psize,
410 "M DEFINITIONS ::=\nBEGIN\n"
411 "V ::= %s\n"
412 "END\n",
Lev Walkind357f3d2017-08-10 17:40:37 -0700413 mivr
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800414 );
415 } else if(cell->field->expr_type == A1TC_CLASSFIELD_FTVFS) {
416 type_expr = TQ_FIRST(&(cell->field->members));
417 ret = snprintf(pp, psize,
418 "M DEFINITIONS ::=\nBEGIN\n"
419 "v %s ::= %s\n"
420 "END\n",
421 type_expr->reference ?
422 type_expr->reference->components[0].name :
423 _asn1p_expr_type2string(type_expr->expr_type),
Lev Walkind357f3d2017-08-10 17:40:37 -0700424 mivr
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800425 );
Lev Walkind370e9f2006-03-16 10:03:35 +0000426 } else {
Lev Walkind357f3d2017-08-10 17:40:37 -0700427 WARNING("asn1c only be able to parse TypeFieldSpec and FixedTypeValueFieldSpec. Failed when parsing %s at line %d\n", mivr, arg->expr->_lineno);
428 free(mivr);
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800429 free(pp);
430 return -1;
431 }
Lev Walkinea6635b2017-08-06 23:23:04 -0700432 DEBUG("ASN.1:\n\n%s\n", pp);
Bi-Ruei, Chiu3dcf05b2017-05-04 21:45:05 +0800433
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800434 assert(ret < psize);
435 psize = ret;
436
437 asn = asn1p_parse_buffer(pp, psize, A1P_NOFLAGS);
438 free(pp);
439 if(asn == NULL) {
440 FATAL("Cannot parse Setting token %s "
441 "at line %d",
Lev Walkind357f3d2017-08-10 17:40:37 -0700442 mivr,
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800443 arg->expr->_lineno
444 );
Lev Walkind357f3d2017-08-10 17:40:37 -0700445 free(mivr);
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800446 return -1;
447 } else {
448 mod = TQ_FIRST(&(asn->modules));
449 assert(mod);
450 expr = TQ_REMOVE(&(mod->members), next);
451 assert(expr);
452
Lev Walkinea6635b2017-08-06 23:23:04 -0700453 expr->parent_expr = NULL;
454 asn1p_expr_set_source(expr, arg->expr->module, arg->expr->_lineno);
Lev Walkind357f3d2017-08-10 17:40:37 -0700455 expr->_type_unique_index = counter;
456 DEBUG("Parsed identifier %s, mivr [%s], reference [%s] value [%s]",
457 expr->Identifier, mivr, asn1p_ref_string(expr->reference),
458 asn1f_printable_value(expr->value));
459 free(expr->Identifier);
460 if(expr->value) {
461 expr->Identifier = strdup(asn1f_printable_value(expr->value));
462 } else if (expr->reference) {
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800463 expr->Identifier = strdup(expr->reference->components[expr->reference->comp_count - 1].name);
464 } else {
Lev Walkind357f3d2017-08-10 17:40:37 -0700465 expr->Identifier = mivr;
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800466 }
467 asn1p_delete(asn);
468 }
469
470 if(expr->reference &&
471 !asn1f_lookup_symbol(arg, arg->mod, expr->rhs_pspecs, expr->reference)) {
472
473 asn1p_ref_free(expr->reference);
474 new_ref = 0;
475 expr->reference = type_expr->reference;
476 if (asn1f_value_resolve(arg, expr, 0)) {
477 expr->reference = 0;
478 asn1p_expr_free(expr);
Lev Walkind370e9f2006-03-16 10:03:35 +0000479 FATAL("Cannot find %s referenced by %s at line %d",
Lev Walkind357f3d2017-08-10 17:40:37 -0700480 mivr, arg->expr->Identifier,
Lev Walkind370e9f2006-03-16 10:03:35 +0000481 arg->expr->_lineno);
Lev Walkind357f3d2017-08-10 17:40:37 -0700482 free(mivr);
Lev Walkind370e9f2006-03-16 10:03:35 +0000483 return -1;
484 }
485 }
486
487 DEBUG("Field %s assignment of %s got %s",
Lev Walkind357f3d2017-08-10 17:40:37 -0700488 cell->field->Identifier, mivr, expr->Identifier);
Lev Walkind370e9f2006-03-16 10:03:35 +0000489
490 cell->value = expr;
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800491 cell->new_ref = new_ref;
Lev Walkind370e9f2006-03-16 10:03:35 +0000492
Lev Walkind357f3d2017-08-10 17:40:37 -0700493 if(expr->Identifier != mivr) {
494 free(mivr);
Lev Walkin4dcf8362017-08-07 20:10:05 -0700495 }
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800496
Lev Walkind370e9f2006-03-16 10:03:35 +0000497 return 0;
498}
499
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800500static asn1p_wsyntx_chunk_t *
Lev Walkinea6635b2017-08-06 23:23:04 -0700501asn1f_next_literal_chunk(asn1p_wsyntx_t *syntax, asn1p_wsyntx_chunk_t *chunk, const uint8_t *buf)
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800502{
503 asn1p_wsyntx_chunk_t *next_chunk;
504
505 next_chunk = TQ_NEXT(chunk, next);
506 do {
507 if(next_chunk == (struct asn1p_wsyntx_chunk_s *)0) {
508 if(!syntax->parent)
509 break;
510 next_chunk = TQ_NEXT(syntax->parent, next);
511 } else if(next_chunk->type == WC_LITERAL) {
Lev Walkinea6635b2017-08-06 23:23:04 -0700512 if(strstr((const char *)buf, (char *)next_chunk->content.token))
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800513 break;
514 if(!syntax->parent)
515 break;
516 next_chunk = TQ_NEXT(syntax->parent, next);
517 } else if(next_chunk->type == WC_WHITESPACE) {
518 next_chunk = TQ_NEXT(next_chunk, next);
519 } else if(next_chunk->type == WC_OPTIONALGROUP) {
520 syntax = next_chunk->content.syntax;
521 next_chunk = TQ_FIRST(((&next_chunk->content.syntax->chunks)));
522 } else
523 break;
524 } while (next_chunk);
525
526 return next_chunk;
527}