constraint checking code

diff --git a/libasn1compiler/asn1c_C.c b/libasn1compiler/asn1c_C.c
index 197ce1f..ac13873 100644
--- a/libasn1compiler/asn1c_C.c
+++ b/libasn1compiler/asn1c_C.c
@@ -4,7 +4,8 @@
  */
 #include "asn1c_internal.h"
 #include "asn1c_C.h"
-#include <asn1fix_export.h>	/* exportable stuff from libasn1fix */
+#include "asn1c_constraint.h"
+#include <asn1fix_export.h>	/* Stuff exported by libasn1fix */
 
 typedef struct tag2el_s {
 	struct asn1p_type_tag_s el_tag;
@@ -25,17 +26,6 @@
 static int check_if_extensible(asn1p_expr_t *expr);
 static int emit_tags_vector(arg_t *arg, asn1p_expr_t *expr, int *tags_impl_skip, int choice_mode);
 static int emit_tag2member_map(arg_t *arg, tag2el_t *tag2el, int tag2el_count);
-static int emit_constraint_checking_code(arg_t *arg);
-static int emit_single_constraint_check(arg_t *arg, asn1p_constraint_t *ct, int mode);
-static int emit_alphabet_tables(arg_t *arg, asn1p_constraint_t *ct, int *table);
-static int emit_alphabet_check_cycle(arg_t *arg);
-static int check_constraint_type_presence(asn1p_constraint_t *ct, enum asn1p_constraint_type_e type);
-static asn1p_expr_type_e _find_terminal_type(arg_t *arg);
-static int emit_value_determination_code(arg_t *arg);
-static int emit_size_determination_code(arg_t *arg);
-static long compute_min_size(arg_t *arg);
-static long compute_max_size(arg_t *arg);
-static long compute_xxx_size(arg_t *arg, int _max);
 
 #define	C99_MODE	(arg->flags & A1C_NO_C99)
 #define	UNNAMED_UNIONS	(arg->flags & A1C_UNNAMED_UNIONS)
@@ -969,28 +959,28 @@
 	/*
 	 * Constraint checking.
 	 */
-	if(expr->constraints)	/* Emit tables with FROM() constraints */
-		emit_alphabet_tables(arg, expr->constraints, 0);
+	/* Emit FROM() tables and others */
+	asn1c_emit_constraint_tables(arg, 0);
+
 	p = MKID(expr->Identifier);
 	OUT("int\n");
 	OUT("%s_constraint(asn1_TYPE_descriptor_t *td, const void *sptr,\n", p);
 	INDENTED(
 	OUT("\t\tasn_app_consume_bytes_f *app_errlog, void *app_key) {\n");
 	OUT("\n");
-	if(expr->constraints) {
-
-		emit_constraint_checking_code(arg);
-
+	if(asn1c_emit_constraint_checking_code(arg) == 1) {
+		if(0) {
 		OUT("/* Check the constraints of the underlying type */\n");
 		OUT("return asn1_DEF_%s.check_constraints\n",
 			asn1c_type_name(arg, expr, TNF_SAFE));
 		OUT("\t(td, sptr, app_errlog, app_key);\n");
-	} else {
+		} else {
 		OUT("/* Make the underlying type checker permanent */\n");
 		OUT("td->check_constraints = asn1_DEF_%s.check_constraints;\n",
 			asn1c_type_name(arg, expr, TNF_SAFE));
 		OUT("return td->check_constraints\n");
 		OUT("\t(td, sptr, app_errlog, app_key);\n");
+		}
 	}
 	);
 	OUT("}\n");
@@ -1365,687 +1355,3 @@
 
 	return tags_count;
 }
-
-static int
-emit_constraint_checking_code(arg_t *arg) {
-	asn1p_expr_t *expr = arg->expr;
-	asn1p_expr_type_e etype;
-	int size_present, value_present;
-
-	if(expr->constraints == NULL)
-		return 0;	/* No constraints defined */
-
-	etype = _find_terminal_type(arg);
-
-	size_present = check_constraint_type_presence(expr->constraints,
-		ACT_CT_SIZE);
-	value_present = check_constraint_type_presence(expr->constraints,
-		ACT_EL_VALUE);
-
-	if(size_present || value_present) {
-		OUT("const %s_t *st = sptr;\n", MKID(arg->expr->Identifier));
-		if(size_present) {
-			OUT("size_t size;\n");
-			OUT("size_t min_size __attribute__ ((unused)) = %ld;\n",
-				compute_min_size(arg));
-			OUT("size_t max_size __attribute__ ((unused)) = %ld;\n",
-				compute_max_size(arg));
-		}
-		if(value_present)
-		switch(etype) {
-		case ASN_BASIC_INTEGER:
-		case ASN_BASIC_ENUMERATED:
-			OUT("long value;\n");
-			break;
-		case ASN_BASIC_BOOLEAN:
-			OUT("int value;\n");
-			break;
-		default:
-			break;
-		}
-		OUT("\n");
-	}
-
-	OUT("if(!sptr) {\n");
-	INDENT(+1);
-		OUT("_ASN_ERRLOG(app_errlog, app_key,\n");
-		OUT("\t\"%%s: value not given\", td->name);\n");
-		OUT("return -1;\n");
-	INDENT(-1);
-	OUT("}\n");
-	OUT("\n");
-
-	if(size_present)
-		emit_size_determination_code(arg);
-	if(value_present)
-		emit_value_determination_code(arg);
-
-	OUT("\n");
-	OUT("if(\n");
-	emit_single_constraint_check(arg, expr->constraints, 0);
-	OUT(") {\n");
-	INDENTED(OUT("/* Constraint check succeeded */\n"));
-	OUT("} else {\n");
-	INDENT(+1);
-		OUT("_ASN_ERRLOG(app_errlog, app_key,\n");
-		OUT("\t\"%%s: constraint failed\", td->name);\n");
-		OUT("return -1;\n");
-	INDENT(-1);
-	OUT("}\n");
-
-	return 0;
-}
-
-static int
-emit_single_constraint_check(arg_t *arg, asn1p_constraint_t *ct, int mode) {
-	char *s_v;
-	int el;
-
-	assert(arg && ct);
-
-	switch(ct->type) {
-	case ACT_INVALID:
-		assert(ct->type != ACT_INVALID);
-		OUT("-1 /* Invalid constraint at line %d */\n", ct->_lineno);
-		break;
-	case ACT_EL_VALUE:
-		OUT("(");
-		if(mode == ACT_CT_SIZE)	s_v = "size";
-		else			s_v = "value";
-		OUT("%s", s_v);
-		if(ct->value->type != ATV_TRUE)
-			OUT(" == ");
-		switch(ct->value->type) {
-		case ATV_INTEGER: OUT("%lld",
-			(long long)ct->value->value.v_integer); break;
-		case ATV_MIN:	OUT("min_%s", s_v);	break;
-		case ATV_MAX:	OUT("max_%s", s_v);	break;
-		case ATV_FALSE:	OUT("0");	break;
-		case ATV_TRUE:			break;
-		default:
-			break;
-		}
-		OUT(")\n");
-		break;
-	case ACT_EL_RANGE:
-	case ACT_EL_LLRANGE:
-	case ACT_EL_RLRANGE:
-	case ACT_EL_ULRANGE:
-		if(mode == ACT_CT_SIZE) {
-			s_v = "size";
-		} else {
-			s_v = "value";
-		}
-		OUT("((%s", s_v);
-		switch(ct->type) {
-		case ACT_EL_RANGE:
-		case ACT_EL_RLRANGE:
-			OUT(" >= ");	break;
-		case ACT_EL_LLRANGE:
-		case ACT_EL_ULRANGE:
-			OUT(" > ");	break;
-		default:	break;
-		}
-		switch(ct->range_start->type) {
-		case ATV_INTEGER: OUT("%lld",
-			(long long)ct->range_start->value.v_integer); break;
-		case ATV_MIN:	OUT("min_%s", s_v);	break;
-		case ATV_MAX:	OUT("max_%s", s_v);	break;
-		case ATV_FALSE:	OUT("0");	break;
-		case ATV_TRUE:			break;
-		default:
-			break;
-		}
-		OUT(") && (%s", s_v);
-		switch(ct->type) {
-		case ACT_EL_RANGE:
-		case ACT_EL_LLRANGE:
-			OUT(" <= ");	break;
-		case ACT_EL_RLRANGE:
-		case ACT_EL_ULRANGE:
-			OUT(" < ");	break;
-		default:	break;
-		}
-		switch(ct->range_stop->type) {
-		case ATV_INTEGER: OUT("%lld",
-			(long long)ct->range_stop->value.v_integer); break;
-		case ATV_MIN:	OUT("min_%s", s_v);	break;
-		case ATV_MAX:	OUT("max_%s", s_v);	break;
-		case ATV_FALSE:	OUT("0");	break;
-		case ATV_TRUE:			break;
-		default:
-			break;
-		}
-		OUT("))\n");
-		break;
-	case ACT_EL_EXT:
-		OUT("0 /* Extensible (...), but not defined herein */\n");
-		break;
-	case ACT_CT_SIZE:
-		if(mode) {
-			OUT("0 /* Invalid constraint at line %d */\n",
-				ct->_lineno);
-			return -1;
-		}
-		assert(ct->el_count == 1);
-		return emit_single_constraint_check(arg,
-			ct->elements[0], ACT_CT_SIZE);
-	case ACT_CT_FROM:
-		if(mode) {
-			OUT("0 /* Invalid constraint at line %d */\n",
-				ct->_lineno);
-			return -1;
-		}
-		OUT("check_alphabet_%x(sptr)\n", ct);
-		break;
-	case ACT_CT_WCOMP:
-	case ACT_CT_WCOMPS:
-		OUT("%d /* Unsupported constraint at line %d */\n",
-			ct->type, ct->_lineno);
-		return -1;
-		break;
-	case ACT_CA_SET:
-		OUT("(\n");
-		INDENT(+1);
-		for(el = 0; el < ct->el_count; el++) {
-			if(el) OUT("&& ");
-			emit_single_constraint_check(arg,
-				ct->elements[el], mode);
-		}
-		INDENT(-1);
-		OUT(")\n");
-		break;
-	case ACT_CA_CSV:
-		OUT("(\n");
-		INDENT(+1);
-		for(el = 0; el < ct->el_count; el++) {
-			if(el) OUT("|| ");
-			emit_single_constraint_check(arg,
-				ct->elements[el], mode);
-		}
-		INDENT(-1);
-		OUT(")\n");
-		break;
-	case ACT_CA_UNI:
-		OUT("(\n");
-		INDENT(+1);
-		for(el = 0; el < ct->el_count; el++) {
-			if(el) OUT("|| ");
-			emit_single_constraint_check(arg,
-				ct->elements[el], mode);
-		}
-		INDENT(-1);
-		OUT(")\n");
-		break;
-	case ACT_CA_INT:
-		OUT("(\n");
-		INDENT(+1);
-		for(el = 0; el < ct->el_count; el++) {
-			if(el) OUT("&& ");
-			emit_single_constraint_check(arg,
-				ct->elements[el], mode);
-		}
-		INDENT(-1);
-		OUT(")\n");
-		break;
-	case ACT_CA_CRC:
-		WARNING("Unsupported component relation constraint at line %d",
-			ct->_lineno);
-		OUT("%d /* Unsupported component relation constraint "
-			"at line %d */\n",
-			ct->type, ct->_lineno);
-		return -1;
-	case ACT_CA_EXC:
-		WARNING("Unsupported EXCEPT constraint at line %d",
-			ct->_lineno);
-		OUT("%d /* Unsupported EXCEPT constraint at line %d */\n",
-			ct->type, ct->_lineno);
-		return -1;
-	}
-
-	return 0;
-}
-
-static int
-check_constraint_type_presence(asn1p_constraint_t *ct, enum asn1p_constraint_type_e type) {
-	int el;
-
-	if(ct == NULL) return 0;
-
-	if(ct->type == type) return 1;
-
-	if(type == ACT_EL_VALUE) {
-		if(ct->type >= ACT_CT_SIZE
-		&& ct->type <= ACT_CT_WCOMPS)
-			/* Values defined further
-			 * are not really value's values */
-			return 0;
-		if(ct->type > ACT_EL_VALUE && ct->type < ACT_CT_SIZE)
-			return 1;	/* Also values */
-	}
-
-	for(el = 0; el < ct->el_count; el++) {
-		if(check_constraint_type_presence(ct->elements[el], type))
-			return 1;
-	}
-
-	return 0;
-}
-
-static int
-emit_alphabet_tables(arg_t *arg, asn1p_constraint_t *ct, int *table) {
-	int ch = 0;
-	int ch_start = 0;
-	int ch_stop = 0;
-	int el = 0;
-
-	assert(arg && ct);
-
-	switch(ct->type) {
-	case ACT_INVALID:
-		break;
-	case ACT_EL_VALUE:
-		if(!table) break;
-
-		switch(ct->value->type) {
-		case ATV_INTEGER:
-			if(ct->value->value.v_integer < 0
-			|| ct->value->value.v_integer > 255) {
-				OUT("\n");
-				OUT("#error Value %lld out of range "
-				"for alphabet character at line %d\n",
-				(long long)ct->value->value.v_integer,
-					ct->_lineno);
-				break;
-			} else {
-				ch = ct->value->value.v_integer;
-				table[ch] = 1;
-			}
-			break;
-		case ATV_STRING:
-			for(ch = 0; ch < ct->value->value.string.size; ch++)
-				table[ct->value->value.string.buf[ch]] = 1;
-			break;
-		default:
-			OUT("\n");
-			WARNING("Invalid alphabet character specification "
-				"at line %d", ct->_lineno);
-			OUT("#error Invalid alphabet character specification "
-				"at line %d\n", ct->_lineno);
-			break;
-		}
-		break;
-	case ACT_EL_RANGE:
-	case ACT_EL_LLRANGE:
-	case ACT_EL_RLRANGE:
-	case ACT_EL_ULRANGE:
-		if(!table) break;
-
-		ch_start = 0;
-		ch_stop = 255;
-
-		switch(ct->range_start->type) {
-		case ATV_INTEGER:
-			ch_start = ct->range_start->value.v_integer; break;
-		case ATV_MIN:	ch_start = 0;	break;
-		case ATV_MAX:	ch_start = 255;	break;
-		case ATV_STRING:
-			if(ct->range_start->value.string.size == 1) {
-				ch_start = ct->range_start->value.string.buf[0];
-				break;
-			}
-			/* Fall through */
-		default:
-			OUT("\n");
-			FATAL("Invalid alphabet range constraint "
-				"at line %d\n", ct->_lineno);
-			OUT("#error Invalid alphabet range constraint "
-				"at line %d\n", ct->_lineno);
-			return -1;
-		}
-
-		switch(ct->range_stop->type) {
-		case ATV_INTEGER:
-			ch_stop = ct->range_stop->value.v_integer; break;
-		case ATV_MIN:	ch_stop = 0;	break;
-		case ATV_MAX:	ch_stop = 255;	break;
-		case ATV_STRING:
-			if(ct->range_stop->value.string.size == 1) {
-				ch_stop = ct->range_stop->value.string.buf[0];
-				break;
-			}
-			/* Fall through */
-		default:
-			OUT("\n");
-			FATAL("Invalid alphabet range constraint "
-				"at line %d\n", ct->_lineno);
-			OUT("#error Invalid alphabet range constraint "
-				"at line %d\n", ct->_lineno);
-			break;
-		}
-
-		switch(ct->type) {
-		case ACT_EL_RANGE:	break;
-		case ACT_EL_RLRANGE:	ch_stop--;	break;
-		case ACT_EL_LLRANGE:	ch_start++;	break;
-		case ACT_EL_ULRANGE:	ch_start++; ch_stop--; break;
-		default:	break;
-		}
-
-		if(ch_start > ch_stop) {
-			WARNING("Empty character range "
-			"alphabet constraint at line %d", ct->_lineno);
-			OUT_NOINDENT("#warning Empty character range "
-			"alphabet constraint at line %d\n", ct->_lineno);
-			break;
-		}
-
-		for(ch = ch_start; ch <= ch_stop; ch++) {
-			if(ch < 0 || ch > 255) continue;
-			table[ch] = 1;
-		}
-
-		break;
-	case ACT_EL_EXT:
-		break;
-	case ACT_CT_SIZE:
-		break;
-	case ACT_CT_FROM:
-	  if(table) {
-			OUT("#error Nested FROM in subtype constraints\n");
-			return -1;
-	  } else {
-			table = alloca(256 * sizeof(table[0]));
-			memset(table, 0, 256 * sizeof(table[0]));
-
-			for(el = 0; el < ct->el_count; el++) {
-				emit_alphabet_tables(arg, ct->elements[el],
-					table);
-			}
-			OUT("static int alphabet_table_%x[256] = {\n", ct);
-			for(ch = 0; ch < 256; ch++) {
-				OUT("%d,", table[ch]?1:0);
-				if(!((ch+1) % 16)) {
-				  if(ch) {
-					int c;
-					OUT("\t/* ");
-					for(c = ch - 16; c < ch; c++) {
-						if(table[c]) {
-							if(c > 0x20
-								&& c < 0x80)
-								OUT("%c", c);
-							else
-								OUT(".", c);
-						} else {
-							OUT(" ");
-						}
-					}
-					OUT(" */");
-				  }
-				  OUT("\n");
-				}
-			}
-			OUT("};\n");
-			OUT("static int check_alphabet_%x(const void *sptr) {\n", ct);
-			INDENT(+1);
-			OUT("int *table = alphabet_table_%x;\n", ct);
-			emit_alphabet_check_cycle(arg);
-			OUT("return 1;\n");
-			INDENT(-1);
-			OUT("};\n");
-	  }
-		break;
-	case ACT_CT_WCOMP:
-	case ACT_CT_WCOMPS:
-		break;
-	case ACT_CA_CRC:
-		break;
-	case ACT_CA_SET:
-	case ACT_CA_CSV:
-	case ACT_CA_UNI:
-		for(el = 0; el < ct->el_count; el++)
-			emit_alphabet_tables(arg, ct->elements[el], table);
-		break;
-	case ACT_CA_INT:
-		if(table) {
-			int table2[256];
-
-			assert(ct->el_count >= 1);
-			emit_alphabet_tables(arg, ct->elements[0], table);
-			for(el = 1; el < ct->el_count; el++) {
-				memset(table2, 0, sizeof(table2));
-				emit_alphabet_tables(arg,
-					ct->elements[el], table2);
-				/* Intersection */
-				for(ch = 0; ch < 256; ch++) {
-					if(table2[ch] == 0)
-						table[ch] = 0;
-				}
-			}
-		} else {
-			for(el = 0; el < ct->el_count; el++)
-				emit_alphabet_tables(arg, ct->elements[el], 0);
-		}
-
-		break;
-	case ACT_CA_EXC:
-		OUT("EXC\n");
-		if(table) {
-			int table2[256];
-
-			assert(ct->el_count >= 1);
-			emit_alphabet_tables(arg, ct->elements[0], table);
-			for(el = 1; el < ct->el_count; el++) {
-				memset(table2, 0, sizeof(table2));
-				emit_alphabet_tables(arg,
-					ct->elements[el], table2);
-				/* Exclusion */
-				for(ch = 0; ch < 256; ch++) {
-					if(table2[ch])
-						table[ch] = 0;
-				}
-			}
-		} else {
-			for(el = 0; el < ct->el_count; el++)
-				emit_alphabet_tables(arg, ct->elements[el], 0);
-		}
-		break;
-	}
-
-	return 0;
-}
-
-static int
-emit_alphabet_check_cycle(arg_t *arg) {
-	asn1p_expr_type_e etype;
-
-	etype = _find_terminal_type(arg);
-	if(!(etype & ASN_STRING_MASK)
-	&& !(etype == ASN_BASIC_OCTET_STRING)) {
-		OUT("#error Cannot apply FROM constraint to ASN.1 type %s\n",
-			ASN_EXPR_TYPE2STR(etype));
-		return -1;
-	}
-
-	OUT("/* The underlying type is %s */\n",
-		ASN_EXPR_TYPE2STR(etype));
-	OUT("const %s_t *st = sptr;\n", MKID(arg->expr->Identifier));
-
-	switch(etype) {
-	case ASN_STRING_UTF8String:
-		OUT("uint8_t *ch = st->buf;\n");
-		OUT("uint8_t *end = ch + st->size;\n");
-		OUT("\n");
-		OUT("for(; ch < end; ch++) {\n");
-		INDENT(+1);
-		OUT("if(*ch >= 0x80 || !table[*ch]) return 0;\n");
-		INDENT(-1);
-		OUT("}\n");
-		break;
-	case ASN_STRING_UniversalString:
-		OUT("uint32_t *ch = st->buf;\n");
-		OUT("uint32_t *end = ch + st->size;\n");
-		OUT("\n");
-		OUT("for(; ch < end; ch++) {\n");
-		INDENT(+1);
-		OUT("uint32_t wc = (((uint8_t *)ch)[0] << 24)\n");
-		OUT("\t\t| (((uint8_t *)ch)[1] << 16)\n");
-		OUT("\t\t| (((uint8_t *)ch)[2] << 8)\n");
-		OUT("\t\t|  ((uint8_t *)ch)[3]\n");
-		OUT("if(wc > 255 || !table[wc]) return 0;\n");
-		INDENT(-1);
-		OUT("}\n");
-		OUT("if(ch != end) return 0; /* (size%4)! */\n");
-		break;
-	case ASN_STRING_BMPString:
-		OUT("uint16_t *ch = st->buf;\n");
-		OUT("uint16_t *end = ch + st->size;\n");
-		OUT("\n");
-		OUT("for(; ch < end; ch++) {\n");
-		INDENT(+1);
-		OUT("uint16_t wc = (((uint8_t *)ch)[0] << 8)\n");
-		OUT("\t\t| ((uint8_t *)ch)[1];\n");
-		OUT("if(wc > 255 || !table[wc]) return 0;\n");
-		INDENT(-1);
-		OUT("}\n");
-		OUT("if(ch != end) return 0; /* (size%2)! */\n");
-		break;
-	case ASN_BASIC_OCTET_STRING:
-	default:
-		OUT("uint8_t *ch = st->buf;\n");
-		OUT("uint8_t *end = ch + st->size;\n");
-		OUT("\n");
-		OUT("for(; ch < end; ch++) {\n");
-		INDENT(+1);
-		OUT("if(!table[*ch]) return 0;\n");
-		INDENT(-1);
-		OUT("}\n");
-		break;
-	}
-
-	return 0;
-}
-
-static int
-emit_size_determination_code(arg_t *arg) {
-	asn1p_expr_type_e etype = _find_terminal_type(arg);
-
-	switch(etype) {
-	case ASN_BASIC_BIT_STRING:
-		OUT("if(st->size > 0) {\n");
-		OUT("\t/* Size in bits */\n");
-		OUT("\tsize = (st->size - 1) - (st->buf[0] & 0x7);\n");
-		OUT("} else {\n");
-		OUT("\tsize = 0;\n");
-		OUT("}\n");
-		break;
-	case ASN_STRING_UniversalString:
-		OUT("size = st->size >> 2;\t/* 4 byte per character */\n");
-		break;
-	case ASN_STRING_BMPString:
-		OUT("size = st->size >> 1;\t/* 2 byte per character */\n");
-		break;
-	case ASN_STRING_UTF8String:
-		OUT("size = UTF8String_length(st, td->name, app_errlog, app_key);\n");
-		OUT("if(size == (size_t)-1) return -1;\n");
-		break;
-	default:
-		if((etype & ASN_STRING_MASK)
-		|| etype == ASN_BASIC_OCTET_STRING) {
-			OUT("size = st->size;\n");
-			break;
-		} else {
-			const char *type_name = ASN_EXPR_TYPE2STR(etype);
-			if(!type_name) type_name = arg->expr->Identifier;
-			WARNING("SIZE constraint is not defined for %s",
-				type_name);
-			OUT_NOINDENT("#warning SIZE constraint "
-				"not defined for %s!\n", type_name);
-			OUT("size = st->size;\n");
-		}
-		return -1;
-	}
-
-	return 0;
-}
-
-static int
-emit_value_determination_code(arg_t *arg) {
-	asn1p_expr_type_e etype = _find_terminal_type(arg);
-
-	switch(etype) {
-	case ASN_BASIC_INTEGER:
-	case ASN_BASIC_ENUMERATED:
-		if(arg->flags & A1C_USE_NATIVE_INTEGERS) {
-			OUT("value = *(int *)st;\n");
-		} else {
-			OUT("if(asn1_INTEGER2long(st, &value)) {\n");
-			INDENT(+1);
-			OUT("_ASN_ERRLOG(app_errlog, app_key,\n");
-			OUT("\t\"%%s: value too large\", td->name);\n");
-			OUT("return -1;\n");
-			INDENT(-1);
-			OUT("}\n");
-		}
-		break;
-	case ASN_BASIC_BOOLEAN:
-		OUT("value = st->value;\n");
-		break;
-	default:
-		WARNING("Value cannot be determined "
-			"for constraint check for %s at line %d\n",
-			arg->expr->Identifier, arg->expr->_lineno);
-		OUT("#error Value cannot be determined for %s at %d\n",
-			arg->expr->Identifier, arg->expr->_lineno);
-		break;
-	}
-
-	return 0;
-}
-
-static long compute_min_size(arg_t *arg) { return compute_xxx_size(arg, 0); }
-static long compute_max_size(arg_t *arg) { return compute_xxx_size(arg, 1); }
-
-static long compute_xxx_size(arg_t *arg, int _max) {
-	asn1p_expr_type_e etype;
-	long basic_max = 0x7fffffff;
-	long basic_min = 0x80000000;
-	long svalue = 0;
-
-	etype = _find_terminal_type(arg);
-	switch(etype) {
-	case ASN_BASIC_BIT_STRING:
-		svalue = _max?basic_max/8:0;
-		break;
-	case ASN_STRING_UTF8String:
-		svalue = _max?basic_max/6:0;
-		break;
-	case ASN_STRING_UniversalString:
-		svalue = _max?basic_max/4:0;
-		break;
-	case ASN_STRING_BMPString:
-		svalue = _max?basic_max/2:0;
-		break;
-	case ASN_BASIC_OCTET_STRING:
-		svalue = _max?basic_max:0;
-		break;
-	default:
-		if((etype & ASN_STRING_MASK)) {
-			svalue = _max?basic_max:0;
-			break;
-		}
-		svalue = _max?basic_max:basic_min;
-		break;
-	}
-
-	return svalue;
-}
-
-static asn1p_expr_type_e
-_find_terminal_type(arg_t *arg) {
-	asn1p_expr_t *expr;
-	expr = asn1f_find_terminal_type_ex(arg->asn, arg->mod, arg->expr, NULL);
-	if(expr) return expr->expr_type;
-	return A1TC_INVALID;
-}
-