mirror of https://gerrit.osmocom.org/asn1c
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:
parent
eeb3c51bc0
commit
a6a84d7160
|
@ -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
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
||||
,
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
@ -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
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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})
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue