parsing object classes more properly

This commit is contained in:
Lev Walkin 2006-03-09 08:49:26 +00:00
parent 9344c9fdbf
commit 9c2285abf3
10 changed files with 1219 additions and 1216 deletions

View File

@ -96,7 +96,8 @@ asn1c_compile_expr(arg_t *arg) {
switch(expr->meta_type) {
case AMT_PARAMTYPE:
case AMT_OBJECT:
case AMT_OBJECTSET:
case AMT_OBJECTCLASS:
case AMT_OBJECTFIELD:
case AMT_VALUE:
case AMT_VALUESET:
ret = 0;
@ -104,13 +105,6 @@ asn1c_compile_expr(arg_t *arg) {
default:
break;
}
switch(expr->expr_type) {
case A1TC_TYPEID:
ret = 0; /* TYPE-IDENTIFIER is a CLASS */
default:
break;
}
}
if(ret == -1) {

View File

@ -433,6 +433,7 @@ asn1f_check_constraints(arg_t *arg) {
static int
asn1f_check_duplicate(arg_t *arg) {
arg_t tmparg = *arg;
int rvalue = 0;
/*
* This is a linear scan in search of a similar type.
@ -478,11 +479,12 @@ asn1f_check_duplicate(arg_t *arg) {
diff_files ? ")" : "");
if(critical)
return -1;
RET2RVAL(1, rvalue);
}
if(tmparg.mod == arg->mod) break;
}
return 0;
return rvalue;
}
static int

View File

@ -1,38 +1,15 @@
#include "asn1fix_internal.h"
typedef enum field_category {
OFC_INVALID, /* Invalid object field category */
OFC_TYPE,
OFC_FIXED_TYPE_VALUE,
OFC_VARIABLE_TYPE_VALUE,
OFC_FIXED_TYPE_VALUE_SET,
OFC_VARIABLE_TYPE_VALUE_SET,
OFC_INFORMATION_OBJECT,
OFC_INFORMATION_OBJECT_SET,
} field_category_e;
typedef enum object_category {
OC_INVALID,
OC_OBJECT,
OC_OBJECTSET,
} object_category_e;
static field_category_e asn1f_class_field_category(asn1p_expr_t *ofield);
static object_category_e asn1f_class_object_category(asn1p_expr_t *expr);
static asn1p_expr_t *
asn1f_class_dot_lookup(arg_t *arg, asn1p_expr_t *obj, asn1p_ref_t *ref);
asn1p_expr_t *
asn1f_class_access(arg_t *arg, asn1p_module_t *mod, asn1p_ref_t *ref) {
asn1p_expr_t *obj; /* Information Object or Object Set */
object_category_e obj_cat; /* Object category */
//field_category_e field_cat; /* Field category */
asn1p_expr_t *result;
asn1p_expr_t *ioclass;
asn1p_expr_t *classfield;
asn1p_expr_t *expr;
asn1p_ref_t tmpref;
assert(ref->comp_count > 1);
DEBUG("(%s) for line %d", asn1f_printable_reference(ref), ref->_lineno);
DEBUG("ClassAccess lookup (%s) for line %d", asn1f_printable_reference(ref), ref->_lineno);
/*
* Fetch the first part of the reference (OBJECT or ObjectSet).
@ -43,198 +20,47 @@ asn1f_class_access(arg_t *arg, asn1p_module_t *mod, asn1p_ref_t *ref) {
tmpref = *ref;
tmpref.comp_count = 1;
obj = asn1f_lookup_symbol(arg, mod, &tmpref);
if(obj == NULL) {
ioclass = asn1f_lookup_symbol(arg, mod, &tmpref);
if(ioclass == NULL) {
errno = ESRCH;
return NULL;
}
/*
* Make sure the symbol lexical property (upper-case, lower-case)
* corresponds to the type of the expression returned by
* lookup_symbol().
*/
obj_cat = asn1f_class_object_category(obj);
switch(obj_cat) {
case OC_OBJECT:
case OC_OBJECTSET:
if(ref->components[0].lex_type
== (obj_cat==OC_OBJECT)
? RLT_CAPITALS
: RLT_Uppercase)
break;
/* Fall through */
case OC_INVALID:
WARNING("Symbol \"%s\" is not compatible "
"with referenced expression \"%s\" at line %d",
ref->components[0].name,
obj->Identifier, obj->_lineno);
errno = EPERM;
classfield = asn1f_lookup_child(ioclass, ref->components[1].name);
if(classfield == NULL) {
DEBUG("CLASS %s does not contain field %s",
ioclass->Identifier, ref->components[1].name);
errno = ESRCH;
return NULL;
}
/*
* Find the specified field within the object.
*/
result = asn1f_class_dot_lookup(arg, obj, ref);
if(result == NULL) {
return NULL;
}
assert(classfield->meta_type == AMT_OBJECTFIELD);
//field_cat = asn1f_class_field_category(result);
DEBUG("CLASS %s -> %s (%d)", ioclass->Identifier,
classfield->Identifier, classfield->expr_type);
DEBUG("FILLME: %s", result->Identifier);
return result;
}
static object_category_e
asn1f_class_object_category(asn1p_expr_t *expr) {
switch(expr->meta_type) {
case AMT_OBJECT:
return OC_OBJECT;
case AMT_OBJECTSET:
return OC_OBJECTSET;
case AMT_VALUESET:
if(expr->expr_type == A1TC_REFERENCE
&& expr->reference
&& expr->reference->comp_count == 1
&& expr->reference->components[0].lex_type == RLT_CAPITALS)
{
/* FIXME: use find_terminal_type instead! */
return OC_OBJECTSET;
switch(classfield->expr_type) {
case A1TC_CLASSFIELD_TFS:
if(TQ_FIRST(&classfield->members)) {
/* Already have something */
} else {
expr = asn1p_expr_new(classfield->_lineno);
expr->expr_type = ASN_TYPE_ANY;
expr->meta_type = AMT_TYPE;
asn1p_expr_add(classfield, expr);
}
/* Fall through */
case A1TC_CLASSFIELD_FTVFS:
expr = TQ_FIRST(&classfield->members);
assert(expr);
return expr;
break;
default:
break;
FATAL("%s.%s: field type not yet supported. "
"Consider donation to the asn1c author.",
ioclass->Identifier, classfield->Identifier);
return NULL;
}
return OC_INVALID;
}
static field_category_e
asn1f_class_field_category(asn1p_expr_t *ofield) {
assert(ofield);
if(ofield->Identifier[0] != '&') {
assert(ofield->Identifier[0] == '&');
return OFC_INVALID;
}
if(isupper(ofield->Identifier[1])) {
if(ofield->reference) {
enum asn1p_ref_lex_type_e lex_type
= ofield->reference->components[0].lex_type;
switch(lex_type) {
case RLT_CAPITALS:
return OFC_INFORMATION_OBJECT_SET;
case RLT_Uppercase:
return OFC_FIXED_TYPE_VALUE_SET;
case RLT_AmpUppercase:
return OFC_VARIABLE_TYPE_VALUE_SET;
default:
break;
}
} else {
if(ofield->expr_type == A1TC_CLASSFIELD)
return OFC_TYPE;
switch(ofield->meta_type) {
case AMT_TYPE:
case AMT_TYPEREF:
return OFC_FIXED_TYPE_VALUE_SET;
default:
break;
}
}
} else {
if(ofield->reference) {
enum asn1p_ref_lex_type_e lex_type
= ofield->reference->components[0].lex_type;
switch(lex_type) {
case RLT_CAPITALS:
return OFC_INFORMATION_OBJECT;
case RLT_Uppercase:
return OFC_FIXED_TYPE_VALUE;
case RLT_AmpUppercase:
return OFC_VARIABLE_TYPE_VALUE;
default:
break;
}
} else {
switch(ofield->meta_type) {
case AMT_TYPE:
case AMT_TYPEREF:
return OFC_FIXED_TYPE_VALUE;
default:
break;
}
}
}
return OFC_INVALID;
}
static asn1p_expr_t *
asn1f_class_dot_lookup(arg_t *arg, asn1p_expr_t *obj, asn1p_ref_t *ref) {
asn1p_expr_t *ofield = NULL; /* Information Object's Field */
field_category_e field_cat; /* Field category */
int comp;
assert(ref->comp_count >= 2);
for(comp = 1 /* sic! */; comp < ref->comp_count; comp++) {
int is_last_component = (comp + 1 == ref->comp_count);
char *comp_name = ref->components[comp].name;
ofield = asn1f_lookup_child(obj, comp_name);
if(ofield == NULL) {
DEBUG("Cannot find field \"%s\" in \"%s\" at line %d",
ref->components[1].name,
obj->Identifier,
obj->_lineno);
errno = EPERM;
return NULL;
}
/*
* Compute the category of the field of
* the information object class.
*/
field_cat = asn1f_class_field_category(ofield);
switch(field_cat) {
case OFC_INVALID:
WARNING("Invalid field category of \"%s\" at line %d",
ofield->Identifier, ofield->_lineno);
errno = EPERM;
return NULL;
case OFC_TYPE:
case OFC_FIXED_TYPE_VALUE:
case OFC_VARIABLE_TYPE_VALUE:
case OFC_FIXED_TYPE_VALUE_SET:
case OFC_VARIABLE_TYPE_VALUE_SET:
if(!is_last_component) {
FATAL("Field name component \"%s\" at line %d "
"specifies non-dereferenceable thing",
comp_name, ref->_lineno);
errno = EPERM;
return NULL;
}
break;
case OFC_INFORMATION_OBJECT:
case OFC_INFORMATION_OBJECT_SET:
obj = ofield;
break;
}
}
assert(ofield);
return ofield;
return NULL;
}

View File

@ -25,6 +25,9 @@ static int
asn1f_fetch_tags_impl(arg_t *arg, struct asn1p_type_tag_s **tags, int count, int skip, enum asn1f_aft_flags_e flags) {
asn1p_expr_t *expr = arg->expr;
DEBUG("Fetching tag from %s: meta %d, type %s", expr->Identifier,
expr->meta_type, expr->expr_type);
/* If this type is tagged, add this tag first */
if(expr->tag.tag_class != TC_NOCLASS)
ADD_TAG(skip, expr->tag);

View File

@ -185,8 +185,10 @@ check(const char *fname,
std_asn = asn1p_parse_file("../skeletons/standard-modules/ASN1C-UsefulInformationObjectClasses.asn1", A1P_NOFLAGS);
if(std_asn) {
asn1p_module_t *mod;
while((mod = TQ_REMOVE(&(std_asn->modules), mod_next)))
while((mod = TQ_REMOVE(&(std_asn->modules), mod_next))) {
mod->_tags |= MT_STANDARD_MODULE;
TQ_ADD(&(asn->modules), mod, mod_next);
}
asn1p_free(std_asn);
}
}

View File

@ -14,8 +14,8 @@ typedef enum asn1p_expr_meta {
AMT_PARAMTYPE, /* Type3{Parameter} ::= SET { ... } */
AMT_VALUE, /* value1 Type1 ::= 1 */
AMT_VALUESET, /* ValueSet Type1 ::= { value1 } */
AMT_OBJECT, /* FUNCTION ::= CLASS {...} */
AMT_OBJECTSET, /* Functions FUNCTION ::= {...} */
AMT_OBJECT, /* object CLASS ::= {...} */
AMT_OBJECTCLASS, /* FUNCTION ::= CLASS {...} */
AMT_OBJECTFIELD, /* ... */
AMT_EXPR_META_MAX
} asn1p_expr_meta_e;
@ -38,14 +38,24 @@ typedef enum asn1p_expr_type {
A1TC_PARAMETRIZED, /* A parametrized type declaration */
A1TC_VALUESET, /* Value set definition */
A1TC_CLASSDEF, /* Information Object Class */
A1TC_CLASSFIELD, /* Information Object Class field */
A1TC_INSTANCE, /* Instance of Object Class */
A1TC_TYPEID, /* Type identifier */
/*
* ASN.1 Class field types
*/
#define ASN_CLASSFIELD_MASK 0x10 /* Every class field type */
A1TC_CLASSFIELD_TFS = ASN_CLASSFIELD_MASK, /* TypeFieldSpec */
A1TC_CLASSFIELD_FTVFS, /* FixedTypeValueFieldSpec */
A1TC_CLASSFIELD_VTVFS, /* VariableTypeValueFieldSpec */
A1TC_CLASSFIELD_FTVSFS, /* FixedTypeValueSetFieldSpec */
A1TC_CLASSFIELD_VTVSFS, /* VariableTypeValueSetFieldSpec */
A1TC_CLASSFIELD_OFS, /* ObjectFieldSpec */
A1TC_CLASSFIELD_OSFS, /* ObjectSetFieldSpec */
/*
* ASN.1 Constructed types
*/
#define ASN_CONSTR_MASK 0x10 /* Every constructed type */
#define ASN_CONSTR_MASK 0x20 /* Every constructed type */
ASN_CONSTR_SEQUENCE = ASN_CONSTR_MASK, /* SEQUENCE */
ASN_CONSTR_CHOICE, /* CHOICE */
ASN_CONSTR_SET, /* SET */
@ -55,7 +65,7 @@ typedef enum asn1p_expr_type {
/*
* ASN.1 Basic types
*/
#define ASN_BASIC_MASK 0x20 /* Every basic type */
#define ASN_BASIC_MASK 0x40 /* Every basic type */
ASN_TYPE_ANY = ASN_BASIC_MASK, /* ANY (deprecated) */
ASN_BASIC_BOOLEAN,
ASN_BASIC_NULL,
@ -75,9 +85,9 @@ typedef enum asn1p_expr_type {
/*
* ASN.1 String types
*/
#define ASN_STRING_KM_MASK 0x40 /* Known multiplier */
#define ASN_STRING_NKM_MASK 0x80 /* Not a known multiplier */
#define ASN_STRING_MASK 0xC0 /* Every restricted string type */
#define ASN_STRING_KM_MASK 0x100 /* Known multiplier */
#define ASN_STRING_NKM_MASK 0x200 /* Not a known multiplier */
#define ASN_STRING_MASK 0x300 /* Every restricted string type */
ASN_STRING_IA5String = ASN_STRING_KM_MASK,
ASN_STRING_PrintableString,
ASN_STRING_VisibleString,

File diff suppressed because it is too large Load Diff

View File

@ -242,9 +242,11 @@ static void _fixup_anonymous_identifier(asn1p_expr_t *expr);
%type <a_refcomp> ComplexTypeReferenceElement
%type <a_refcomp> ClassFieldIdentifier
%type <a_refcomp> ClassFieldName
%type <a_expr> ClassFieldList
%type <a_expr> FieldSpec
%type <a_ref> FieldName
%type <a_ref> DefinedObjectClass
%type <a_expr> ClassField
%type <a_expr> ClassDeclaration
%type <a_expr> ObjectClass
%type <a_expr> Type
%type <a_expr> DataTypeReference /* Type1 ::= Type2 */
%type <a_expr> DefinedTypeRef
@ -747,25 +749,17 @@ DataTypeReference:
/*
* Optionally tagged type definition.
*/
TypeRefName TOK_PPEQ optTag TOK_TYPE_IDENTIFIER {
$$ = asn1p_expr_new(yylineno);
checkmem($$);
$$->Identifier = $1;
$$->tag = $3;
$$->expr_type = A1TC_TYPEID;
$$->meta_type = AMT_TYPE;
}
| TypeRefName TOK_PPEQ Type {
TypeRefName TOK_PPEQ Type {
$$ = $3;
$$->Identifier = $1;
assert($$->expr_type);
assert($$->meta_type);
}
| TypeRefName TOK_PPEQ ClassDeclaration {
| TypeRefName TOK_PPEQ ObjectClass {
$$ = $3;
$$->Identifier = $1;
assert($$->expr_type == A1TC_CLASSDEF);
assert($$->meta_type == AMT_OBJECT);
assert($$->meta_type == AMT_OBJECTCLASS);
}
/*
* Parametrized <Type> declaration:
@ -943,13 +937,13 @@ AlternativeType:
}
;
ClassDeclaration:
TOK_CLASS '{' ClassFieldList '}' optWithSyntax {
ObjectClass:
TOK_CLASS '{' FieldSpec '}' optWithSyntax {
$$ = $3;
checkmem($$);
$$->with_syntax = $5;
assert($$->expr_type == A1TC_CLASSDEF);
assert($$->meta_type == AMT_OBJECT);
assert($$->meta_type == AMT_OBJECTCLASS);
}
;
@ -958,50 +952,111 @@ optUnique:
| TOK_UNIQUE { $$ = 1; }
;
ClassFieldList:
FieldSpec:
ClassField {
$$ = asn1p_expr_new(yylineno);
checkmem($$);
$$->expr_type = A1TC_CLASSDEF;
$$->meta_type = AMT_OBJECT;
$$->meta_type = AMT_OBJECTCLASS;
asn1p_expr_add($$, $1);
}
| ClassFieldList ',' ClassField {
| FieldSpec ',' ClassField {
$$ = $1;
asn1p_expr_add($$, $3);
}
;
/* X.681 */
ClassField:
ClassFieldIdentifier optMarker {
/* TypeFieldSpec ::= typefieldreference TypeOptionalitySpec? */
TOK_typefieldreference optMarker {
$$ = asn1p_expr_new(yylineno);
checkmem($$);
$$->Identifier = $1.name;
$$->expr_type = A1TC_CLASSFIELD;
$$->Identifier = $1;
$$->meta_type = AMT_OBJECTFIELD;
$$->expr_type = A1TC_CLASSFIELD_TFS; /* TypeFieldSpec */
$$->marker = $2;
}
| ClassFieldIdentifier Type optUnique optMarker {
$$ = $2;
$$->Identifier = $1.name;
$$->marker = $4;
/* FixedTypeValueFieldSpec ::= valuefieldreference Type UNIQUE ? ValueOptionalitySpec ? */
| TOK_valuefieldreference Type optUnique optMarker {
$$ = asn1p_expr_new(yylineno);
$$->Identifier = $1;
$$->meta_type = AMT_OBJECTFIELD;
$$->expr_type = A1TC_CLASSFIELD_FTVFS; /* FixedTypeValueFieldSpec */
$$->unique = $3;
$$->marker = $4;
asn1p_expr_add($$, $2);
}
| ClassFieldIdentifier ClassFieldIdentifier optUnique optMarker {
int ret;
/* VariableTypeValueFieldSpec ::= valuefieldreference FieldName ValueOptionalitySpec ? */
| TOK_valuefieldreference FieldName optMarker {
$$ = asn1p_expr_new(yylineno);
$$->Identifier = $1;
$$->meta_type = AMT_OBJECTFIELD;
$$->expr_type = A1TC_CLASSFIELD_VTVFS;
$$->reference = $2;
$$->marker = $3;
}
/* VariableTypeValueSetFieldSpec ::= valuesetfieldreference FieldName ValueOptionalitySpec ? */
| TOK_typefieldreference FieldName optMarker {
$$ = asn1p_expr_new(yylineno);
$$->Identifier = $1;
$$->meta_type = AMT_OBJECTFIELD;
$$->expr_type = A1TC_CLASSFIELD_VTVSFS;
$$->reference = $2;
$$->marker = $3;
}
/* ObjectFieldSpec ::= objectfieldreference DefinedObjectClass ObjectOptionalitySpec ? */
| TOK_valuefieldreference DefinedObjectClass optMarker {
$$ = asn1p_expr_new(yylineno);
checkmem($$);
$$->Identifier = $1.name;
$$->reference = asn1p_ref_new(yylineno);
checkmem($$->reference);
ret = asn1p_ref_add_component($$->reference,
$2.name, $2.lex_type);
checkmem(ret == 0);
$$->expr_type = A1TC_CLASSFIELD;
$$->Identifier = $1;
$$->reference = $2;
$$->meta_type = AMT_OBJECTFIELD;
$$->marker = $4;
$$->unique = $3;
$$->expr_type = A1TC_CLASSFIELD_OFS;
$$->marker = $3;
}
/* ObjectSetFieldSpec ::= objectsetfieldreference DefinedObjectClass ObjectOptionalitySpec ? */
| TOK_typefieldreference DefinedObjectClass optMarker {
$$ = asn1p_expr_new(yylineno);
checkmem($$);
$$->Identifier = $1;
$$->reference = $2;
$$->meta_type = AMT_OBJECTFIELD;
$$->expr_type = A1TC_CLASSFIELD_OSFS;
$$->marker = $3;
}
/* FixedTypeValueSetFieldSpec ::= valuesetfieldreference Type ValueSetOptionalitySpec ? */
| TOK_typefieldreference Type optMarker {
$$ = asn1p_expr_new(yylineno);
checkmem($$);
$$->Identifier = $1;
$$->meta_type = AMT_OBJECTFIELD;
$$->expr_type = A1TC_CLASSFIELD_FTVSFS;
asn1p_expr_add($$, $2);
$$->marker = $3;
}
/*
DefinedObjectClass:
TOK_capitalreference {
$$ = asn1p_ref_new(yylineno);
asn1p_ref_add_component($$, $1, RLT_CAPITALS);
}
| TypeRefName '.' TOK_capitalreference {
$$ = asn1p_ref_new(yylineno);
asn1p_ref_add_component($$, $1, RLT_AmpUppercase);
asn1p_ref_add_component($$, $3, RLT_CAPITALS);
}
;
*/
;
optWithSyntax:
@ -1333,6 +1388,35 @@ ClassFieldName:
;
FieldName:
/* "&Type1" */
TOK_typefieldreference {
$$ = asn1p_ref_new(yylineno);
asn1p_ref_add_component($$, $1, RLT_AmpUppercase);
}
| FieldName '.' TOK_typefieldreference {
$$ = $$;
asn1p_ref_add_component($$, $3, RLT_AmpUppercase);
}
| FieldName '.' TOK_valuefieldreference {
$$ = $$;
asn1p_ref_add_component($$, $3, RLT_Amplowercase);
}
;
DefinedObjectClass:
TOK_capitalreference {
$$ = asn1p_ref_new(yylineno);
asn1p_ref_add_component($$, $1, RLT_CAPITALS);
}
| TypeRefName '.' TOK_capitalreference {
$$ = asn1p_ref_new(yylineno);
asn1p_ref_add_component($$, $1, RLT_AmpUppercase);
asn1p_ref_add_component($$, $3, RLT_CAPITALS);
}
;
/*
* === EXAMPLE ===
* value INTEGER ::= 1

View File

@ -562,7 +562,7 @@ asn1print_expr(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *tc, enum asn1pri
case A1TC_CLASSDEF:
printf(" CLASS");
break;
case A1TC_CLASSFIELD:
case A1TC_CLASSFIELD_TFS ... A1TC_CLASSFIELD_OSFS:
/* Nothing to print here */
break;
case ASN_CONSTR_SET_OF:
@ -604,10 +604,12 @@ asn1print_expr(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *tc, enum asn1pri
|| (tc->expr_type & ASN_CONSTR_MASK)
|| tc->meta_type == AMT_VALUESET
|| tc->meta_type == AMT_OBJECT
|| tc->meta_type == AMT_OBJECTSET
|| tc->meta_type == AMT_OBJECTCLASS
|| tc->meta_type == AMT_OBJECTFIELD
) {
asn1p_expr_t *se; /* SubExpression */
int put_braces = !SEQ_OF; /* Don't need 'em, if SET OF... */
int put_braces = (!SEQ_OF) /* Don't need 'em, if SET OF... */
&& (tc->meta_type != AMT_OBJECTFIELD);
if(put_braces) {
if(flags & APF_NOINDENT) {

View File

@ -18,7 +18,7 @@ Ext1 ::= SEQUENCE {
EXTENSION-ATTRIBUTE ::= CLASS {
&id INTEGER (0..256) UNIQUE,
&Type
&Type ANY
} WITH SYNTAX {&Type IDENTIFIED BY &id}
@ -26,7 +26,7 @@ terminal-type EXTENSION-ATTRIBUTE ::= {TerminalType IDENTIFIED BY 23}
ExtensionAttribute ::= SEQUENCE {
extension-attribute-type [0] IMPLICIT EXTENSION-ATTRIBUTE.&id ({ExtensionAttributeTable}),
extension-attribute-value [1] IMPLICIT EXTENSION-ATTRIBUTE.&Type ({ExtensionAttributeTable}{@extension-attribute-type})
extension-attribute-value [1] EXPLICIT EXTENSION-ATTRIBUTE.&Type ({ExtensionAttributeTable}{@extension-attribute-type})
}
ub-extension-attributes INTEGER ::= 256