mirror of https://gerrit.osmocom.org/asn1c
refactor constraint matrix handling
This commit is contained in:
parent
494fb707a7
commit
4dcf8367d9
|
@ -318,24 +318,22 @@ asn1c_get_information_object_set_reference_from_constraint(
|
|||
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) {
|
||||
(void)arg;
|
||||
static asn1p_ioc_table_t *
|
||||
asn1c_get_ioc_table_from_objset(arg_t *arg, const asn1p_ref_t *objset_ref, asn1p_expr_t *objset) {
|
||||
(void)objset_ref;
|
||||
(void)objset;
|
||||
|
||||
asn1c_ioc_table_t *itable = NULL;
|
||||
itable = calloc(1, sizeof(*itable));
|
||||
assert(itable);
|
||||
|
||||
return itable;
|
||||
if(objset->ioc_table) {
|
||||
return objset->ioc_table;
|
||||
} else {
|
||||
FATAL("Information Object Set %s contains no objects at line %d",
|
||||
objset->Identifier, objset->_lineno);
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
};
|
||||
|
||||
static asn1c_ioc_table_t *
|
||||
asn1c_construct_ioc_table(arg_t *arg) {
|
||||
static asn1p_ioc_table_t *
|
||||
asn1c_get_ioc_table(arg_t *arg) {
|
||||
asn1p_expr_t *expr = arg->expr;
|
||||
asn1p_expr_t *memb;
|
||||
asn1p_expr_t *objset = 0;
|
||||
|
@ -369,7 +367,7 @@ asn1c_construct_ioc_table(arg_t *arg) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
return asn1c_construct_ioc_table_from_objset(arg, objset_ref, objset);
|
||||
return asn1c_get_ioc_table_from_objset(arg, objset_ref, objset);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -378,11 +376,11 @@ asn1c_lang_C_type_SEQUENCE(arg_t *arg) {
|
|||
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;
|
||||
asn1p_ioc_table_t *itable = NULL;
|
||||
|
||||
DEPENDENCIES;
|
||||
|
||||
itable = asn1c_construct_ioc_table(arg);
|
||||
itable = asn1c_get_ioc_table(arg);
|
||||
if(!itable && errno != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ static int _asn1f_parse_class_object_data(arg_t *, asn1p_expr_t *eclass,
|
|||
struct asn1p_ioc_row_s *row, asn1p_wsyntx_t *syntax,
|
||||
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 int _asn1f_assign_cell_value(arg_t *arg, 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
|
||||
|
@ -51,9 +51,13 @@ asn1f_check_class_object(arg_t *arg) {
|
|||
}
|
||||
|
||||
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)) {
|
||||
_asn1f_is_ioc_row_duplicate(asn1p_ioc_table_t *it, asn1p_ioc_row_t *row) {
|
||||
if(!it) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < it->rows; i++) {
|
||||
switch(asn1p_ioc_row_match(it->row[i], row)) {
|
||||
default:
|
||||
case -1:
|
||||
return -1;
|
||||
|
@ -72,37 +76,33 @@ struct parse_object_key {
|
|||
asn1p_expr_t *eclass; /* CLASS */
|
||||
};
|
||||
|
||||
/*
|
||||
* Add to the IoC table if the row is unique.
|
||||
*/
|
||||
static int
|
||||
_asn1f_add_row(arg_t *arg, asn1p_expr_t *expr, asn1p_ioc_row_t *row) {
|
||||
void *new_rows_ptr;
|
||||
_asn1f_add_unique_row(arg_t *arg, asn1p_expr_t *expr, asn1p_ioc_row_t *row) {
|
||||
|
||||
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;
|
||||
if(expr->ioc_table == NULL) {
|
||||
expr->ioc_table = asn1p_ioc_table_new();
|
||||
} else {
|
||||
/* Look for duplicates */
|
||||
|
||||
switch(_asn1f_is_ioc_row_duplicate(expr->ioc_table, 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;
|
||||
asn1p_ioc_table_add(expr->ioc_table, row);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -134,7 +134,7 @@ _asn1f_parse_object_cb(const uint8_t *buf, size_t size, void *keyp) {
|
|||
}
|
||||
|
||||
/* Add object to a CLASS. */
|
||||
if(_asn1f_add_row(arg, eclass, row) != 0)
|
||||
if(_asn1f_add_unique_row(arg, eclass, row) != 0)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
|
@ -146,7 +146,7 @@ _asn1f_parse_object_cb(const uint8_t *buf, size_t size, void *keyp) {
|
|||
buf, buf + size, 0, 0);
|
||||
assert(ret == 0);
|
||||
|
||||
if(_asn1f_add_row(arg, expr, row) != 0)
|
||||
if(_asn1f_add_unique_row(arg, expr, row) != 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
|
@ -342,7 +342,7 @@ _asn1f_parse_class_object_data(arg_t *arg, asn1p_expr_t *eclass,
|
|||
DEBUG("Reference %s satisfied by %s (%d)",
|
||||
chunk->content.token,
|
||||
buf, p - buf);
|
||||
ret = _asn1f_assign_cell_value(arg, row, cell, buf, p);
|
||||
ret = _asn1f_assign_cell_value(arg, cell, buf, p);
|
||||
if(ret) return ret;
|
||||
buf = p;
|
||||
if(newpos) *newpos = buf;
|
||||
|
@ -367,9 +367,8 @@ _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, const uint8_t *buf,
|
||||
const uint8_t *bend) {
|
||||
_asn1f_assign_cell_value(arg_t *arg, struct asn1p_ioc_cell_s *cell,
|
||||
const uint8_t *buf, const uint8_t *bend) {
|
||||
asn1p_expr_t *expr = (asn1p_expr_t *)NULL;
|
||||
char *p;
|
||||
int new_ref = 1;
|
||||
|
@ -481,12 +480,9 @@ _asn1f_assign_cell_value(arg_t *arg, struct asn1p_ioc_row_s *row,
|
|||
cell->value = expr;
|
||||
cell->new_ref = new_ref;
|
||||
|
||||
size_t idLength = strlen(expr->Identifier);
|
||||
if(row->max_identifier_length < idLength)
|
||||
row->max_identifier_length = idLength;
|
||||
|
||||
if(expr->Identifier != p)
|
||||
if(expr->Identifier != p) {
|
||||
free(p);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,62 @@
|
|||
#include <assert.h>
|
||||
|
||||
#include "asn1parser.h"
|
||||
#include "asn1p_class.h"
|
||||
|
||||
asn1p_ioc_table_t *
|
||||
asn1p_ioc_table_new() {
|
||||
asn1p_ioc_table_t *it = calloc(1, sizeof(*it));
|
||||
assert(it);
|
||||
return it;
|
||||
}
|
||||
|
||||
void
|
||||
asn1p_ioc_table_add(asn1p_ioc_table_t *it, asn1p_ioc_row_t *row) {
|
||||
assert(it);
|
||||
|
||||
asn1p_ioc_row_t **new_rows =
|
||||
realloc(it->row, (it->rows + 1) * sizeof(it->row[0]));
|
||||
assert(new_rows);
|
||||
it->row = new_rows;
|
||||
it->row[it->rows++] = row;
|
||||
}
|
||||
|
||||
void
|
||||
asn1p_ioc_table_free(asn1p_ioc_table_t *it) {
|
||||
if(it) {
|
||||
for(size_t i = 0; i < it->rows; i++) {
|
||||
asn1p_ioc_row_delete(it->row[i]);
|
||||
}
|
||||
free(it->row);
|
||||
free(it);
|
||||
}
|
||||
}
|
||||
|
||||
size_t
|
||||
asn1p_ioc_table_max_identifier_length(asn1p_ioc_table_t *it) {
|
||||
size_t max_length = 0;
|
||||
if(it) {
|
||||
for(size_t i = 0; i < it->rows; i++) {
|
||||
size_t len = asn1p_ioc_row_max_identifier_length(it->row[i]);
|
||||
if(len > max_length) max_length = len;
|
||||
}
|
||||
}
|
||||
return max_length;
|
||||
}
|
||||
|
||||
size_t
|
||||
asn1p_ioc_row_max_identifier_length(asn1p_ioc_row_t *row) {
|
||||
size_t max_length = 0;
|
||||
if(row) {
|
||||
for(size_t i = 0; i < row->columns; i++) {
|
||||
if(row->column[i].value) {
|
||||
size_t len = strlen(row->column[i].value->Identifier);
|
||||
if(len > max_length) max_length = len;
|
||||
}
|
||||
}
|
||||
}
|
||||
return max_length;
|
||||
}
|
||||
|
||||
asn1p_ioc_row_t *
|
||||
asn1p_ioc_row_new(asn1p_expr_t *oclass) {
|
||||
|
@ -29,9 +85,6 @@ asn1p_ioc_row_new(asn1p_expr_t *oclass) {
|
|||
|
||||
columns = 0;
|
||||
TQ_FOR(field, &oclass->members, next) {
|
||||
size_t fieldIdLen = strlen(field->Identifier);
|
||||
if(fieldIdLen > row->max_identifier_length)
|
||||
row->max_identifier_length = fieldIdLen;
|
||||
row->column[columns].field = field;
|
||||
row->column[columns].value = NULL;
|
||||
columns++;
|
||||
|
|
|
@ -15,12 +15,22 @@ typedef struct asn1p_ioc_row_s {
|
|||
int new_ref;
|
||||
} *column;
|
||||
size_t columns;
|
||||
size_t max_identifier_length;
|
||||
} asn1p_ioc_row_t;
|
||||
|
||||
asn1p_ioc_row_t *asn1p_ioc_row_new(struct asn1p_expr_s *oclass);
|
||||
size_t asn1p_ioc_row_max_identifier_length(asn1p_ioc_row_t *);
|
||||
void asn1p_ioc_row_delete(asn1p_ioc_row_t *);
|
||||
|
||||
typedef struct asn1p_ioc_table_s {
|
||||
asn1p_ioc_row_t **row;
|
||||
size_t rows;
|
||||
} asn1p_ioc_table_t;
|
||||
|
||||
asn1p_ioc_table_t *asn1p_ioc_table_new(void);
|
||||
void asn1p_ioc_table_add(asn1p_ioc_table_t *, asn1p_ioc_row_t *row);
|
||||
size_t asn1p_ioc_table_max_identifier_length(asn1p_ioc_table_t *);
|
||||
void asn1p_ioc_table_free(asn1p_ioc_table_t *);
|
||||
|
||||
/*
|
||||
* Match is similar to a comparison,
|
||||
* but -1 means error and 1 means not equal. 0 is OK
|
||||
|
|
|
@ -345,12 +345,7 @@ asn1p_expr_free(asn1p_expr_t *expr) {
|
|||
}
|
||||
free(expr->specializations.pspec);
|
||||
}
|
||||
if(expr->object_class_matrix.row) {
|
||||
for(size_t row = 0; row < expr->object_class_matrix.rows; row++) {
|
||||
asn1p_ioc_row_delete(expr->object_class_matrix.row[row]);
|
||||
}
|
||||
free(expr->object_class_matrix.row);
|
||||
}
|
||||
asn1p_ioc_table_free(expr->ioc_table);
|
||||
|
||||
if(expr->data && expr->data_free)
|
||||
expr->data_free(expr->data);
|
||||
|
|
|
@ -107,6 +107,7 @@ typedef enum asn1p_expr_type {
|
|||
#include "asn1p_expr2uclass.h"
|
||||
|
||||
struct asn1p_module_s; /* Forward declaration */
|
||||
struct asn1p_ioc_table_s; /* Forward declaration */
|
||||
|
||||
/*
|
||||
* A named collection of types.
|
||||
|
@ -178,12 +179,8 @@ typedef struct asn1p_expr_s {
|
|||
*/
|
||||
asn1p_wsyntx_t *with_syntax;
|
||||
|
||||
/* Information Object Class matrix, specific for this class */
|
||||
struct asn1p_ioc_matrix_s {
|
||||
asn1p_ioc_row_t **row;
|
||||
size_t rows;
|
||||
size_t max_identifier_length;
|
||||
} object_class_matrix;
|
||||
/* Information Object Class table, specific for a class or object set */
|
||||
struct asn1p_ioc_table_s *ioc_table;
|
||||
|
||||
/*
|
||||
* A tag.
|
||||
|
|
|
@ -776,19 +776,19 @@ asn1print_expr(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *tc, enum asn1pri
|
|||
|
||||
if(flags & APF_PRINT_CLASS_MATRIX) do {
|
||||
size_t col, maxidlen;
|
||||
if(tc->object_class_matrix.rows == 0) {
|
||||
if(tc->ioc_table == NULL) {
|
||||
if(tc->expr_type == A1TC_CLASSDEF) {
|
||||
safe_printf("\n-- Information Object Class table is empty");
|
||||
}
|
||||
break;
|
||||
}
|
||||
safe_printf("\n-- Information Object Set has %d entr%s:\n",
|
||||
tc->object_class_matrix.rows,
|
||||
tc->object_class_matrix.rows==1 ? "y" : "ies");
|
||||
maxidlen = tc->object_class_matrix.max_identifier_length;
|
||||
for(ssize_t r = -1; r < (ssize_t)tc->object_class_matrix.rows; r++) {
|
||||
struct asn1p_ioc_row_s *row;
|
||||
row = tc->object_class_matrix.row[r<0?0:r];
|
||||
tc->ioc_table->rows,
|
||||
tc->ioc_table->rows==1 ? "y" : "ies");
|
||||
maxidlen = asn1p_ioc_table_max_identifier_length(tc->ioc_table);
|
||||
for(ssize_t r = -1; r < (ssize_t)tc->ioc_table->rows; r++) {
|
||||
asn1p_ioc_row_t *row;
|
||||
row = tc->ioc_table->row[r<0?0:r];
|
||||
if(r < 0) safe_printf("-- %s", r > 9 ? " " : "");
|
||||
else safe_printf("-- [%*d]", r > 9 ? 2 : 1, r+1);
|
||||
for(col = 0; col < row->columns; col++) {
|
||||
|
|
|
@ -20,9 +20,7 @@ BEGIN
|
|||
siAttributeValue IA5String
|
||||
}
|
||||
|
||||
Attributes ATTRIBUTE ::= { Names }
|
||||
|
||||
Names ATTRIBUTE ::= { rafService | rcfService }
|
||||
Attributes ATTRIBUTE ::= { rafService | rcfService }
|
||||
|
||||
rafService ATTRIBUTE ::= { ID raf }
|
||||
rcfService ATTRIBUTE ::= { ID rcf }
|
||||
|
|
|
@ -13,9 +13,7 @@ Attribute ::= SEQUENCE {
|
|||
siAttributeValue IA5String
|
||||
}
|
||||
|
||||
Attributes ATTRIBUTE ::= {Names}
|
||||
|
||||
Names ATTRIBUTE ::= {{ ID raf } | { ID rcf }}
|
||||
Attributes ATTRIBUTE ::= {{ ID raf } | { ID rcf }}
|
||||
|
||||
rafService ATTRIBUTE ::= { ID raf }
|
||||
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
ModuleAttributeClass { iso org(3) dod(6) internet(1) private(4) enterprise(1)
|
||||
spelio(9363) software(1) asn1c(5) test(1) 98 }
|
||||
DEFINITIONS ::=
|
||||
BEGIN
|
||||
|
||||
ATTRIBUTE ::= CLASS {
|
||||
&id RELATIVE-OID UNIQUE
|
||||
} WITH SYNTAX { ID &id }
|
||||
|
||||
-- Information Object Set has 2 entries:
|
||||
-- [&id]
|
||||
-- [1] raf
|
||||
-- [2] rcf
|
||||
|
||||
|
||||
Attribute ::= SEQUENCE {
|
||||
identifier ATTRIBUTE.&id ({Attributes}),
|
||||
siAttributeValue IA5String
|
||||
}
|
||||
|
||||
Attributes ATTRIBUTE ::= {{ ID raf } | { ID rcf }}
|
||||
-- Information Object Set has 2 entries:
|
||||
-- [&id]
|
||||
-- [1] raf
|
||||
-- [2] rcf
|
||||
|
||||
|
||||
rafService ATTRIBUTE ::= { ID raf }
|
||||
-- Information Object Set has 1 entry:
|
||||
-- [&id]
|
||||
-- [1] raf
|
||||
|
||||
|
||||
rcfService ATTRIBUTE ::= { ID rcf }
|
||||
-- Information Object Set has 1 entry:
|
||||
-- [&id]
|
||||
-- [1] rcf
|
||||
|
||||
|
||||
raf RELATIVE-OID ::= {3 2 1}
|
||||
|
||||
rcf RELATIVE-OID ::= {3 2 2}
|
||||
|
||||
END
|
Loading…
Reference in New Issue