blob: 91847a6fb1c23dd07704f5daef5ee1ce8c092c29 [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 Walkinc0e03b92017-08-22 01:48:23 -07004asn1f_class_access(arg_t *arg, asn1p_expr_t *rhs_pspecs, const 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 Walkinc0e03b92017-08-22 01:48:23 -070012 DEBUG("ClassAccess lookup (%s%s) for line %d",
13 asn1f_printable_reference(ref), rhs_pspecs ? ", parameterized" : "",
14 ref->_lineno);
Lev Walkinf15320b2004-06-03 03:38:44 +000015
Lev Walkinc0e03b92017-08-22 01:48:23 -070016 /*
Lev Walkinf15320b2004-06-03 03:38:44 +000017 * Fetch the first part of the reference (OBJECT or ObjectSet).
18 * OBJECT.&<something>...
19 * ObjectSet.&<something>...
20 */
21 assert(isupper(ref->components[0].name[0]));
22
23 tmpref = *ref;
24 tmpref.comp_count = 1;
Lev Walkinc0e03b92017-08-22 01:48:23 -070025 ioclass = asn1f_lookup_symbol(arg, rhs_pspecs, &tmpref);
Lev Walkin9c2285a2006-03-09 08:49:26 +000026 if(ioclass == NULL) {
Lev Walkinc0e03b92017-08-22 01:48:23 -070027 DEBUG("ClassAccess lookup (%s) failed",
28 asn1f_printable_reference(&tmpref));
29 errno = ESRCH;
Lev Walkinf15320b2004-06-03 03:38:44 +000030 return NULL;
31 }
Lev Walkin88385382006-03-17 02:37:08 +000032 if(ioclass->expr_type == A1TC_REFERENCE) {
Lev Walkinc0e03b92017-08-22 01:48:23 -070033 ioclass = WITH_MODULE(
34 ioclass->module,
35 asn1f_lookup_symbol(arg, ioclass->rhs_pspecs, ioclass->reference));
36 if(ioclass == NULL) {
Lev Walkin88385382006-03-17 02:37:08 +000037 errno = ESRCH;
38 return NULL;
39 }
40 }
41 if(ioclass->expr_type != A1TC_CLASSDEF) {
42 if(!(ioclass->_mark & TM_BROKEN)) {
43 ioclass->_mark |= TM_BROKEN;
44 FATAL("Class field %s lookup at line %d in something that is not a class: %s at line %d",
45 asn1f_printable_reference(ref), ref->_lineno,
46 ioclass->Identifier,
47 ioclass->_lineno);
48 }
49 errno = EINVAL;
50 return NULL;
51 }
Lev Walkinf15320b2004-06-03 03:38:44 +000052
Lev Walkin9c2285a2006-03-09 08:49:26 +000053 classfield = asn1f_lookup_child(ioclass, ref->components[1].name);
54 if(classfield == NULL) {
55 DEBUG("CLASS %s does not contain field %s",
56 ioclass->Identifier, ref->components[1].name);
57 errno = ESRCH;
Lev Walkinf15320b2004-06-03 03:38:44 +000058 return NULL;
59 }
60
Lev Walkin9c2285a2006-03-09 08:49:26 +000061 assert(classfield->meta_type == AMT_OBJECTFIELD);
Lev Walkinf15320b2004-06-03 03:38:44 +000062
Lev Walkin9c2285a2006-03-09 08:49:26 +000063 DEBUG("CLASS %s -> %s (%d)", ioclass->Identifier,
64 classfield->Identifier, classfield->expr_type);
Lev Walkinf15320b2004-06-03 03:38:44 +000065
Lev Walkin9c2285a2006-03-09 08:49:26 +000066 switch(classfield->expr_type) {
67 case A1TC_CLASSFIELD_TFS:
68 if(TQ_FIRST(&classfield->members)) {
69 /* Already have something */
70 } else {
Lev Walkinc0e03b92017-08-22 01:48:23 -070071 expr = asn1p_expr_new(classfield->_lineno, arg->mod);
Lev Walkin9c2285a2006-03-09 08:49:26 +000072 expr->expr_type = ASN_TYPE_ANY;
73 expr->meta_type = AMT_TYPE;
74 asn1p_expr_add(classfield, expr);
Lev Walkinf15320b2004-06-03 03:38:44 +000075 }
Lev Walkin9c2285a2006-03-09 08:49:26 +000076 /* Fall through */
77 case A1TC_CLASSFIELD_FTVFS:
78 expr = TQ_FIRST(&classfield->members);
79 assert(expr);
80 return expr;
Lev Walkinf15320b2004-06-03 03:38:44 +000081 break;
82 default:
Lev Walkin9c2285a2006-03-09 08:49:26 +000083 FATAL("%s.%s: field type not yet supported. "
84 "Consider donation to the asn1c author.",
85 ioclass->Identifier, classfield->Identifier);
86 return NULL;
Lev Walkinf15320b2004-06-03 03:38:44 +000087 }
88
Lev Walkin9c2285a2006-03-09 08:49:26 +000089 return NULL;
Lev Walkinf15320b2004-06-03 03:38:44 +000090}
Lev Walkinaa7f5302006-03-14 15:53:59 +000091