parsing object classes more properly
git-svn-id: https://asn1c.svn.sourceforge.net/svnroot/asn1c/trunk@1062 59561ff5-6e30-0410-9f3c-9617f08c8826
diff --git a/libasn1fix/asn1fix.c b/libasn1fix/asn1fix.c
index 5ee73a8..44dbf0e 100644
--- a/libasn1fix/asn1fix.c
+++ b/libasn1fix/asn1fix.c
@@ -433,6 +433,7 @@
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 @@
diff_files ? ")" : "");
if(critical)
return -1;
+ RET2RVAL(1, rvalue);
}
if(tmparg.mod == arg->mod) break;
}
- return 0;
+ return rvalue;
}
static int
diff --git a/libasn1fix/asn1fix_class.c b/libasn1fix/asn1fix_class.c
index 3542e0c..11acd8b 100644
--- a/libasn1fix/asn1fix_class.c
+++ b/libasn1fix/asn1fix_class.c
@@ -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 @@
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;
}
diff --git a/libasn1fix/asn1fix_tags.c b/libasn1fix/asn1fix_tags.c
index dfda441..3215fff 100644
--- a/libasn1fix/asn1fix_tags.c
+++ b/libasn1fix/asn1fix_tags.c
@@ -25,6 +25,9 @@
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);
diff --git a/libasn1fix/check_fixer.c b/libasn1fix/check_fixer.c
index a64d9bd..c4e3f99 100644
--- a/libasn1fix/check_fixer.c
+++ b/libasn1fix/check_fixer.c
@@ -185,8 +185,10 @@
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);
}
}