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_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;
 }