Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 1 | #include "asn1fix_internal.h" |
| 2 | |
| 3 | static int _compare_value(asn1p_expr_t *expr1, asn1p_expr_t *expr2) { |
| 4 | if(expr2->value->type == ATV_INTEGER |
| 5 | && expr1->value->type == ATV_INTEGER) { |
| 6 | return expr2->value->value.v_integer |
| 7 | - expr1->value->value.v_integer; |
| 8 | } else { |
| 9 | return -1; |
| 10 | } |
| 11 | } |
| 12 | |
| 13 | /* |
| 14 | * Check the validity of an INTEGER type. |
| 15 | */ |
| 16 | int |
| 17 | asn1f_fix_integer(arg_t *arg) { |
| 18 | asn1p_expr_t *expr = arg->expr; |
| 19 | asn1p_expr_t *iv; |
| 20 | int rvalue = 0; |
| 21 | int ret; |
| 22 | |
| 23 | if(expr->expr_type != ASN_BASIC_INTEGER) |
| 24 | return 0; /* Just ignore it */ |
| 25 | |
Lev Walkin | 0385018 | 2005-03-10 10:02:50 +0000 | [diff] [blame] | 26 | DEBUG("(\"%s\", %x) for line %d", |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 27 | expr->Identifier, expr->expr_type, expr->_lineno); |
| 28 | |
| 29 | /* |
| 30 | * Scan the integer values in search for inconsistencies. |
| 31 | */ |
| 32 | TQ_FOR(iv, &(expr->members), next) { |
| 33 | |
| 34 | DEBUG("\tItem %s(%s)", iv->Identifier, |
| 35 | asn1f_printable_value(iv->value)); |
| 36 | |
| 37 | /* |
| 38 | * Found "...", check correctness. |
| 39 | */ |
| 40 | if(iv->expr_type == A1TC_EXTENSIBLE) { |
Lev Walkin | a0c9290 | 2006-08-28 02:24:24 +0000 | [diff] [blame] | 41 | FATAL("INTEGER %s at line %d: " |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 42 | "Extension marker is not allowed", |
| 43 | expr->Identifier, |
Lev Walkin | a0c9290 | 2006-08-28 02:24:24 +0000 | [diff] [blame] | 44 | iv->_lineno); |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 45 | rvalue = -1; |
| 46 | continue; |
| 47 | } |
| 48 | |
| 49 | if(iv->Identifier == NULL |
| 50 | || iv->expr_type != A1TC_UNIVERVAL) { |
Lev Walkin | a0c9290 | 2006-08-28 02:24:24 +0000 | [diff] [blame] | 51 | FATAL("INTEGER %s at line %d: " |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 52 | "Unsupported enumeration element %s", |
| 53 | expr->Identifier, |
| 54 | iv->_lineno, |
| 55 | iv->Identifier?iv->Identifier:"<Anonymous>" |
| 56 | ); |
| 57 | rvalue = -1; |
| 58 | continue; |
| 59 | } |
| 60 | |
| 61 | if(iv->value == NULL) { |
Lev Walkin | a0c9290 | 2006-08-28 02:24:24 +0000 | [diff] [blame] | 62 | FATAL("INTEGER %s at line %d: " |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 63 | "Value for the identifier %s " |
| 64 | "must be set explicitly", |
| 65 | expr->Identifier, |
| 66 | iv->_lineno, |
| 67 | iv->Identifier |
| 68 | ); |
| 69 | rvalue = -1; |
| 70 | continue; |
| 71 | } else if(iv->value->type == ATV_REFERENCED) { |
| 72 | /* |
| 73 | * Resolve the value, once and for all. |
| 74 | */ |
Lev Walkin | 9288d1c | 2005-03-10 11:27:13 +0000 | [diff] [blame] | 75 | if(asn1f_value_resolve(arg, iv, 0)) { |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 76 | /* This function will emit messages */ |
| 77 | rvalue = -1; |
| 78 | continue; |
| 79 | } |
| 80 | } |
| 81 | |
| 82 | if(iv->value->type != ATV_INTEGER) { |
Lev Walkin | a0c9290 | 2006-08-28 02:24:24 +0000 | [diff] [blame] | 83 | FATAL("INTEGER %s at line %d: " |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 84 | "Value for the identifier %s " |
| 85 | "is not compatible with INTEGER type", |
| 86 | expr->Identifier, |
| 87 | iv->_lineno); |
| 88 | rvalue = -1; |
| 89 | continue; |
| 90 | } |
| 91 | |
| 92 | /* |
| 93 | * Check that all identifiers are distinct. |
| 94 | */ |
Lev Walkin | fbfc7bc | 2006-08-28 02:45:44 +0000 | [diff] [blame] | 95 | ret = asn1f_check_unique_expr_child(arg, iv, 0, "identifier"); |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 96 | RET2RVAL(ret, rvalue); |
| 97 | /* |
| 98 | * Check that all values are distinct. |
| 99 | */ |
Lev Walkin | fbfc7bc | 2006-08-28 02:45:44 +0000 | [diff] [blame] | 100 | ret = asn1f_check_unique_expr_child(arg, iv, |
| 101 | _compare_value, "value"); |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 102 | RET2RVAL(ret, rvalue); |
| 103 | } |
| 104 | |
| 105 | |
| 106 | return rvalue; |
| 107 | } |
| 108 | |
Lev Walkin | 1715b32 | 2013-03-28 04:02:13 -0700 | [diff] [blame] | 109 | #if 0 |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 110 | static int |
| 111 | _asn1f_make_sure_type_is(arg_t *arg, asn1p_expr_t *expr, asn1p_expr_type_e type) { |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 112 | asn1p_expr_t *next_expr; |
Lev Walkin | d9bd775 | 2004-06-05 08:17:50 +0000 | [diff] [blame] | 113 | asn1p_expr_type_e expr_type; |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 114 | int ret; |
| 115 | |
| 116 | expr_type = expr->expr_type; |
| 117 | |
| 118 | /* |
| 119 | * Here we're trying to make sure that the type of the given |
| 120 | * expression is really what is expected. |
| 121 | * This is ensured in two ways. |
| 122 | * First, if the immediate type matches the provided one, |
| 123 | * this is a clear hit. |
| 124 | */ |
| 125 | if(expr_type == type) |
| 126 | return 0; |
| 127 | |
| 128 | /* |
| 129 | * Otherwise, it must be either a reference or a different type. |
| 130 | */ |
| 131 | if(expr_type != A1TC_REFERENCE) { |
| 132 | errno = EPERM; |
| 133 | return -1; |
| 134 | } |
| 135 | |
| 136 | assert(expr_type == A1TC_REFERENCE); |
| 137 | assert(expr->reference); |
| 138 | |
| 139 | /* |
| 140 | * Then, it is a reference. For a reference, try to resolve type |
| 141 | * and try again. |
| 142 | */ |
Lev Walkin | a00d6b3 | 2006-03-21 03:40:38 +0000 | [diff] [blame] | 143 | next_expr = asn1f_lookup_symbol(arg, expr->module, |
| 144 | expr->rhs_pspecs, expr->reference); |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 145 | if(next_expr == NULL) { |
| 146 | errno = ESRCH; |
| 147 | return -1; |
| 148 | } |
| 149 | |
| 150 | /* |
| 151 | * If symbol is here, recursively check that it conforms to the type. |
| 152 | */ |
Lev Walkin | 6fec44d | 2004-08-22 03:10:23 +0000 | [diff] [blame] | 153 | WITH_MODULE(next_expr->module, |
| 154 | ret = _asn1f_make_sure_type_is(arg, next_expr, type)); |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 155 | |
| 156 | return ret; |
| 157 | } |
Lev Walkin | 1715b32 | 2013-03-28 04:02:13 -0700 | [diff] [blame] | 158 | #endif |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 159 | |
| 160 | |