blob: 32ad896347ae9d8b02cd94e917da6d27896c6f72 [file] [log] [blame]
Lev Walkinf15320b2004-06-03 03:38:44 +00001#include "asn1fix_internal.h"
2
Lev Walkinf15320b2004-06-03 03:38:44 +00003asn1p_expr_t *
Lev Walkina00d6b32006-03-21 03:40:38 +00004asn1f_class_access(arg_t *arg, asn1p_module_t *mod, asn1p_expr_t *rhs_pspecs, asn1p_ref_t *ref) {
Lev Walkin9c2285a2006-03-09 08:49:26 +00005 asn1p_expr_t *ioclass;
6 asn1p_expr_t *classfield;
7 asn1p_expr_t *expr;
Lev Walkinf15320b2004-06-03 03:38:44 +00008 asn1p_ref_t tmpref;
9
Lev Walkinf15320b2004-06-03 03:38:44 +000010 assert(ref->comp_count > 1);
11
Lev Walkin9c2285a2006-03-09 08:49:26 +000012 DEBUG("ClassAccess lookup (%s) for line %d", asn1f_printable_reference(ref), ref->_lineno);
Lev Walkinf15320b2004-06-03 03:38:44 +000013
14 /*
15 * Fetch the first part of the reference (OBJECT or ObjectSet).
16 * OBJECT.&<something>...
17 * ObjectSet.&<something>...
18 */
19 assert(isupper(ref->components[0].name[0]));
20
21 tmpref = *ref;
22 tmpref.comp_count = 1;
Lev Walkina00d6b32006-03-21 03:40:38 +000023 ioclass = asn1f_lookup_symbol(arg, mod, rhs_pspecs, &tmpref);
Lev Walkin9c2285a2006-03-09 08:49:26 +000024 if(ioclass == NULL) {
Lev Walkinf15320b2004-06-03 03:38:44 +000025 errno = ESRCH;
26 return NULL;
27 }
Lev Walkin88385382006-03-17 02:37:08 +000028 if(ioclass->expr_type == A1TC_REFERENCE) {
29 ioclass = asn1f_lookup_symbol(arg,
Lev Walkina00d6b32006-03-21 03:40:38 +000030 ioclass->module,
31 ioclass->rhs_pspecs,
32 ioclass->reference);
Lev Walkin88385382006-03-17 02:37:08 +000033 if(ioclass == NULL) {
34 errno = ESRCH;
35 return NULL;
36 }
37 }
38 if(ioclass->expr_type != A1TC_CLASSDEF) {
39 if(!(ioclass->_mark & TM_BROKEN)) {
40 ioclass->_mark |= TM_BROKEN;
41 FATAL("Class field %s lookup at line %d in something that is not a class: %s at line %d",
42 asn1f_printable_reference(ref), ref->_lineno,
43 ioclass->Identifier,
44 ioclass->_lineno);
45 }
46 errno = EINVAL;
47 return NULL;
48 }
Lev Walkinf15320b2004-06-03 03:38:44 +000049
Lev Walkin9c2285a2006-03-09 08:49:26 +000050 classfield = asn1f_lookup_child(ioclass, ref->components[1].name);
51 if(classfield == NULL) {
52 DEBUG("CLASS %s does not contain field %s",
53 ioclass->Identifier, ref->components[1].name);
54 errno = ESRCH;
Lev Walkinf15320b2004-06-03 03:38:44 +000055 return NULL;
56 }
57
Lev Walkin9c2285a2006-03-09 08:49:26 +000058 assert(classfield->meta_type == AMT_OBJECTFIELD);
Lev Walkinf15320b2004-06-03 03:38:44 +000059
Lev Walkin9c2285a2006-03-09 08:49:26 +000060 DEBUG("CLASS %s -> %s (%d)", ioclass->Identifier,
61 classfield->Identifier, classfield->expr_type);
Lev Walkinf15320b2004-06-03 03:38:44 +000062
Lev Walkin9c2285a2006-03-09 08:49:26 +000063 switch(classfield->expr_type) {
64 case A1TC_CLASSFIELD_TFS:
65 if(TQ_FIRST(&classfield->members)) {
66 /* Already have something */
67 } else {
Lev Walkina9532f42006-09-17 04:52:50 +000068 expr = asn1p_expr_new(classfield->_lineno, mod);
Lev Walkin9c2285a2006-03-09 08:49:26 +000069 expr->expr_type = ASN_TYPE_ANY;
70 expr->meta_type = AMT_TYPE;
71 asn1p_expr_add(classfield, expr);
Lev Walkinf15320b2004-06-03 03:38:44 +000072 }
Lev Walkin9c2285a2006-03-09 08:49:26 +000073 /* Fall through */
74 case A1TC_CLASSFIELD_FTVFS:
75 expr = TQ_FIRST(&classfield->members);
76 assert(expr);
77 return expr;
Lev Walkinf15320b2004-06-03 03:38:44 +000078 break;
79 default:
Lev Walkin9c2285a2006-03-09 08:49:26 +000080 FATAL("%s.%s: field type not yet supported. "
81 "Consider donation to the asn1c author.",
82 ioclass->Identifier, classfield->Identifier);
83 return NULL;
Lev Walkinf15320b2004-06-03 03:38:44 +000084 }
85
Lev Walkin9c2285a2006-03-09 08:49:26 +000086 return NULL;
Lev Walkinf15320b2004-06-03 03:38:44 +000087}
Lev Walkinaa7f5302006-03-14 15:53:59 +000088