mirror of https://gerrit.osmocom.org/asn1c
better parsing information object class sets
This commit is contained in:
parent
e700b208bc
commit
ea6635bdae
|
@ -298,15 +298,91 @@ asn1c_lang_C_type_BIT_STRING(arg_t *arg) {
|
|||
return asn1c_lang_C_type_SIMPLE_TYPE(arg);
|
||||
}
|
||||
|
||||
/*
|
||||
* Given the table constraint or component relation constraint
|
||||
* ({ObjectSetName}{...}) returns "ObjectSetName" as a reference.
|
||||
*/
|
||||
static const asn1p_ref_t *
|
||||
asn1c_get_information_object_set_reference_from_constraint(
|
||||
const asn1p_constraint_t *ct) {
|
||||
|
||||
if(!ct) return NULL;
|
||||
assert(ct->type == ACT_CA_CRC);
|
||||
assert(ct->el_count >= 1);
|
||||
|
||||
assert(ct->elements[0]->type == ACT_EL_VALUE);
|
||||
|
||||
asn1p_value_t *val = ct->elements[0]->value;
|
||||
assert(val->type == ATV_REFERENCED);
|
||||
|
||||
return val->value.reference;
|
||||
}
|
||||
|
||||
typedef struct asn1c_ioc_table_s {
|
||||
} asn1c_ioc_table_t;
|
||||
|
||||
static asn1c_ioc_table_t *
|
||||
asn1c_construct_ioc_table_from_objset(arg_t *arg, const asn1p_ref_t *objset_ref, asn1p_expr_t *objset) {
|
||||
asn1c_ioc_table_t *itable = NULL;
|
||||
itable = calloc(1, sizeof(*itable));
|
||||
assert(itable);
|
||||
|
||||
return itable;
|
||||
};
|
||||
|
||||
static asn1c_ioc_table_t *
|
||||
asn1c_construct_ioc_table(arg_t *arg) {
|
||||
asn1p_expr_t *expr = arg->expr;
|
||||
asn1p_expr_t *memb;
|
||||
asn1p_expr_t *objset = 0;
|
||||
const asn1p_ref_t *objset_ref = NULL;
|
||||
|
||||
TQ_FOR(memb, &(expr->members), next) {
|
||||
const asn1p_ref_t *tmpref =
|
||||
asn1c_get_information_object_set_reference_from_constraint(
|
||||
asn1p_get_component_relation_constraint(memb->constraints));
|
||||
if(tmpref) {
|
||||
if(objset_ref && asn1p_ref_compare(objset_ref, tmpref) != 0) {
|
||||
FATAL(
|
||||
"Object set reference on line %d differs from object set "
|
||||
"reference on line %d",
|
||||
objset_ref->_lineno, tmpref->_lineno);
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
objset_ref = tmpref;
|
||||
}
|
||||
}
|
||||
|
||||
if(!objset_ref) {
|
||||
errno = 0; /* "Safe" error. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
objset = asn1f_lookup_symbol_ex(arg->asn, arg->expr, objset_ref);
|
||||
if(!objset) {
|
||||
FATAL("Cannot found %s", asn1p_ref_string(objset_ref));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return asn1c_construct_ioc_table_from_objset(arg, objset_ref, objset);
|
||||
}
|
||||
|
||||
int
|
||||
asn1c_lang_C_type_SEQUENCE(arg_t *arg) {
|
||||
asn1p_expr_t *expr = arg->expr;
|
||||
asn1p_expr_t *v;
|
||||
int comp_mode = 0; /* {root,ext=1,root,root,...} */
|
||||
int saved_target = arg->target->target;
|
||||
asn1c_ioc_table_t *itable = NULL;
|
||||
|
||||
DEPENDENCIES;
|
||||
|
||||
itable = asn1c_construct_ioc_table(arg);
|
||||
if(!itable && errno != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(arg->embed) {
|
||||
|
||||
/* Use _anonymous_type field to indicate it's called from
|
||||
|
@ -450,11 +526,13 @@ asn1c_lang_C_type_SEQUENCE_def(arg_t *arg) {
|
|||
++elm;
|
||||
}
|
||||
OUT(" };\n");
|
||||
if(roms_count > 65536)
|
||||
if(roms_count > 65536) {
|
||||
FATAL("Too many optional elements in %s "
|
||||
"at line %d!",
|
||||
arg->expr->Identifier,
|
||||
arg->expr->_lineno);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
roms_count = 0;
|
||||
aoms_count = 0;
|
||||
|
|
|
@ -338,18 +338,18 @@ phase_1_1(arg_t *arg, int prm2) {
|
|||
ret = asn1f_recurse_expr(arg, asn1f_fix_dereference_values);
|
||||
RET2RVAL(ret, rvalue);
|
||||
|
||||
/*
|
||||
* Parse class objects and fill up the object class with data.
|
||||
*/
|
||||
ret = asn1f_parse_class_object(arg);
|
||||
RET2RVAL(ret, rvalue);
|
||||
|
||||
/*
|
||||
* Resolve references in constraints.
|
||||
*/
|
||||
ret = asn1f_recurse_expr(arg, asn1f_resolve_constraints);
|
||||
RET2RVAL(ret, rvalue);
|
||||
|
||||
/*
|
||||
* Parse class information object sets.
|
||||
*/
|
||||
ret = asn1f_parse_class_object(arg);
|
||||
RET2RVAL(ret, rvalue);
|
||||
|
||||
/*
|
||||
* 6. INTEGER value processed at 2.5.4.
|
||||
*/
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include "asn1fix_internal.h"
|
||||
|
||||
asn1p_expr_t *
|
||||
asn1f_class_access(arg_t *arg, asn1p_module_t *mod, asn1p_expr_t *rhs_pspecs, asn1p_ref_t *ref) {
|
||||
asn1f_class_access(arg_t *arg, asn1p_module_t *mod, asn1p_expr_t *rhs_pspecs, const asn1p_ref_t *ref) {
|
||||
asn1p_expr_t *ioclass;
|
||||
asn1p_expr_t *classfield;
|
||||
asn1p_expr_t *expr;
|
||||
|
|
|
@ -4,6 +4,6 @@
|
|||
/*
|
||||
* Fetch the element from the class-related stuff (thing) by its reference.
|
||||
*/
|
||||
asn1p_expr_t *asn1f_class_access(arg_t *, asn1p_module_t *mod, asn1p_expr_t *rhs_pspecs, asn1p_ref_t *);
|
||||
asn1p_expr_t *asn1f_class_access(arg_t *, asn1p_module_t *mod, asn1p_expr_t *rhs_pspecs, const asn1p_ref_t *);
|
||||
|
||||
#endif /* ASN1FIX_CLASS_H */
|
||||
|
|
|
@ -356,7 +356,7 @@ constraint_object_resolve(arg_t *arg, asn1p_value_t *value) {
|
|||
asn1p_expr_t tmp_expr = *arg->expr;
|
||||
asn1p_expr_t *saved_expr = arg->expr;
|
||||
|
||||
tmp_expr.meta_type = AMT_VALUE;
|
||||
tmp_expr.meta_type = AMT_VALUESET;
|
||||
tmp_expr.expr_type = A1TC_REFERENCE;
|
||||
tmp_expr.value = value;
|
||||
arg->expr = &tmp_expr;
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
|
||||
static int _asn1f_parse_class_object_data(arg_t *, asn1p_expr_t *eclass,
|
||||
struct asn1p_ioc_row_s *row, asn1p_wsyntx_t *syntax,
|
||||
uint8_t *buf, const uint8_t *bend,
|
||||
int optional_mode, uint8_t **newpos);
|
||||
static int _asn1f_assign_cell_value(arg_t *arg, struct asn1p_ioc_row_s *row, struct asn1p_ioc_cell_s *cell, uint8_t *buf, const uint8_t *bend);
|
||||
static asn1p_wsyntx_chunk_t *asn1f_next_literal_chunk(asn1p_wsyntx_t *syntax, asn1p_wsyntx_chunk_t *chunk, uint8_t *buf);
|
||||
const uint8_t *buf, const uint8_t *bend,
|
||||
int optional_mode, const uint8_t **newpos);
|
||||
static int _asn1f_assign_cell_value(arg_t *arg, struct asn1p_ioc_row_s *row, struct asn1p_ioc_cell_s *cell, const uint8_t *buf, const uint8_t *bend);
|
||||
static asn1p_wsyntx_chunk_t *asn1f_next_literal_chunk(asn1p_wsyntx_t *syntax, asn1p_wsyntx_chunk_t *chunk, const uint8_t *buf);
|
||||
|
||||
int
|
||||
asn1f_check_class_object(arg_t *arg) {
|
||||
|
@ -15,11 +15,12 @@ asn1f_check_class_object(arg_t *arg) {
|
|||
asn1p_ioc_row_t *row;
|
||||
int ret;
|
||||
|
||||
if(expr->meta_type != AMT_VALUE
|
||||
if(expr->meta_type != AMT_VALUESET
|
||||
|| expr->expr_type != A1TC_REFERENCE
|
||||
|| !expr->value
|
||||
|| expr->value->type != ATV_UNPARSED)
|
||||
|| expr->value->type != ATV_UNPARSED) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
eclass = asn1f_find_terminal_type(arg, expr);
|
||||
if(!eclass
|
||||
|
@ -49,19 +50,193 @@ asn1f_check_class_object(arg_t *arg) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
_asn1f_is_ioc_row_duplicate(asn1p_ioc_row_t **rows, size_t count, asn1p_ioc_row_t *row) {
|
||||
for(size_t i = 0; i < count; i++) {
|
||||
switch(asn1p_ioc_row_match(rows[i], row)) {
|
||||
default:
|
||||
case -1:
|
||||
return -1;
|
||||
case 1:
|
||||
continue;
|
||||
case 0:
|
||||
return 1; /* Duplicate! */
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct parse_object_key {
|
||||
arg_t *arg;
|
||||
asn1p_expr_t *expr; /* InformationObjectSet */
|
||||
asn1p_expr_t *eclass; /* CLASS */
|
||||
};
|
||||
|
||||
static int
|
||||
_asn1f_add_row(arg_t *arg, asn1p_expr_t *expr, asn1p_ioc_row_t *row) {
|
||||
void *new_rows_ptr;
|
||||
|
||||
switch(_asn1f_is_ioc_row_duplicate(expr->object_class_matrix.row,
|
||||
expr->object_class_matrix.rows, row)) {
|
||||
case -1:
|
||||
DEBUG("Found Information Object Duplicate in %s", expr->Identifier,
|
||||
expr->_lineno);
|
||||
return -1;
|
||||
case 0:
|
||||
/* Not a duplicate */
|
||||
break;
|
||||
case 1:
|
||||
/* Proper duplicate detected; ignore */
|
||||
asn1p_ioc_row_delete(row);
|
||||
return 0;
|
||||
}
|
||||
|
||||
new_rows_ptr = realloc(expr->object_class_matrix.row,
|
||||
(expr->object_class_matrix.rows + 1)
|
||||
* sizeof(expr->object_class_matrix.row[0]));
|
||||
assert(new_rows_ptr);
|
||||
expr->object_class_matrix.row = new_rows_ptr;
|
||||
expr->object_class_matrix.row[expr->object_class_matrix.rows] = row;
|
||||
expr->object_class_matrix.rows++;
|
||||
/* Propagate max identifier length */
|
||||
if(expr->object_class_matrix.max_identifier_length
|
||||
< row->max_identifier_length)
|
||||
expr->object_class_matrix.max_identifier_length
|
||||
= row->max_identifier_length;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a single blob of unparsed Information Object specification, parse it
|
||||
* into a given InformationObjectSet.
|
||||
*/
|
||||
static int
|
||||
_asn1f_parse_object_cb(const uint8_t *buf, size_t size, void *keyp) {
|
||||
struct parse_object_key *key = keyp;
|
||||
arg_t *arg = key->arg;
|
||||
asn1p_expr_t *expr = key->expr;
|
||||
asn1p_expr_t *eclass = key->eclass;
|
||||
asn1p_ioc_row_t *row;
|
||||
int ret;
|
||||
|
||||
row = asn1p_ioc_row_new(eclass);
|
||||
assert(row);
|
||||
|
||||
ret = _asn1f_parse_class_object_data(arg, eclass, row, eclass->with_syntax,
|
||||
buf, buf + size, 0, 0);
|
||||
if(ret) {
|
||||
LOG((int)(ret < 0),
|
||||
"Cannot parse %s of CLASS %s found at line %d",
|
||||
expr->Identifier, eclass->Identifier, expr->_lineno);
|
||||
asn1p_ioc_row_delete(row);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Add object to a CLASS. */
|
||||
if(_asn1f_add_row(arg, eclass, row) != 0)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* Add a copy of the object to the Information Object Set.
|
||||
*/
|
||||
row = asn1p_ioc_row_new(eclass);
|
||||
assert(row);
|
||||
ret = _asn1f_parse_class_object_data(arg, eclass, row, eclass->with_syntax,
|
||||
buf, buf + size, 0, 0);
|
||||
assert(ret == 0);
|
||||
|
||||
if(_asn1f_add_row(arg, expr, row) != 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
_asn1f_foreach_unparsed_union(const asn1p_constraint_t *ct_union,
|
||||
int (*process)(const uint8_t *buf, size_t size,
|
||||
void *key),
|
||||
void *key) {
|
||||
assert(ct_union->type == ACT_CA_UNI);
|
||||
|
||||
for(size_t j = 0; j < ct_union->el_count; j++) {
|
||||
const asn1p_constraint_t *ct2 = ct_union->elements[j];
|
||||
if(ct2->type == ACT_EL_VALUE && ct2->value->type == ATV_UNPARSED) {
|
||||
if(process
|
||||
&& process(ct2->value->value.string.buf + 1,
|
||||
ct2->value->value.string.size - 2, key)
|
||||
!= 0) {
|
||||
return -1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
_asn1f_foreach_unparsed(const asn1p_constraint_t *ct,
|
||||
int (*process)(const uint8_t *buf, size_t size,
|
||||
void *key),
|
||||
void *key) {
|
||||
if(!ct) return -1;
|
||||
if(ct->type == ACT_CA_UNI) {
|
||||
return _asn1f_foreach_unparsed_union(ct, process, key);
|
||||
}
|
||||
if(ct->type != ACT_CA_CSV) return -1;
|
||||
|
||||
for(size_t i = 0; i < ct->el_count; i++) {
|
||||
const asn1p_constraint_t *ct1 = ct->elements[i];
|
||||
switch(ct1->type) {
|
||||
case ACT_EL_EXT:
|
||||
break;
|
||||
case ACT_CA_UNI:
|
||||
if(_asn1f_foreach_unparsed_union(ct1, process, key) != 0) {
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
_asn1f_constraint_looks_like_object_set(const asn1p_constraint_t *ct) {
|
||||
return 0 == _asn1f_foreach_unparsed(ct, NULL, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
asn1f_parse_class_object(arg_t *arg) {
|
||||
asn1p_expr_t *expr = arg->expr;
|
||||
asn1p_expr_t *eclass;
|
||||
asn1p_ioc_row_t *row;
|
||||
void *new_rows_ptr;
|
||||
int ret;
|
||||
enum {
|
||||
FROM_VALUE,
|
||||
FROM_CONSTRAINT,
|
||||
} source = FROM_VALUE;
|
||||
|
||||
if(expr->meta_type != AMT_VALUE
|
||||
|| expr->expr_type != A1TC_REFERENCE
|
||||
|| !expr->value
|
||||
|| expr->value->type != ATV_UNPARSED)
|
||||
return 0;
|
||||
if(expr->meta_type == AMT_VALUE
|
||||
&& expr->expr_type == A1TC_REFERENCE
|
||||
&& expr->value && expr->value->type == ATV_UNPARSED) {
|
||||
source = FROM_VALUE;
|
||||
} else if(expr->meta_type != AMT_VALUESET
|
||||
|| expr->expr_type != A1TC_REFERENCE) {
|
||||
return 0;
|
||||
} else if(expr->value && expr->value->type == ATV_UNPARSED) {
|
||||
source = FROM_VALUE;
|
||||
} else if(!expr->value) {
|
||||
if(_asn1f_constraint_looks_like_object_set(expr->constraints)) {
|
||||
source = FROM_CONSTRAINT;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the governing class.
|
||||
|
@ -82,35 +257,27 @@ asn1f_parse_class_object(arg_t *arg) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
row = asn1p_ioc_row_new(eclass);
|
||||
assert(row);
|
||||
struct parse_object_key key = {
|
||||
.arg = arg,
|
||||
.expr = expr,
|
||||
.eclass = eclass,
|
||||
};
|
||||
|
||||
ret = _asn1f_parse_class_object_data(arg, eclass, row,
|
||||
eclass->with_syntax,
|
||||
expr->value->value.string.buf + 1,
|
||||
expr->value->value.string.buf
|
||||
+ expr->value->value.string.size - 1,
|
||||
0, 0);
|
||||
if(ret) {
|
||||
LOG((int)(ret < 0),
|
||||
"Cannot parse %s of CLASS %s found at line %d",
|
||||
expr->Identifier, eclass->Identifier, expr->_lineno);
|
||||
asn1p_ioc_row_delete(row);
|
||||
return ret;
|
||||
}
|
||||
|
||||
new_rows_ptr = realloc(eclass->object_class_matrix.row,
|
||||
(eclass->object_class_matrix.rows + 1)
|
||||
* sizeof(eclass->object_class_matrix.row[0]));
|
||||
assert(new_rows_ptr);
|
||||
eclass->object_class_matrix.row = new_rows_ptr;
|
||||
eclass->object_class_matrix.row[eclass->object_class_matrix.rows] = row;
|
||||
eclass->object_class_matrix.rows++;
|
||||
/* Propagate max identifier length */
|
||||
if(eclass->object_class_matrix.max_identifier_length
|
||||
< row->max_identifier_length)
|
||||
eclass->object_class_matrix.max_identifier_length
|
||||
= row->max_identifier_length;
|
||||
switch(source) {
|
||||
case FROM_VALUE:
|
||||
if(_asn1f_parse_object_cb(expr->value->value.string.buf + 1,
|
||||
expr->value->value.string.size - 2, &key)
|
||||
!= 0) {
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case FROM_CONSTRAINT:
|
||||
if(_asn1f_foreach_unparsed(expr->constraints, _asn1f_parse_object_cb,
|
||||
&key)
|
||||
!= 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -120,8 +287,8 @@ asn1f_parse_class_object(arg_t *arg) {
|
|||
static int
|
||||
_asn1f_parse_class_object_data(arg_t *arg, asn1p_expr_t *eclass,
|
||||
struct asn1p_ioc_row_s *row, asn1p_wsyntx_t *syntax,
|
||||
uint8_t *buf, const uint8_t *bend,
|
||||
int optional_mode, uint8_t **newpos) {
|
||||
const uint8_t *buf, const uint8_t *bend,
|
||||
int optional_mode, const uint8_t **newpos) {
|
||||
struct asn1p_wsyntx_chunk_s *chunk;
|
||||
int ret;
|
||||
|
||||
|
@ -145,8 +312,8 @@ _asn1f_parse_class_object_data(arg_t *arg, asn1p_expr_t *eclass,
|
|||
case WC_FIELD: {
|
||||
struct asn1p_ioc_cell_s *cell;
|
||||
asn1p_wsyntx_chunk_t *next_literal;
|
||||
uint8_t *buf_old = buf;
|
||||
uint8_t *p = 0;
|
||||
const uint8_t *buf_old = buf;
|
||||
const uint8_t *p = 0;
|
||||
|
||||
SKIPSPACES;
|
||||
|
||||
|
@ -154,7 +321,7 @@ _asn1f_parse_class_object_data(arg_t *arg, asn1p_expr_t *eclass,
|
|||
if(!next_literal) {
|
||||
p += (bend - p);
|
||||
} else {
|
||||
p = (uint8_t *)strstr((char *)buf, (char *)next_literal->content.token);
|
||||
p = (uint8_t *)strstr((const char *)buf, (const char *)next_literal->content.token);
|
||||
if(!p) {
|
||||
if (!optional_mode)
|
||||
FATAL("Next literal \"%s\" not found !", next_literal->content.token);
|
||||
|
@ -181,7 +348,7 @@ _asn1f_parse_class_object_data(arg_t *arg, asn1p_expr_t *eclass,
|
|||
if(newpos) *newpos = buf;
|
||||
} break;
|
||||
case WC_OPTIONALGROUP: {
|
||||
uint8_t *np = 0;
|
||||
const uint8_t *np = 0;
|
||||
SKIPSPACES;
|
||||
ret = _asn1f_parse_class_object_data(arg, eclass, row,
|
||||
chunk->content.syntax, buf, bend, 1, &np);
|
||||
|
@ -200,9 +367,10 @@ _asn1f_parse_class_object_data(arg_t *arg, asn1p_expr_t *eclass,
|
|||
|
||||
|
||||
static int
|
||||
_asn1f_assign_cell_value(arg_t *arg, struct asn1p_ioc_row_s *row, struct asn1p_ioc_cell_s *cell,
|
||||
uint8_t *buf, const uint8_t *bend) {
|
||||
asn1p_expr_t *expr = (asn1p_expr_t *)NULL;
|
||||
_asn1f_assign_cell_value(arg_t *arg, struct asn1p_ioc_row_s *row,
|
||||
struct asn1p_ioc_cell_s *cell, const uint8_t *buf,
|
||||
const uint8_t *bend) {
|
||||
asn1p_expr_t *expr = (asn1p_expr_t *)NULL;
|
||||
int idLength;
|
||||
char *p;
|
||||
int new_ref = 1;
|
||||
|
@ -259,7 +427,7 @@ _asn1f_assign_cell_value(arg_t *arg, struct asn1p_ioc_row_s *row, struct asn1p_i
|
|||
free(pp);
|
||||
return -1;
|
||||
}
|
||||
DEBUG("ASN.1 :\n\n%s\n", pp);
|
||||
DEBUG("ASN.1:\n\n%s\n", pp);
|
||||
|
||||
assert(ret < psize);
|
||||
psize = ret;
|
||||
|
@ -281,11 +449,9 @@ _asn1f_assign_cell_value(arg_t *arg, struct asn1p_ioc_row_s *row, struct asn1p_i
|
|||
assert(expr);
|
||||
|
||||
free(expr->Identifier);
|
||||
expr->module = arg->expr->module;
|
||||
expr->_lineno = arg->expr->_lineno;
|
||||
expr->parent_expr = NULL;
|
||||
asn1p_expr_set_source(expr, arg->expr->module, arg->expr->_lineno);
|
||||
if (expr->reference) {
|
||||
expr->reference->module = arg->expr->module;
|
||||
expr->reference->_lineno = arg->expr->_lineno;
|
||||
expr->Identifier = strdup(expr->reference->components[expr->reference->comp_count - 1].name);
|
||||
} else {
|
||||
expr->Identifier = p;
|
||||
|
@ -327,7 +493,7 @@ _asn1f_assign_cell_value(arg_t *arg, struct asn1p_ioc_row_s *row, struct asn1p_i
|
|||
}
|
||||
|
||||
static asn1p_wsyntx_chunk_t *
|
||||
asn1f_next_literal_chunk(asn1p_wsyntx_t *syntax, asn1p_wsyntx_chunk_t *chunk, uint8_t *buf)
|
||||
asn1f_next_literal_chunk(asn1p_wsyntx_t *syntax, asn1p_wsyntx_chunk_t *chunk, const uint8_t *buf)
|
||||
{
|
||||
asn1p_wsyntx_chunk_t *next_chunk;
|
||||
|
||||
|
@ -338,7 +504,7 @@ asn1f_next_literal_chunk(asn1p_wsyntx_t *syntax, asn1p_wsyntx_chunk_t *chunk, ui
|
|||
break;
|
||||
next_chunk = TQ_NEXT(syntax->parent, next);
|
||||
} else if(next_chunk->type == WC_LITERAL) {
|
||||
if(strstr((char *)buf, (char *)next_chunk->content.token))
|
||||
if(strstr((const char *)buf, (char *)next_chunk->content.token))
|
||||
break;
|
||||
if(!syntax->parent)
|
||||
break;
|
||||
|
|
|
@ -8,7 +8,7 @@ asn1p_expr_t *
|
|||
asn1f_lookup_symbol_ex(
|
||||
asn1p_t *asn,
|
||||
asn1p_expr_t *expr,
|
||||
asn1p_ref_t *ref) {
|
||||
const asn1p_ref_t *ref) {
|
||||
arg_t arg;
|
||||
|
||||
memset(&arg, 0, sizeof(arg));
|
||||
|
@ -28,7 +28,7 @@ asn1f_class_access_ex(asn1p_t *asn,
|
|||
asn1p_module_t *mod,
|
||||
asn1p_expr_t *expr,
|
||||
asn1p_expr_t *rhs_pspecs,
|
||||
asn1p_ref_t *ref) {
|
||||
const asn1p_ref_t *ref) {
|
||||
arg_t arg;
|
||||
|
||||
memset(&arg, 0, sizeof(arg));
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
/*
|
||||
* Create a human-readable representation of a reference and value.
|
||||
*/
|
||||
char const *asn1f_printable_reference(asn1p_ref_t *ref);
|
||||
char const *asn1f_printable_reference(const asn1p_ref_t *ref);
|
||||
char const *asn1f_printable_value(asn1p_value_t *value);
|
||||
|
||||
/*
|
||||
|
@ -19,13 +19,13 @@ char const *asn1f_printable_value(asn1p_value_t *value);
|
|||
asn1p_expr_t *asn1f_lookup_symbol_ex(
|
||||
asn1p_t *asn,
|
||||
asn1p_expr_t *expr,
|
||||
asn1p_ref_t *ref);
|
||||
const asn1p_ref_t *ref);
|
||||
|
||||
/*
|
||||
* Exportable version of an asn1f_class_access().
|
||||
*/
|
||||
asn1p_expr_t *asn1f_class_access_ex(asn1p_t *asn, asn1p_module_t *mod,
|
||||
asn1p_expr_t *expr, asn1p_expr_t *rhs_rspecs, asn1p_ref_t *);
|
||||
asn1p_expr_t *expr, asn1p_expr_t *rhs_rspecs, const asn1p_ref_t *);
|
||||
|
||||
/*
|
||||
* Exportable version of asn1f_find_terminal_type().
|
||||
|
|
|
@ -2,14 +2,9 @@
|
|||
#include "asn1fix.h"
|
||||
|
||||
char const *
|
||||
asn1f_printable_reference(asn1p_ref_t *ref) {
|
||||
asn1f_printable_reference(const asn1p_ref_t *ref) {
|
||||
if(ref) {
|
||||
asn1p_value_t v;
|
||||
|
||||
v.type = ATV_REFERENCED;
|
||||
v.value.reference = ref;
|
||||
|
||||
return asn1f_printable_value(&v);
|
||||
return asn1p_ref_string(ref);
|
||||
} else {
|
||||
return "<no ref>";
|
||||
}
|
||||
|
|
|
@ -80,7 +80,7 @@ asn1f_lookup_in_imports(arg_t *arg, asn1p_module_t *mod, const char *name) {
|
|||
}
|
||||
|
||||
asn1p_module_t *
|
||||
asn1f_lookup_module(arg_t *arg, const char *module_name, asn1p_oid_t *oid) {
|
||||
asn1f_lookup_module(arg_t *arg, const char *module_name, const asn1p_oid_t *oid) {
|
||||
asn1p_module_t *mod;
|
||||
|
||||
assert(module_name);
|
||||
|
@ -147,7 +147,7 @@ asn1f_lookup_module(arg_t *arg, const char *module_name, asn1p_oid_t *oid) {
|
|||
}
|
||||
|
||||
static asn1p_expr_t *
|
||||
asn1f_lookup_symbol_impl(arg_t *arg, asn1p_module_t *mod, asn1p_expr_t *rhs_pspecs, asn1p_ref_t *ref, int recursion_depth) {
|
||||
asn1f_lookup_symbol_impl(arg_t *arg, asn1p_module_t *mod, asn1p_expr_t *rhs_pspecs, const asn1p_ref_t *ref, int recursion_depth) {
|
||||
asn1p_expr_t *ref_tc; /* Referenced tc */
|
||||
asn1p_module_t *imports_from;
|
||||
char *modulename;
|
||||
|
@ -369,7 +369,7 @@ asn1f_lookup_symbol_impl(arg_t *arg, asn1p_module_t *mod, asn1p_expr_t *rhs_pspe
|
|||
|
||||
asn1p_expr_t *
|
||||
asn1f_lookup_symbol(arg_t *arg,
|
||||
asn1p_module_t *mod, asn1p_expr_t *rhs_pspecs, asn1p_ref_t *ref) {
|
||||
asn1p_module_t *mod, asn1p_expr_t *rhs_pspecs, const asn1p_ref_t *ref) {
|
||||
return asn1f_lookup_symbol_impl(arg, mod, rhs_pspecs, ref, 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ asn1p_module_t *asn1f_lookup_in_imports(arg_t *arg, asn1p_module_t *mod, const c
|
|||
*/
|
||||
asn1p_module_t *asn1f_lookup_module(arg_t *arg,
|
||||
const char *module_name,
|
||||
asn1p_oid_t *module_oid);
|
||||
const asn1p_oid_t *module_oid);
|
||||
|
||||
/*
|
||||
* Return the reference to a destination of the given reference,
|
||||
|
@ -40,7 +40,7 @@ asn1p_module_t *asn1f_lookup_module(arg_t *arg,
|
|||
asn1p_expr_t *asn1f_lookup_symbol(arg_t *arg,
|
||||
asn1p_module_t *mod,
|
||||
asn1p_expr_t *rhs_pspecs,
|
||||
asn1p_ref_t *ref);
|
||||
const asn1p_ref_t *ref);
|
||||
|
||||
/*
|
||||
* Recursively find the original type for the given expression.
|
||||
|
|
|
@ -62,6 +62,36 @@ asn1p_ioc_row_delete(asn1p_ioc_row_t *row) {
|
|||
}
|
||||
}
|
||||
|
||||
int
|
||||
asn1p_ioc_row_match(const asn1p_ioc_row_t *a, const asn1p_ioc_row_t *b) {
|
||||
assert(a && b);
|
||||
|
||||
if(a->columns != b->columns)
|
||||
return -1; /* Bad! */
|
||||
|
||||
for(size_t i = 0; i < a->columns; i++) {
|
||||
assert(a->column[i].field);
|
||||
assert(b->column[i].field);
|
||||
if(strcmp(a->column[i].field->Identifier,
|
||||
b->column[i].field->Identifier)
|
||||
!= 0) {
|
||||
return -1; /* Bad! */
|
||||
}
|
||||
if((a->column[i].value && !b->column[i].value)
|
||||
|| (!a->column[i].value && b->column[i].value)) {
|
||||
return 1; /* Not match */
|
||||
}
|
||||
if(a->column[i].value && b->column[i].value) {
|
||||
if(asn1p_expr_compare(a->column[i].value, b->column[i].value)
|
||||
!= 0) {
|
||||
return 1; /* Not match */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct asn1p_ioc_cell_s *
|
||||
asn1p_ioc_row_cell_fetch(asn1p_ioc_row_t *row, const char *fieldname) {
|
||||
int i;
|
||||
|
|
|
@ -20,6 +20,13 @@ typedef struct asn1p_ioc_row_s {
|
|||
|
||||
asn1p_ioc_row_t *asn1p_ioc_row_new(struct asn1p_expr_s *oclass);
|
||||
void asn1p_ioc_row_delete(asn1p_ioc_row_t *);
|
||||
|
||||
/*
|
||||
* Match is similar to a comparison,
|
||||
* but -1 means error and 1 means not equal. 0 is OK
|
||||
*/
|
||||
int asn1p_ioc_row_match(const asn1p_ioc_row_t *, const asn1p_ioc_row_t *);
|
||||
|
||||
struct asn1p_ioc_cell_s *asn1p_ioc_row_cell_fetch(asn1p_ioc_row_t *,
|
||||
const char *fieldname);
|
||||
|
||||
|
|
|
@ -6,6 +6,28 @@
|
|||
|
||||
#include "asn1parser.h"
|
||||
|
||||
void
|
||||
asn1p_constraint_set_source(asn1p_constraint_t *ct,
|
||||
struct asn1p_module_s *module, int lineno) {
|
||||
if(ct) {
|
||||
ct->module = module;
|
||||
ct->_lineno = lineno;
|
||||
asn1p_value_set_source(ct->containedSubtype,module,lineno);
|
||||
asn1p_value_set_source(ct->value,module,lineno);
|
||||
asn1p_value_set_source(ct->range_start,module,lineno);
|
||||
asn1p_value_set_source(ct->range_stop,module,lineno);
|
||||
for(size_t i = 0; i < ct->el_count; i++) {
|
||||
asn1p_constraint_set_source(ct->elements[i], module, lineno);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int asn1p_constraint_compare(const asn1p_constraint_t *a,
|
||||
const asn1p_constraint_t *b) {
|
||||
assert(!"Constraint comparison is not implemented");
|
||||
return -1;
|
||||
}
|
||||
|
||||
asn1p_constraint_t *
|
||||
asn1p_constraint_new(int _lineno, asn1p_module_t *mod) {
|
||||
asn1p_constraint_t *ct;
|
||||
|
@ -189,3 +211,20 @@ asn1p_constraint_type2str(enum asn1p_constraint_type_e type) {
|
|||
}
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
const asn1p_constraint_t *
|
||||
asn1p_get_component_relation_constraint(asn1p_constraint_t *ct) {
|
||||
if(ct) {
|
||||
if(ct->type == ACT_CA_CRC)
|
||||
return ct;
|
||||
if(ct->type == ACT_CA_SET) {
|
||||
for(size_t i = 0; i < ct->el_count; i++) {
|
||||
const asn1p_constraint_t *tmp =
|
||||
asn1p_get_component_relation_constraint(ct->elements[i]);
|
||||
if(tmp) return tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -71,6 +71,14 @@ typedef struct asn1p_constraint_s {
|
|||
/* Human-readable constraint type description */
|
||||
const char *asn1p_constraint_type2str(enum asn1p_constraint_type_e);
|
||||
|
||||
const asn1p_constraint_t *asn1p_get_component_relation_constraint(
|
||||
asn1p_constraint_t *);
|
||||
|
||||
int asn1p_constraint_compare(const asn1p_constraint_t *,
|
||||
const asn1p_constraint_t *);
|
||||
void asn1p_constraint_set_source(asn1p_constraint_t *,
|
||||
struct asn1p_module_s *module, int lineno);
|
||||
|
||||
/*
|
||||
* Constructors and a recursive destructor.
|
||||
*/
|
||||
|
|
|
@ -9,6 +9,82 @@
|
|||
static asn1p_expr_t *asn1p_expr_clone_impl(asn1p_expr_t *expr, int skip_extensions, asn1p_expr_t *(*)(asn1p_expr_t *, void *), void *);
|
||||
static asn1p_value_t *value_resolver(asn1p_value_t *, void *arg);
|
||||
|
||||
void
|
||||
asn1p_expr_set_source(asn1p_expr_t *expr, asn1p_module_t *module, int lineno) {
|
||||
if(expr) {
|
||||
expr->module = module;
|
||||
expr->_lineno = lineno;
|
||||
asn1p_ref_set_source(expr->reference, module, lineno);
|
||||
asn1p_value_set_source(expr->value, module, lineno);
|
||||
asn1p_constraint_set_source(expr->constraints, module, lineno);
|
||||
asn1p_constraint_set_source(expr->combined_constraints, module, lineno);
|
||||
asn1p_expr_set_source(expr->rhs_pspecs, module, lineno);
|
||||
|
||||
asn1p_expr_t *memb;
|
||||
|
||||
TQ_FOR(memb, &(expr->members), next) {
|
||||
asn1p_expr_set_source(memb, module, lineno);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
asn1p_expr_compare(const asn1p_expr_t *a, const asn1p_expr_t *b) {
|
||||
if(a->meta_type != b->meta_type || a->expr_type != b->expr_type) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((!a->Identifier && b->Identifier) || (a->Identifier && !b->Identifier)) {
|
||||
return -1;
|
||||
} else if(a->Identifier && strcmp(a->Identifier, b->Identifier)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((!a->reference && b->reference) || (a->reference && !b->reference)) {
|
||||
return -1;
|
||||
} else if(a->reference
|
||||
&& asn1p_ref_compare(a->reference, b->reference) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((!a->value && b->value) || (a->value && !b->value)) {
|
||||
return -1;
|
||||
} else if(a->value && asn1p_value_compare(a->value, b->value)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((a->tag.tag_class != b->tag.tag_class)
|
||||
|| (a->tag.tag_mode != b->tag.tag_mode)
|
||||
|| (a->tag.tag_value != b->tag.tag_value)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((a->marker.flags != b->marker.flags)
|
||||
|| (a->marker.default_value && !b->marker.default_value)
|
||||
|| (!a->marker.default_value && b->marker.default_value)
|
||||
|| (a->marker.default_value
|
||||
&& asn1p_value_compare(a->marker.default_value,
|
||||
b->marker.default_value))) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(a->unique != b->unique) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
const asn1p_expr_t *am = TQ_FIRST(&a->members);
|
||||
const asn1p_expr_t *bm = TQ_FIRST(&b->members);
|
||||
for(; am || bm; am = TQ_NEXT(am, next), bm = TQ_NEXT(bm, next)) {
|
||||
if((am && !bm) || (!am && bm)) {
|
||||
return -1;
|
||||
} else if(asn1p_expr_compare(am, bm) != 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Construct a new empty types collection.
|
||||
*/
|
||||
|
|
|
@ -281,7 +281,10 @@ asn1p_expr_t *asn1p_expr_clone_with_resolver(asn1p_expr_t *,
|
|||
void *resolver_arg);
|
||||
void asn1p_expr_add(asn1p_expr_t *to, asn1p_expr_t *what);
|
||||
void asn1p_expr_add_many(asn1p_expr_t *to, asn1p_expr_t *from_what);
|
||||
int asn1p_expr_compare(const asn1p_expr_t *, const asn1p_expr_t *);
|
||||
void asn1p_expr_free(asn1p_expr_t *expr);
|
||||
void asn1p_expr_set_source(asn1p_expr_t *, asn1p_module_t *, int lineno);
|
||||
|
||||
|
||||
#define TAG2STRING_BUFFER_SIZE 64 /* buf should be at least this big */
|
||||
char *asn1p_tag2string(struct asn1p_type_tag_s *tag, char *opt_buf);
|
||||
|
|
|
@ -81,7 +81,7 @@ asn1p_oid_arc_free(asn1p_oid_arc_t *arc) {
|
|||
}
|
||||
|
||||
int
|
||||
asn1p_oid_compare(asn1p_oid_t *a, asn1p_oid_t *b) {
|
||||
asn1p_oid_compare(const asn1p_oid_t *a, const asn1p_oid_t *b) {
|
||||
int i;
|
||||
|
||||
for(i = 0; ; i++) {
|
||||
|
|
|
@ -61,7 +61,7 @@ void asn1p_oid_free(asn1p_oid_t *);
|
|||
* 0: The specified OIDs are equal.
|
||||
* -1 or 1 otherwise.
|
||||
*/
|
||||
int asn1p_oid_compare(asn1p_oid_t *a, asn1p_oid_t *b);
|
||||
int asn1p_oid_compare(const asn1p_oid_t *a, const asn1p_oid_t *b);
|
||||
|
||||
|
||||
#endif /* ASN1_PARSER_OID_H */
|
||||
|
|
|
@ -14,10 +14,8 @@ asn1p_ref_new(int _lineno, asn1p_module_t *mod) {
|
|||
asn1p_ref_t *ref;
|
||||
|
||||
ref = calloc(1, sizeof *ref);
|
||||
if(ref) {
|
||||
ref->_lineno = _lineno;
|
||||
ref->module = mod;
|
||||
}
|
||||
assert(ref);
|
||||
asn1p_ref_set_source(ref, mod, _lineno);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
@ -39,6 +37,14 @@ asn1p_ref_free(asn1p_ref_t *ref) {
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
asn1p_ref_set_source(asn1p_ref_t *ref, asn1p_module_t *module, int lineno) {
|
||||
if(ref) {
|
||||
ref->module = module;
|
||||
ref->_lineno = lineno;
|
||||
}
|
||||
}
|
||||
|
||||
static enum asn1p_ref_lex_type_e
|
||||
asn1p_ref_name2lextype(const char *name) {
|
||||
enum asn1p_ref_lex_type_e lex_type;
|
||||
|
@ -136,3 +142,51 @@ asn1p_ref_clone(asn1p_ref_t *ref) {
|
|||
|
||||
return newref;
|
||||
}
|
||||
|
||||
int
|
||||
asn1p_ref_compare(const asn1p_ref_t *a, const asn1p_ref_t *b) {
|
||||
if(a->comp_count != b->comp_count)
|
||||
return -1;
|
||||
if(a->module != b->module)
|
||||
return -1;
|
||||
|
||||
for(size_t i = 0; i < a->comp_count; i++) {
|
||||
if(a->components[i].lex_type != b->components[i].lex_type
|
||||
|| strcmp(a->components[i].name, b->components[i].name) != 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *
|
||||
asn1p_ref_string(const asn1p_ref_t *ref) {
|
||||
static char static_buf[32];
|
||||
static char *buf = static_buf;
|
||||
static size_t buf_size = sizeof(static_buf);
|
||||
char *p = buf;
|
||||
|
||||
for(size_t i = 0; i < ref->comp_count; i++) {
|
||||
size_t space = buf_size - (p - buf);
|
||||
int ret =
|
||||
snprintf(p, space, "%s%s", i ? "." : "", ref->components[i].name);
|
||||
if(ret < 0 || (size_t)ret >= space) {
|
||||
i--;
|
||||
char *tmp = malloc(buf_size * 2 + 1);
|
||||
assert(tmp);
|
||||
size_t p_offset = p - buf;
|
||||
memcpy(tmp, buf, (p - buf));
|
||||
if(buf != static_buf) free(buf);
|
||||
buf_size *= 2;
|
||||
buf = tmp;
|
||||
p = tmp + p_offset;
|
||||
} else {
|
||||
p += ret;
|
||||
}
|
||||
}
|
||||
|
||||
*p = '\0';
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,6 +49,20 @@ void asn1p_ref_free(asn1p_ref_t *);
|
|||
|
||||
asn1p_ref_t *asn1p_ref_clone(asn1p_ref_t *ref);
|
||||
|
||||
void asn1p_ref_set_source(asn1p_ref_t *, asn1p_module_t *module, int lineno);
|
||||
|
||||
|
||||
/*
|
||||
* Lexicographically compare references.
|
||||
*/
|
||||
int asn1p_ref_compare(const asn1p_ref_t *, const asn1p_ref_t *);
|
||||
|
||||
/*
|
||||
* Return a pointer to a statically allocated buffer representing the
|
||||
* complete reference.
|
||||
*/
|
||||
const char *asn1p_ref_string(const asn1p_ref_t *);
|
||||
|
||||
/*
|
||||
* Add a new reference component to the existing reference structure.
|
||||
*
|
||||
|
|
|
@ -4,7 +4,85 @@
|
|||
#include <assert.h>
|
||||
|
||||
#include "asn1parser.h"
|
||||
#include "asn1p_expr.h"
|
||||
|
||||
void
|
||||
asn1p_value_set_source(asn1p_value_t *value, asn1p_module_t *module,
|
||||
int lineno) {
|
||||
if(value) {
|
||||
switch(value->type) {
|
||||
case ATV_TYPE:
|
||||
asn1p_expr_set_source(value->value.v_type, module, lineno);
|
||||
break;
|
||||
case ATV_REFERENCED:
|
||||
asn1p_ref_set_source(value->value.reference, module, lineno);
|
||||
break;
|
||||
case ATV_VALUESET:
|
||||
asn1p_constraint_set_source(value->value.constraint, module,
|
||||
lineno);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
asn1p_value_compare(const asn1p_value_t *a, const asn1p_value_t *b) {
|
||||
if(a->type != b->type) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch(a->type) {
|
||||
case ATV_NULL:
|
||||
case ATV_NOVALUE:
|
||||
case ATV_MAX:
|
||||
case ATV_MIN:
|
||||
case ATV_FALSE:
|
||||
case ATV_TRUE:
|
||||
break;
|
||||
case ATV_TYPE:
|
||||
return asn1p_expr_compare(a->value.v_type, b->value.v_type);
|
||||
case ATV_REAL:
|
||||
return (a->value.v_double == b->value.v_double) ? 0 : -1;
|
||||
case ATV_INTEGER:
|
||||
case ATV_TUPLE:
|
||||
case ATV_QUADRUPLE:
|
||||
return (a->value.v_integer == b->value.v_integer) ? 0 : -1;
|
||||
case ATV_STRING:
|
||||
case ATV_UNPARSED:
|
||||
if(a->value.string.size != b->value.string.size
|
||||
|| memcmp(a->value.string.buf, b->value.string.buf,
|
||||
a->value.string.size)
|
||||
!= 0) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
case ATV_BITVECTOR:
|
||||
if(a->value.binary_vector.size_in_bits
|
||||
!= b->value.binary_vector.size_in_bits
|
||||
|| memcmp(a->value.binary_vector.bits, b->value.binary_vector.bits,
|
||||
(a->value.binary_vector.size_in_bits+7) >> 3)
|
||||
!= 0) {
|
||||
return -1;
|
||||
}
|
||||
case ATV_VALUESET:
|
||||
return asn1p_constraint_compare(a->value.constraint,
|
||||
b->value.constraint);
|
||||
case ATV_REFERENCED:
|
||||
return asn1p_ref_compare(a->value.reference, b->value.reference);
|
||||
case ATV_CHOICE_IDENTIFIER:
|
||||
if(strcmp(a->value.choice_identifier.identifier,
|
||||
b->value.choice_identifier.identifier)
|
||||
!= 0) {
|
||||
return -1;
|
||||
}
|
||||
return asn1p_value_compare(a->value.choice_identifier.value,
|
||||
b->value.choice_identifier.value);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
asn1p_value_t *
|
||||
asn1p_value_fromref(asn1p_ref_t *ref, int do_copy) {
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#define ASN1_PARSER_VALUE_H
|
||||
|
||||
struct asn1p_constraint_s; /* Forward declaration */
|
||||
struct asn1p_module_s;
|
||||
struct asn1p_expr_s;
|
||||
|
||||
/*
|
||||
|
@ -76,5 +77,7 @@ asn1p_value_t *asn1p_value_clone(asn1p_value_t *);
|
|||
asn1p_value_t *asn1p_value_clone_with_resolver(asn1p_value_t *,
|
||||
asn1p_value_t *(*resolver)(asn1p_value_t *, void *rarg),
|
||||
void *rarg);
|
||||
int asn1p_value_compare(const asn1p_value_t *, const asn1p_value_t *);
|
||||
void asn1p_value_set_source(asn1p_value_t *, struct asn1p_module_s *, int line);
|
||||
|
||||
#endif /* ASN1_PARSER_VALUE_H */
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
|
||||
-- OK: Everything is fine
|
||||
|
||||
-- iso.org.dod.internet.private.enterprise (1.3.6.1.4.1)
|
||||
-- .spelio.software.asn1c.test (9363.1.5.1)
|
||||
-- .139
|
||||
|
||||
ModuleComponentRelationConstraint
|
||||
{ iso org(3) dod(6) internet (1) private(4) enterprise(1)
|
||||
spelio(9363) software(1) asn1c(5) test(1) 139 }
|
||||
DEFINITIONS ::=
|
||||
BEGIN
|
||||
|
||||
Frame ::= SEQUENCE {
|
||||
ident FRAME-STRUCTURE.&id({FrameTypes}),
|
||||
value FRAME-STRUCTURE.&Type({FrameTypes}{@.ident}),
|
||||
...
|
||||
}
|
||||
|
||||
FRAME-STRUCTURE ::= CLASS {
|
||||
&id INTEGER UNIQUE,
|
||||
&Type
|
||||
} WITH SYNTAX {&Type IDENTIFIED BY &id}
|
||||
|
||||
FrameTypes FRAME-STRUCTURE ::= {
|
||||
{ PrimitiveMessage IDENTIFIED BY basicMessage } |
|
||||
{ ComplexMessage IDENTIFIED BY 2 },
|
||||
...
|
||||
}
|
||||
|
||||
PrimitiveMessage ::= SEQUENCE {}
|
||||
ComplexMessage ::= SEQUENCE {}
|
||||
|
||||
basicMessage INTEGER ::= 1
|
||||
|
||||
END
|
|
@ -0,0 +1,31 @@
|
|||
ModuleComponentRelationConstraint { iso org(3) dod(6) internet(1) private(4)
|
||||
enterprise(1) spelio(9363) software(1) asn1c(5) test(1) 139 }
|
||||
DEFINITIONS ::=
|
||||
BEGIN
|
||||
|
||||
Frame ::= SEQUENCE {
|
||||
ident FRAME-STRUCTURE.&id ({FrameTypes}),
|
||||
value FRAME-STRUCTURE.&Type ({FrameTypes}{@.ident}),
|
||||
...
|
||||
}
|
||||
|
||||
FRAME-STRUCTURE ::= CLASS {
|
||||
&id INTEGER UNIQUE,
|
||||
&Type ANY
|
||||
} WITH SYNTAX {&Type IDENTIFIED BY &id}
|
||||
|
||||
-- Class matrix has 2 entries:
|
||||
-- [ &id][ &Type]
|
||||
-- [1] basicMessage PrimitiveMessage
|
||||
-- [2] 2 ComplexMessage
|
||||
|
||||
|
||||
FrameTypes FRAME-STRUCTURE ::= {{ PrimitiveMessage IDENTIFIED BY basicMessage } | { ComplexMessage IDENTIFIED BY 2 },...}
|
||||
|
||||
PrimitiveMessage ::= SEQUENCE { }
|
||||
|
||||
ComplexMessage ::= SEQUENCE { }
|
||||
|
||||
basicMessage INTEGER ::= 1
|
||||
|
||||
END
|
|
@ -0,0 +1,35 @@
|
|||
|
||||
-- OK: Everything is fine
|
||||
|
||||
-- iso.org.dod.internet.private.enterprise (1.3.6.1.4.1)
|
||||
-- .spelio.software.asn1c.test (9363.1.5.1)
|
||||
-- .140
|
||||
|
||||
ModuleComponentRelationConstraint
|
||||
{ iso org(3) dod(6) internet (1) private(4) enterprise(1)
|
||||
spelio(9363) software(1) asn1c(5) test(1) 140 }
|
||||
DEFINITIONS ::=
|
||||
BEGIN
|
||||
|
||||
Frame ::= SEQUENCE {
|
||||
ident FRAME-STRUCTURE.&id({FrameTypes}),
|
||||
value FRAME-STRUCTURE.&Type({FrameTypes}{@.ident}),
|
||||
...
|
||||
}
|
||||
|
||||
FRAME-STRUCTURE ::= CLASS {
|
||||
&id INTEGER UNIQUE,
|
||||
&Type
|
||||
} WITH SYNTAX {&Type IDENTIFIED BY &id}
|
||||
|
||||
FrameTypes FRAME-STRUCTURE ::= { primType | complexType, ... }
|
||||
|
||||
primType FRAME-STRUCTURE ::= { PrimitiveMessage IDENTIFIED BY basicMessage }
|
||||
complexType FRAME-STRUCTURE ::= { ComplexMessage IDENTIFIED BY 2 }
|
||||
|
||||
PrimitiveMessage ::= SEQUENCE {}
|
||||
ComplexMessage ::= SEQUENCE {}
|
||||
|
||||
basicMessage INTEGER ::= 1
|
||||
|
||||
END
|
|
@ -0,0 +1,35 @@
|
|||
ModuleComponentRelationConstraint { iso org(3) dod(6) internet(1) private(4)
|
||||
enterprise(1) spelio(9363) software(1) asn1c(5) test(1) 140 }
|
||||
DEFINITIONS ::=
|
||||
BEGIN
|
||||
|
||||
Frame ::= SEQUENCE {
|
||||
ident FRAME-STRUCTURE.&id ({FrameTypes}),
|
||||
value FRAME-STRUCTURE.&Type ({FrameTypes}{@.ident}),
|
||||
...
|
||||
}
|
||||
|
||||
FRAME-STRUCTURE ::= CLASS {
|
||||
&id INTEGER UNIQUE,
|
||||
&Type ANY
|
||||
} WITH SYNTAX {&Type IDENTIFIED BY &id}
|
||||
|
||||
-- Class matrix has 2 entries:
|
||||
-- [ &id][ &Type]
|
||||
-- [1] basicMessage PrimitiveMessage
|
||||
-- [2] 2 ComplexMessage
|
||||
|
||||
|
||||
FrameTypes FRAME-STRUCTURE ::= {{ PrimitiveMessage IDENTIFIED BY basicMessage } | { ComplexMessage IDENTIFIED BY 2 },...}
|
||||
|
||||
primType FRAME-STRUCTURE ::= { PrimitiveMessage IDENTIFIED BY basicMessage }
|
||||
|
||||
complexType FRAME-STRUCTURE ::= { ComplexMessage IDENTIFIED BY 2 }
|
||||
|
||||
PrimitiveMessage ::= SEQUENCE { }
|
||||
|
||||
ComplexMessage ::= SEQUENCE { }
|
||||
|
||||
basicMessage INTEGER ::= 1
|
||||
|
||||
END
|
Loading…
Reference in New Issue