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