Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 1 | #include "asn1fix_internal.h" |
| 2 | |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 3 | asn1p_expr_t * |
Lev Walkin | c0e03b9 | 2017-08-22 01:48:23 -0700 | [diff] [blame] | 4 | asn1f_class_access(arg_t *arg, asn1p_expr_t *rhs_pspecs, const asn1p_ref_t *ref) { |
Lev Walkin | 9c2285a | 2006-03-09 08:49:26 +0000 | [diff] [blame] | 5 | asn1p_expr_t *ioclass; |
| 6 | asn1p_expr_t *classfield; |
| 7 | asn1p_expr_t *expr; |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 8 | asn1p_ref_t tmpref; |
| 9 | |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 10 | assert(ref->comp_count > 1); |
| 11 | |
Lev Walkin | c0e03b9 | 2017-08-22 01:48:23 -0700 | [diff] [blame] | 12 | DEBUG("ClassAccess lookup (%s%s) for line %d", |
| 13 | asn1f_printable_reference(ref), rhs_pspecs ? ", parameterized" : "", |
| 14 | ref->_lineno); |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 15 | |
Lev Walkin | c0e03b9 | 2017-08-22 01:48:23 -0700 | [diff] [blame] | 16 | /* |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 17 | * 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 Walkin | c0e03b9 | 2017-08-22 01:48:23 -0700 | [diff] [blame] | 25 | ioclass = asn1f_lookup_symbol(arg, rhs_pspecs, &tmpref); |
Lev Walkin | 9c2285a | 2006-03-09 08:49:26 +0000 | [diff] [blame] | 26 | if(ioclass == NULL) { |
Lev Walkin | c0e03b9 | 2017-08-22 01:48:23 -0700 | [diff] [blame] | 27 | DEBUG("ClassAccess lookup (%s) failed", |
| 28 | asn1f_printable_reference(&tmpref)); |
| 29 | errno = ESRCH; |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 30 | return NULL; |
| 31 | } |
Lev Walkin | 8838538 | 2006-03-17 02:37:08 +0000 | [diff] [blame] | 32 | if(ioclass->expr_type == A1TC_REFERENCE) { |
Lev Walkin | c0e03b9 | 2017-08-22 01:48:23 -0700 | [diff] [blame] | 33 | ioclass = WITH_MODULE( |
| 34 | ioclass->module, |
| 35 | asn1f_lookup_symbol(arg, ioclass->rhs_pspecs, ioclass->reference)); |
| 36 | if(ioclass == NULL) { |
Lev Walkin | 8838538 | 2006-03-17 02:37:08 +0000 | [diff] [blame] | 37 | 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 Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 52 | |
Lev Walkin | 9c2285a | 2006-03-09 08:49:26 +0000 | [diff] [blame] | 53 | 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 Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 58 | return NULL; |
| 59 | } |
| 60 | |
Lev Walkin | 9c2285a | 2006-03-09 08:49:26 +0000 | [diff] [blame] | 61 | assert(classfield->meta_type == AMT_OBJECTFIELD); |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 62 | |
Lev Walkin | 9c2285a | 2006-03-09 08:49:26 +0000 | [diff] [blame] | 63 | DEBUG("CLASS %s -> %s (%d)", ioclass->Identifier, |
| 64 | classfield->Identifier, classfield->expr_type); |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 65 | |
Lev Walkin | 9c2285a | 2006-03-09 08:49:26 +0000 | [diff] [blame] | 66 | switch(classfield->expr_type) { |
| 67 | case A1TC_CLASSFIELD_TFS: |
| 68 | if(TQ_FIRST(&classfield->members)) { |
| 69 | /* Already have something */ |
| 70 | } else { |
Lev Walkin | c0e03b9 | 2017-08-22 01:48:23 -0700 | [diff] [blame] | 71 | expr = asn1p_expr_new(classfield->_lineno, arg->mod); |
Lev Walkin | 9c2285a | 2006-03-09 08:49:26 +0000 | [diff] [blame] | 72 | expr->expr_type = ASN_TYPE_ANY; |
| 73 | expr->meta_type = AMT_TYPE; |
| 74 | asn1p_expr_add(classfield, expr); |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 75 | } |
Lev Walkin | 9c2285a | 2006-03-09 08:49:26 +0000 | [diff] [blame] | 76 | /* Fall through */ |
| 77 | case A1TC_CLASSFIELD_FTVFS: |
| 78 | expr = TQ_FIRST(&classfield->members); |
| 79 | assert(expr); |
| 80 | return expr; |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 81 | break; |
| 82 | default: |
Lev Walkin | 9c2285a | 2006-03-09 08:49:26 +0000 | [diff] [blame] | 83 | FATAL("%s.%s: field type not yet supported. " |
| 84 | "Consider donation to the asn1c author.", |
| 85 | ioclass->Identifier, classfield->Identifier); |
| 86 | return NULL; |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 87 | } |
| 88 | |
Lev Walkin | 9c2285a | 2006-03-09 08:49:26 +0000 | [diff] [blame] | 89 | return NULL; |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 90 | } |
Lev Walkin | aa7f530 | 2006-03-14 15:53:59 +0000 | [diff] [blame] | 91 | |