parsing WITH SYNTAX clauses

git-svn-id: https://asn1c.svn.sourceforge.net/svnroot/asn1c/trunk@1074 59561ff5-6e30-0410-9f3c-9617f08c8826
This commit is contained in:
vlm 2006-03-16 10:03:35 +00:00
parent eeb3c51bc0
commit a6a84d7160
19 changed files with 1388 additions and 1055 deletions

View File

@ -2,9 +2,9 @@
0.9.21: 2006-Mar-14
* skeletons/standard-modules directory is now used for standard types.
* Refactored system for parsing Information Object Classes.
* Fixed class field access problem (Test case 98)
(Severity: medim; Security impact: none)
* Refactored system for parsing Information Object Classes.
0.9.20: 2006-Mar-06

View File

@ -129,8 +129,10 @@ main(int ac, char **av) {
exit(EX_USAGE);
}
asn1_compiler_flags |= A1C_PDU_AUTO;
} else if(strcmp(optarg, "rint-class-matrix") == 0) {
asn1_printer_flags |= APF_PRINT_CLASS_MATRIX;
} else if(strcmp(optarg, "rint-constraints") == 0) {
asn1_printer_flags |= APF_DEBUG_CONSTRAINTS;
asn1_printer_flags |= APF_PRINT_CONSTRAINTS;
} else if(strcmp(optarg, "rint-lines") == 0) {
asn1_printer_flags |= APF_LINE_COMMENTS;
} else {
@ -459,6 +461,7 @@ usage(const char *av0) {
"\n"
" -print-constraints Explain subtype constraints (debug)\n"
" -print-class-matrix Print out the collected object class matrix (debug)\n"
" -print-lines Generate \"-- #line\" comments in -E output\n"
,

View File

@ -188,8 +188,9 @@ asn1f_fix_module__phase_1(arg_t *arg) {
/* Do not process the parametrized type just yet */
continue;
DEBUG("=== Now processing \"%s\" at line %d ===",
expr->Identifier, expr->_lineno);
DEBUG("=== Now processing \"%s\" (%d/0x%x) at line %d ===",
expr->Identifier, expr->meta_type, expr->expr_type,
expr->_lineno);
assert(expr->meta_type != AMT_INVALID);
/*
@ -223,9 +224,10 @@ asn1f_fix_module__phase_1(arg_t *arg) {
RET2RVAL(ret, rvalue);
/*
* Parse WITH SYNTAX in CLASSes.
* Parse class objects and fill up the object class with data.
*/
ret = asn1f_parse_class_with_syntax(arg);
ret = asn1f_parse_class_object(arg);
RET2RVAL(ret, rvalue);
/*
* Resolve references in constraints.
@ -293,6 +295,9 @@ asn1f_fix_module__phase_2(arg_t *arg) {
int rvalue = 0;
int ret;
TQ_FOR(expr, &(arg->mod->members), next) {
}
TQ_FOR(expr, &(arg->mod->members), next) {
arg->expr = expr;

View File

@ -1,15 +1,226 @@
#include "asn1fix_internal.h"
#include "asn1fix_cws.h"
int
asn1f_parse_class_with_syntax(arg_t *arg) {
asn1p_expr_t *expr = arg->expr;
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);
if(expr->expr_type != A1TC_CLASSDEF
|| expr->with_syntax == 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;
if(expr->meta_type != AMT_VALUE
|| expr->expr_type != A1TC_REFERENCE
|| !expr->value
|| expr->value->type != ATV_UNPARSED)
return 0;
DEBUG("Class %s: checking WITH SYNTAX", expr->Identifier);
/*
* Find the governing class.
*/
eclass = asn1f_find_terminal_type(arg, expr);
if(!eclass
|| eclass->meta_type != AMT_OBJECTCLASS
|| eclass->expr_type != A1TC_CLASSDEF) {
return 0;
}
DEBUG("Value %s of CLASS %s found at line %d",
expr->Identifier, eclass->Identifier, expr->_lineno);
if(!eclass->with_syntax) {
DEBUG("Can't process classes without WITH SYNTAX just yet");
return 0;
}
row = asn1p_ioc_row_new(eclass);
assert(row);
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((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;
return 0;
}
#define SKIPSPACES for(; buf < bend && isspace(*buf); buf++)
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) {
struct asn1p_wsyntx_chunk_s *chunk;
int ret;
TQ_FOR(chunk, (&syntax->chunks), next) {
switch(chunk->type) {
case WC_LITERAL: {
int token_len = strlen(chunk->content.token);
SKIPSPACES;
if(bend - buf < token_len
|| memcmp(buf, chunk->content.token, token_len)) {
if(!optional_mode) {
FATAL("While parsing object class value %s at line %d: Expected: \"%s\", found: \"%s\"",
arg->expr->Identifier, arg->expr->_lineno, chunk->content.token, buf);
}
if(newpos) *newpos = buf;
return -1;
}
buf += token_len;
} break;
case WC_WHITESPACE: break; /* Ignore whitespace */
case WC_FIELD: {
struct asn1p_ioc_cell_s *cell;
uint8_t *p;
SKIPSPACES;
int lbraces = 0;
p = buf;
if(p < bend && *p == '{')
lbraces = 1, p++;
for(; p < bend; p++) {
if(lbraces) {
/* Search the terminating brace */
switch(*p) {
case '}': lbraces--; break;
case '{': lbraces++; break;
}
} else if(isspace(*p)) {
break;
}
}
if(lbraces) {
FATAL("Field reference %s found in class value definition for %s at line %d can not be satisfied by broken value \"%s\"",
chunk->content.token,
arg->expr->Identifier, arg->expr->_lineno, buf);
if(newpos) *newpos = buf;
return -1;
}
cell = asn1p_ioc_row_cell_fetch(row,
chunk->content.token);
if(cell == NULL) {
FATAL("Field reference %s found in WITH SYNAX {} clause does not match actual field in Object Class %s",
chunk->content.token,
eclass->Identifier, eclass->_lineno);
if(newpos) *newpos = buf;
return -1;
}
DEBUG("Reference %s satisfied by %s (%d)",
chunk->content.token,
buf, p - buf);
ret = _asn1f_assign_cell_value(arg, row, cell, buf, p);
if(ret) {
if(newpos) *newpos = buf;
return ret;
}
buf = p;
} break;
case WC_OPTIONALGROUP: {
uint8_t *np = 0;
SKIPSPACES;
ret = _asn1f_parse_class_object_data(arg, eclass, row,
chunk->content.syntax, buf, bend, 1, &np);
if(newpos) *newpos = np;
if(ret && np != buf)
return ret;
} break;
}
}
if(newpos) *newpos = buf;
return 0;
}
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_ref_t *ref;
char *p;
if((bend - buf) <= 0) {
FATAL("Assignment warning: empty string is being assigned into %s for %s at line %d",
cell->field->Identifier,
arg->expr->Identifier, arg->expr->_lineno);
return -1;
}
p = malloc(bend - buf + 1);
assert(p);
memcpy(p, buf, bend - buf);
p[bend - buf] = '\0';
if(!isalpha(*p)) {
if(isdigit(*p)) {
asn1c_integer_t value;
if(asn1p_atoi(p, &value)) {
FATAL("Value %s at line %d is too large for this compiler! Please contact the asn1c author.\n", p, arg->expr->_lineno);
return -1;
}
expr = asn1p_expr_new(arg->expr->_lineno);
expr->Identifier = p;
expr->meta_type = AMT_VALUE;
expr->expr_type = ASN_BASIC_INTEGER;
expr->value = asn1p_value_fromint(value);
} else {
WARNING("asn1c is not yet able to parse arbitrary direct values; please convert %s at line %d to a reference.", p, arg->expr->_lineno);
free(p);
return 1;
}
} else {
ref = asn1p_ref_new(arg->expr->_lineno);
asn1p_ref_add_component(ref, p, RLT_UNKNOWN);
assert(ref);
expr = asn1f_lookup_symbol(arg, arg->mod, ref);
if(!expr) {
FATAL("Cannot find %s referenced by %s at line %d",
p, arg->expr->Identifier,
arg->expr->_lineno);
return -1;
}
}
DEBUG("Field %s assignment of %s got %s",
cell->field->Identifier, p, expr->Identifier);
cell->value = expr;
if(row->max_identifier_length < strlen(expr->Identifier))
row->max_identifier_length = strlen(expr->Identifier);
return 0;
}

View File

@ -2,9 +2,8 @@
#define _ASN1FIX_CLASS_WITH_SYNTAX_H_
/*
* CLASS may contain the "WITH SYNTAX" clause, in which case we are
* going to parse it.
* Parse class objects
*/
int asn1f_parse_class_with_syntax(arg_t *arg);
int asn1f_parse_class_object(arg_t *arg);
#endif /* _ASN1FIX_CLASS_WITH_SYNTAX_H_ */

View File

@ -6,6 +6,61 @@
#include "asn1parser.h"
asn1p_ioc_row_t *
asn1p_ioc_row_new(asn1p_expr_t *oclass) {
asn1p_ioc_row_t *row;
asn1p_expr_t *field;
int columns = 0;
assert(oclass->expr_type == A1TC_CLASSDEF);
row = calloc(1, sizeof *row);
if(!row) return NULL;
TQ_FOR(field, &oclass->members, next)
columns++;
row->column = calloc(columns, sizeof *row->column);
if(!row->column) {
free(row);
return NULL;
}
row->columns = columns;
columns = 0;
TQ_FOR(field, &oclass->members, next) {
int 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++;
}
return row;
}
void
asn1p_ioc_row_delete(asn1p_ioc_row_t *row) {
if(row) {
if(row->column) {
free(row->column);
}
free(row);
}
}
struct asn1p_ioc_cell_s *
asn1p_ioc_row_cell_fetch(asn1p_ioc_row_t *row, const char *fieldname) {
int i;
for(i = 0; i < row->columns; i++) {
if(strcmp(row->column[i].field->Identifier, fieldname) == 0)
return &row->column[i];
}
errno = ESRCH;
return NULL;
}
asn1p_wsyntx_chunk_t *
asn1p_wsyntx_chunk_new() {
asn1p_wsyntx_chunk_t *wc;
@ -21,8 +76,8 @@ asn1p_wsyntx_chunk_free(asn1p_wsyntx_chunk_t *wc) {
switch(wc->type) {
case WC_LITERAL:
case WC_WHITESPACE:
case WC_FIELD:
free(wc->content.token); break;
case WC_REFERENCE: asn1p_ref_free(wc->content.ref); break;
case WC_OPTIONALGROUP:
asn1p_wsyntx_free(wc->content.syntax);
break;
@ -41,12 +96,10 @@ asn1p_wsyntx_chunk_clone(asn1p_wsyntx_chunk_t *wc) {
switch(wc->type) {
case WC_LITERAL:
case WC_WHITESPACE:
case WC_FIELD:
nc->content.token = malloc(strlen(wc->content.token)+1);
strcpy(nc->content.token, wc->content.token);
break;
case WC_REFERENCE:
nc->content.ref = asn1p_ref_clone(wc->content.ref);
break;
case WC_OPTIONALGROUP:
nc->content.syntax = asn1p_wsyntx_clone(wc->content.syntax);
break;
@ -100,26 +153,6 @@ asn1p_wsyntx_clone(asn1p_wsyntx_t *wx) {
return nw;
}
asn1p_wsyntx_chunk_t *
asn1p_wsyntx_chunk_fromref(asn1p_ref_t *ref, int do_copy) {
asn1p_wsyntx_chunk_t *wc;
if(do_copy) {
static asn1p_wsyntx_chunk_t tmp;
tmp.type = WC_REFERENCE;
tmp.content.ref = ref;
wc = asn1p_wsyntx_chunk_clone(&tmp);
} else {
wc = asn1p_wsyntx_chunk_new();
if(wc) {
wc->type = WC_REFERENCE;
wc->content.ref = ref;
}
}
return wc;
}
asn1p_wsyntx_chunk_t *
asn1p_wsyntx_chunk_frombuf(char *buf, int len, int do_copy) {
asn1p_wsyntx_chunk_t *wc;

View File

@ -6,6 +6,22 @@
#include "asn1p_ref.h"
struct asn1p_expr_s; /* Forward declaration */
typedef struct asn1p_ioc_row_s {
struct asn1p_ioc_cell_s {
struct asn1p_expr_s *field; /* may never be NULL */
struct asn1p_expr_s *value; /* may be left uninitialized */
} *column;
int columns;
int max_identifier_length;
} asn1p_ioc_row_t;
asn1p_ioc_row_t *asn1p_ioc_row_new(struct asn1p_expr_s *oclass);
void asn1p_ioc_row_delete(asn1p_ioc_row_t *);
struct asn1p_ioc_cell_s *asn1p_ioc_row_cell_fetch(asn1p_ioc_row_t *,
const char *fieldname);
/*
* WITH SYNTAX free-form chunks.
*/
@ -13,18 +29,17 @@ typedef struct asn1p_wsyntx_chunk_s {
enum {
WC_LITERAL,
WC_WHITESPACE,
WC_REFERENCE,
WC_FIELD,
WC_OPTIONALGROUP
} type;
/*
* WC_LITERAL -> {token}
* WC_WHITESPACE -> {token}
* WC_REFERENCE -> {ref}
* WC_FIELD -> {token}
* WC_OPTIONALGROUP -> {syntax}
*/
union {
char *token;
asn1p_ref_t *ref;
char *token;
struct asn1p_wsyntx_s *syntax;
} content;
@ -54,7 +69,6 @@ asn1p_wsyntx_t *asn1p_wsyntx_clone(asn1p_wsyntx_t *);
* 0: Component has been added
* -1: Failure to add component (refer to errno)
*/
asn1p_wsyntx_chunk_t *asn1p_wsyntx_chunk_fromref(asn1p_ref_t *ref, int do_copy);
asn1p_wsyntx_chunk_t *asn1p_wsyntx_chunk_frombuf(char *buf, int len, int _copy);
asn1p_wsyntx_chunk_t *asn1p_wsyntx_chunk_fromsyntax(asn1p_wsyntx_t *syntax);

View File

@ -163,6 +163,13 @@ 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;
int rows;
int max_identifier_length;
} object_class_matrix;
/*
* A tag.
*/

File diff suppressed because it is too large Load Diff

View File

@ -23,10 +23,11 @@ void asn1p_lexer_hack_push_encoding_control(void); /* Used in .y */
int asn1p_lexer_pedantic_1990 = 0;
int asn1p_lexer_types_year = 0;
int asn1p_lexer_constructs_year = 0;
static asn1c_integer_t asn1p_atoi(char *ptr); /* errno is either 0 or ERANGE */
int asn1p_as_pointer;
static asn1c_integer_t _lex_atoi(const char *ptr);
/*
* Check that the type is defined in the year of the standard choosen.
*/
@ -219,21 +220,21 @@ WSP [\t\r\v\f\n ]
-[1-9][0-9]* {
asn1p_lval.a_int = asn1p_atoi(yytext);
asn1p_lval.a_int = _lex_atoi(yytext);
if(errno == ERANGE)
return -1;
return TOK_number_negative;
}
[1-9][0-9]* {
asn1p_lval.a_int = asn1p_atoi(yytext);
asn1p_lval.a_int = _lex_atoi(yytext);
if(errno == ERANGE)
return -1;
return TOK_number;
}
"0" {
asn1p_lval.a_int = asn1p_atoi(yytext);
asn1p_lval.a_int = _lex_atoi(yytext);
if(errno == ERANGE)
return -1;
return TOK_number;
@ -437,10 +438,10 @@ WITH return TOK_WITH;
char *p;
for(p = yytext; *p; p++)
if(*p >= '0' && *p <= '9')
{ v1 = asn1p_atoi(p); break; }
{ v1 = _lex_atoi(p); break; }
while(*p >= '0' && *p <= '9') p++; /* Skip digits */
for(; *p; p++) if(*p >= '0' && *p <= '9')
{ v2 = asn1p_atoi(p); break; }
{ v2 = _lex_atoi(p); break; }
if(v1 < 0 || v1 > 7) {
fprintf(stderr, "%s at line %d: X.680:2003, #37.14 "
"mandates 0..7 range for Tuple's TableColumn\n",
@ -462,16 +463,16 @@ WITH return TOK_WITH;
char *p;
for(p = yytext; *p; p++)
if(*p >= '0' && *p <= '9')
{ v1 = asn1p_atoi(p); break; }
{ v1 = _lex_atoi(p); break; }
while(*p >= '0' && *p <= '9') p++; /* Skip digits */
for(; *p; p++) if(*p >= '0' && *p <= '9')
{ v2 = asn1p_atoi(p); break; }
{ v2 = _lex_atoi(p); break; }
while(*p >= '0' && *p <= '9') p++;
for(; *p; p++) if(*p >= '0' && *p <= '9')
{ v3 = asn1p_atoi(p); break; }
{ v3 = _lex_atoi(p); break; }
while(*p >= '0' && *p <= '9') p++;
for(; *p; p++) if(*p >= '0' && *p <= '9')
{ v4 = asn1p_atoi(p); break; }
{ v4 = _lex_atoi(p); break; }
if(v1 < 0 || v1 > 127) {
fprintf(stderr, "%s at line %d: X.680:2003, #37.12 "
"mandates 0..127 range for Quadruple's Group\n",
@ -552,30 +553,14 @@ void asn1p_lexer_hack_push_encoding_control() {
}
static asn1c_integer_t
asn1p_atoi(char *ptr) {
_lex_atoi(const char *ptr) {
asn1c_integer_t value;
errno = 0; /* Clear the error code */
if(sizeof(value) <= sizeof(int)) {
value = strtol(ptr, 0, 10);
} else {
#ifdef HAVE_STRTOIMAX
value = strtoimax(ptr, 0, 10);
#elif HAVE_STRTOLL
value = strtoll(ptr, 0, 10);
#else
value = strtol(ptr, 0, 10);
#endif
}
if(errno == ERANGE) {
if(asn1p_atoi(ptr, &value)) {
fprintf(stderr,
"Value \"%s\" at line %d is too large "
"for this compiler! Please contact the asn1c author.\n",
ptr, yylineno);
errno = ERANGE; /* Restore potentially clobbered errno */
errno = ERANGE;
}
return value;
}

File diff suppressed because it is too large Load Diff

View File

@ -242,8 +242,7 @@ static void _fixup_anonymous_identifier(asn1p_expr_t *expr);
%type <a_ref> ComplexTypeReference
%type <a_ref> ComplexTypeReferenceAmpList
%type <a_refcomp> ComplexTypeReferenceElement
%type <a_refcomp> ClassFieldIdentifier
%type <a_refcomp> ClassFieldName
%type <a_refcomp> PrimitiveFieldReference
%type <a_expr> FieldSpec
%type <a_ref> FieldName
%type <a_ref> DefinedObjectClass
@ -1081,14 +1080,9 @@ WithSyntaxToken:
| TOK_Literal {
$$ = asn1p_wsyntx_chunk_frombuf($1, strlen($1), 0);
}
| ClassFieldIdentifier {
asn1p_ref_t *ref;
int ret;
ref = asn1p_ref_new(yylineno);
checkmem(ref);
ret = asn1p_ref_add_component(ref, $1.name, $1.lex_type);
checkmem(ret == 0);
$$ = asn1p_wsyntx_chunk_fromref(ref, 0);
| PrimitiveFieldReference {
$$ = asn1p_wsyntx_chunk_frombuf($1.name, strlen($1.name), 0);
$$->type = WC_FIELD;
}
| '[' WithSyntaxList ']' {
$$ = asn1p_wsyntx_chunk_fromsyntax($2);
@ -1365,10 +1359,9 @@ ComplexTypeReferenceAmpList:
}
;
ComplexTypeReferenceElement: ClassFieldName;
ClassFieldIdentifier: ClassFieldName;
ComplexTypeReferenceElement: PrimitiveFieldReference;
ClassFieldName:
PrimitiveFieldReference:
/* "&Type1" */
TOK_typefieldreference {
$$.lex_type = RLT_AmpUppercase;

View File

@ -1,5 +1,6 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <assert.h>
@ -184,3 +185,21 @@ _asn1p_fix_modules(asn1p_t *a, const char *fname) {
}
int
asn1p_atoi(const char *ptr, asn1c_integer_t *value) {
errno = 0; /* Clear the error code */
if(sizeof(*value) <= sizeof(int)) {
*value = strtol(ptr, 0, 10);
} else {
#ifdef HAVE_STRTOIMAX
*value = strtoimax(ptr, 0, 10);
#elif HAVE_STRTOLL
*value = strtoll(ptr, 0, 10);
#else
*value = strtol(ptr, 0, 10);
#endif
}
return errno == 0 ? 0 : -1;
}

View File

@ -69,4 +69,6 @@ asn1p_t *asn1p_parse_file(const char *filename,
asn1p_t *asn1p_parse_buffer(const char *buffer, int size /* = -1 */,
enum asn1p_flags);
int asn1p_atoi(const char *ptr, asn1c_integer_t *r_value);
#endif /* ASN1PARSER_H */

View File

@ -106,7 +106,7 @@ asn1print_module(asn1p_t *asn, asn1p_module_t *mod, enum asn1print_flags flags)
TQ_FOR(tc, &(mod->members), next) {
asn1print_expr(asn, mod, tc, flags, 0);
if(flags & APF_DEBUG_CONSTRAINTS)
if(flags & APF_PRINT_CONSTRAINTS)
printf("\n");
else
printf("\n\n");
@ -416,11 +416,9 @@ asn1print_with_syntax(asn1p_wsyntx_t *wx, enum asn1print_flags flags) {
switch(wc->type) {
case WC_LITERAL:
case WC_WHITESPACE:
case WC_FIELD:
printf("%s", wc->content.token);
break;
case WC_REFERENCE:
asn1print_ref(wc->content.ref, flags);
break;
case WC_OPTIONALGROUP:
printf("[");
asn1print_with_syntax(wc->content.syntax,flags);
@ -690,7 +688,7 @@ asn1print_expr(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *tc, enum asn1pri
/*
* The following section exists entirely for debugging.
*/
if(flags & APF_DEBUG_CONSTRAINTS
if(flags & APF_PRINT_CONSTRAINTS
&& tc->expr_type != A1TC_EXTENSIBLE) {
asn1p_expr_t *top_parent;
@ -713,6 +711,41 @@ asn1print_expr(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *tc, enum asn1pri
printf("\n");
}
if(flags & APF_PRINT_CLASS_MATRIX
&& tc->expr_type == A1TC_CLASSDEF) do {
int r, col, maxidlen;
if(tc->object_class_matrix.rows == 0) {
printf("\n-- Class matrix is empty");
break;
}
printf("\n-- Class matrix 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(r = -1; r < tc->object_class_matrix.rows; r++) {
struct asn1p_ioc_row_s *row;
row = tc->object_class_matrix.row[r<0?0:r];
if(r < 0) printf("-- %s", r > 9 ? " " : "");
else printf("-- [%*d]", r > 9 ? 2 : 1, r+1);
for(col = 0; col < row->columns; col++) {
struct asn1p_ioc_cell_s *cell;
cell = &row->column[col];
if(r < 0) {
printf("[%*s]", maxidlen,
cell->field->Identifier);
continue;
}
if(!cell->value) {
printf(" %*s ", maxidlen, "<no entry>");
continue;
}
printf(" %*s ", maxidlen,
cell->value->Identifier);
}
printf("\n");
}
} while(0);
return 0;
}

View File

@ -3,10 +3,11 @@
enum asn1print_flags {
APF_NOFLAGS,
APF_LINE_COMMENTS = 0x01, /* Include line comments */
APF_DEBUG_CONSTRAINTS = 0x02, /* Explain constraints */
APF_NOINDENT = 0x01, /* Disable indentation */
APF_LINE_COMMENTS = 0x02, /* Include line comments */
APF_PRINT_XML_DTD = 0x04, /* Generate XML DTD */
APF_NOINDENT = 0x08, /* Disable indentation */
APF_PRINT_CONSTRAINTS = 0x08, /* Explain constraints */
APF_PRINT_CLASS_MATRIX = 0x10, /* Dump class matrix */
};
/*

View File

@ -14,7 +14,7 @@ BEGIN
-- First CLASS
EXTENSION ::= CLASS {
&id [PRIVATE 0] OBJECT IDENTIFIER UNIQUE,
&id [PRIVATE 0] INTEGER UNIQUE,
&ExtnType
} WITH SYNTAX {
SYNTAX &ExtnType
@ -35,6 +35,8 @@ BEGIN
terminal-type EXTENSION-ATTRIBUTE ::= {TerminalType IDENTIFIED BY 23}
TerminalType ::= INTEGER { terminal(0) }
-- Advanced CLASS extraction
ExtensionAttribute ::= SEQUENCE {

View File

@ -4,7 +4,7 @@ DEFINITIONS IMPLICIT TAGS ::=
BEGIN
EXTENSION ::= CLASS {
&id [PRIVATE 0] OBJECT IDENTIFIER UNIQUE,
&id [PRIVATE 0] INTEGER UNIQUE,
&ExtnType
} WITH SYNTAX {
SYNTAX &ExtnType
@ -24,6 +24,10 @@ EXTENSION-ATTRIBUTE ::= CLASS {
terminal-type EXTENSION-ATTRIBUTE ::= {TerminalType IDENTIFIED BY 23}
TerminalType ::= INTEGER {
terminal(0)
}
ExtensionAttribute ::= SEQUENCE {
extension-attribute-type [0] IMPLICIT EXTENSION-ATTRIBUTE.&id ({ExtensionAttributeTable}),
extension-attribute-value [1] EXPLICIT EXTENSION-ATTRIBUTE.&Type ({ExtensionAttributeTable}{@extension-attribute-type})

View File

@ -0,0 +1,43 @@
ModuleTestClassSimple { iso org(3) dod(6) internet(1) private(4) enterprise(1)
spelio(9363) software(1) asn1c(5) test(1) 34 }
DEFINITIONS IMPLICIT TAGS ::=
BEGIN
EXTENSION ::= CLASS {
&id [PRIVATE 0] INTEGER UNIQUE,
&ExtnType
} WITH SYNTAX {
SYNTAX &ExtnType
IDENTIFIED BY &id
}
-- Class matrix is empty
Ext1 ::= SEQUENCE {
extnId EXTENSION.&id
}
EXTENSION-ATTRIBUTE ::= CLASS {
&id INTEGER (0..256) UNIQUE,
&Type ANY
} WITH SYNTAX {&Type IDENTIFIED BY &id}
-- Class matrix has 1 entry:
-- [ &id][ &Type]
-- [1] 23 TerminalType
terminal-type EXTENSION-ATTRIBUTE ::= {TerminalType IDENTIFIED BY 23}
TerminalType ::= INTEGER {
terminal(0)
}
ExtensionAttribute ::= SEQUENCE {
extension-attribute-type [0] IMPLICIT EXTENSION-ATTRIBUTE.&id ({ExtensionAttributeTable}),
extension-attribute-value [1] EXPLICIT EXTENSION-ATTRIBUTE.&Type ({ExtensionAttributeTable}{@extension-attribute-type})
}
ub-extension-attributes INTEGER ::= 256
END