-#include "asn1fix_internal.h"
-
-/*
- * Check the validity of an enumeration.
- */
-int
-asn1f_fix_enum(arg_t *arg) {
- asn1p_expr_t *expr = arg->expr;
- asn1p_expr_t *ev;
- asn1c_integer_t max_value = -1;
- asn1c_integer_t max_value_ext = -1;
- int rvalue = 0;
- asn1p_expr_t *ext_marker = NULL; /* "..." position */
- int ret;
-
- /* Keep track of value collisions */
- asn1c_integer_t *used_vals;
- int used_vals_sz = 50;
- int used_vals_next = 0;
-
- if(expr->expr_type != ASN_BASIC_ENUMERATED)
- return 0; /* Just ignore it */
-
- DEBUG("(%s)", expr->Identifier);
-
- used_vals = (asn1c_integer_t *) malloc(sizeof(asn1c_integer_t) * used_vals_sz);
- if (!used_vals) {
- FATAL("Out of memory");
- return -1;
- }
-
- /*
- * 1. Scan the enumeration values in search for inconsistencies.
- */
- TQ_FOR(ev, &(expr->members), next) {
- asn1c_integer_t eval;
-
- if(ev->value)
- DEBUG("\tItem %s(%s)", ev->Identifier,
- asn1f_printable_value(ev->value));
- else
- DEBUG("\tItem %s", ev->Identifier);
-
- /*
- * 1.1 Found an extension mark "...", check correctness.
- */
- if(ev->expr_type == A1TC_EXTENSIBLE) {
- if(ext_marker) {
- FATAL("Enumeration %s at line %d: "
- "Second extension marker is not allowed",
- expr->Identifier,
- ev->_lineno);
- rvalue = -1;
- } else {
- /*
- * Remember the marker's position.
- */
- ext_marker = ev;
- }
- continue;
- } else if(ev->Identifier == NULL
- || ev->expr_type != A1TC_UNIVERVAL) {
- FATAL(
- "Enumeration %s at line %d: "
- "Unsupported enumeration element %s",
- expr->Identifier,
- ev->_lineno,
- ev->Identifier?ev->Identifier:"<anonymous>");
- rvalue = -1;
- continue;
- }
-
- /*
- * 1.2 Compute the value of the enumeration element.
- */
- if(ev->value) {
- switch(ev->value->type) {
- case ATV_INTEGER:
- eval = ev->value->value.v_integer;
- break;
- case ATV_REFERENCED:
- FATAL("HERE HERE HERE", 1);
- rvalue = -1;
- continue;
- break;
- default:
- FATAL("ENUMERATED type %s at line %d "
- "contain element %s(%s) at line %d",
- expr->Identifier, expr->_lineno,
- ev->Identifier,
- asn1f_printable_value(ev->value),
- ev->_lineno);
- rvalue = -1;
- continue;
- }
- } else {
- eval = max_value + 1;
- ev->value = asn1p_value_fromint(eval);
- if(ev->value == NULL) {
- rvalue = -1;
- continue;
- }
- }
-
- /*
- * 1.3 Check the applicability of this value.
- */
-
- /*
- * Enumeration is allowed to be unordered
- * before the first marker, but after the marker
- * the values must be ordered.
- */
- if (ext_marker) {
- if (eval > max_value_ext) {
- max_value_ext = eval;
- } else {
- char max_value_buf[128];
- asn1p_itoa_s(max_value_buf, sizeof(max_value_buf),
- max_value_ext);
- FATAL(
- "Enumeration %s at line %d: "
- "Explicit value \"%s(%s)\" "
- "is not greater "
- "than previous values (max %s)",
- expr->Identifier,
- ev->_lineno,
- ev->Identifier,
- asn1p_itoa(eval),
- max_value_buf);
- rvalue = -1;
- }
- }
-
- if (eval > max_value) {
- max_value = eval;
- }
-
-
- /*
- * 1.4 Check that all identifiers are unique
- */
- int unique = 1;
- int uv_idx;
- for (uv_idx = 0; uv_idx < used_vals_next; uv_idx++) {
- if (used_vals[uv_idx] == eval) {
- FATAL(
- "Enumeration %s at line %d: "
- "Explicit value \"%s(%s)\" "
- "collides with previous values",
- expr->Identifier,
- ev->_lineno,
- ev->Identifier,
- asn1p_itoa(eval));
- rvalue = -1;
- unique = 0;
- }
- }
-
- if (unique) {
- /* Grow the array if needed */
- if (used_vals_next >= used_vals_sz) {
- asn1c_integer_t *temp;
- int new_sz = used_vals_sz + 50;
- temp = (asn1c_integer_t *) realloc(used_vals,
- sizeof(asn1c_integer_t) * new_sz);
- if (!temp) return -1;
- used_vals = temp;
- used_vals_sz = new_sz;
- }
- used_vals[used_vals_next++] = eval;
- }
-
- /*
- * 1.5 Check that all identifiers before the current one
- * differs from it.
- */
- ret = asn1f_check_unique_expr_child(arg, ev, 0, "identifier");
- RET2RVAL(ret, rvalue);
- }
-
- free(used_vals);
-
- /*
- * 2. Reorder the first half (before optional "...") of the
- * identifiers alphabetically.
- */
- // TODO
-
- return rvalue;
-}
-