REAL support


git-svn-id: https://asn1c.svn.sourceforge.net/svnroot/asn1c/trunk@321 59561ff5-6e30-0410-9f3c-9617f08c8826
diff --git a/libasn1compiler/asn1c_C.c b/libasn1compiler/asn1c_C.c
index 485e990..f17a0d6 100644
--- a/libasn1compiler/asn1c_C.c
+++ b/libasn1compiler/asn1c_C.c
@@ -78,45 +78,21 @@
 #define	MKID(id)	asn1c_make_identifier(0, (id), 0)
 
 int
-asn1c_lang_C_type_ENUMERATED(arg_t *arg) {
-	asn1p_expr_t *expr = arg->expr;
-	asn1p_expr_t *v;
-
+asn1c_lang_C_type_REAL(arg_t *arg) {
 	REDIR(OT_DEPS);
-
-	OUT("typedef enum %s {\n", MKID(expr->Identifier));
-	TQ_FOR(v, &(expr->members), next) {
-		switch(v->expr_type) {
-		case A1TC_UNIVERVAL:
-			OUT("\t%s\t= %lld,\n",
-				asn1c_make_identifier(0,
-					expr->Identifier,
-					v->Identifier, 0),
-				v->value->value.v_integer);
-			break;
-		case A1TC_EXTENSIBLE:
-			OUT("\t/*\n");
-			OUT("\t * Enumeration is extensible\n");
-			OUT("\t */\n");
-			break;
-		default:
-			return -1;
-		}
-	}
-	OUT("} %s_e;\n", MKID(expr->Identifier));
-
 	return asn1c_lang_C_type_SIMPLE_TYPE(arg);
 }
 
-
 int
-asn1c_lang_C_type_INTEGER(arg_t *arg) {
+asn1c_lang_C_type_common_INTEGER(arg_t *arg) {
 	asn1p_expr_t *expr = arg->expr;
 	asn1p_expr_t *v;
 
 	REDIR(OT_DEPS);
 
-	if(TQ_FIRST(&(expr->members))) {
+	if(expr->expr_type == ASN_BASIC_ENUMERATED
+	|| TQ_FIRST(&(expr->members))
+	) {
 		OUT("typedef enum %s {\n", MKID(expr->Identifier));
 		TQ_FOR(v, &(expr->members), next) {
 			switch(v->expr_type) {
@@ -127,6 +103,11 @@
 						v->Identifier, 0),
 					v->value->value.v_integer);
 				break;
+			case A1TC_EXTENSIBLE:
+				OUT("\t/*\n");
+				OUT("\t * Enumeration is extensible\n");
+				OUT("\t */\n");
+				break;
 			default:
 				return -1;
 			}
diff --git a/libasn1compiler/asn1c_C.h b/libasn1compiler/asn1c_C.h
index e8f56ed..76fce34 100644
--- a/libasn1compiler/asn1c_C.h
+++ b/libasn1compiler/asn1c_C.h
@@ -11,8 +11,8 @@
 int asn1c_lang_C_type_SEx_OF(arg_t *);	/* SET OF or  SEQUENCE OF */
 int asn1c_lang_C_type_CHOICE(arg_t *);
 
-int asn1c_lang_C_type_INTEGER(arg_t *);
-int asn1c_lang_C_type_ENUMERATED(arg_t *);
+int asn1c_lang_C_type_common_INTEGER(arg_t *);
+int asn1c_lang_C_type_REAL(arg_t *);
 int asn1c_lang_C_type_SIMPLE_TYPE(arg_t *);
 
 static asn1_language_map_t asn1_lang_C[] __attribute__ ((unused)) = {
@@ -38,9 +38,9 @@
 	 */
 	{ AMT_TYPE, ASN_BASIC_BOOLEAN,	asn1c_lang_C_type_SIMPLE_TYPE },
 	{ AMT_TYPE, ASN_BASIC_NULL,	asn1c_lang_C_type_SIMPLE_TYPE },
-	{ AMT_TYPE, ASN_BASIC_INTEGER,	asn1c_lang_C_type_INTEGER },
-	/* [Skipped REAL] */
-	{ AMT_TYPE, ASN_BASIC_ENUMERATED,	asn1c_lang_C_type_ENUMERATED },
+	{ AMT_TYPE, ASN_BASIC_INTEGER,	asn1c_lang_C_type_common_INTEGER },
+	{ AMT_TYPE, ASN_BASIC_REAL,	asn1c_lang_C_type_REAL },
+	{ AMT_TYPE, ASN_BASIC_ENUMERATED,  asn1c_lang_C_type_common_INTEGER },
 	{ AMT_TYPE, ASN_BASIC_BIT_STRING,	asn1c_lang_C_type_SIMPLE_TYPE },
 	{ AMT_TYPE, ASN_BASIC_OCTET_STRING,	asn1c_lang_C_type_SIMPLE_TYPE },
 	{ AMT_TYPE, ASN_BASIC_OBJECT_IDENTIFIER,asn1c_lang_C_type_SIMPLE_TYPE },
diff --git a/libasn1compiler/asn1c_constraint.c b/libasn1compiler/asn1c_constraint.c
index 7398a46..5147806 100644
--- a/libasn1compiler/asn1c_constraint.c
+++ b/libasn1compiler/asn1c_constraint.c
@@ -65,7 +65,8 @@
 	switch(etype) {
 	case ASN_BASIC_INTEGER:
 	case ASN_BASIC_ENUMERATED:
-		if(!(arg->flags & A1C_USE_NATIVE_INTEGERS))
+	case ASN_BASIC_REAL:
+		if(!(arg->flags & A1C_USE_NATIVE_TYPES))
 			produce_st = 1;
 		break;
 	case ASN_BASIC_BIT_STRING:
@@ -91,6 +92,9 @@
 			case ASN_BASIC_ENUMERATED:
 				OUT("long value;\n");
 				break;
+			case ASN_BASIC_REAL:
+				OUT("double value;\n");
+				break;
 			case ASN_BASIC_BOOLEAN:
 				OUT("int value;\n");
 				break;
@@ -549,7 +553,7 @@
 	switch(etype) {
 	case ASN_BASIC_INTEGER:
 	case ASN_BASIC_ENUMERATED:
-		if(arg->flags & A1C_USE_NATIVE_INTEGERS) {
+		if(arg->flags & A1C_USE_NATIVE_TYPES) {
 			OUT("value = *(const int *)sptr;\n");
 		} else {
 			if(r_value->el_count == 0
@@ -579,6 +583,20 @@
 			OUT("}\n");
 		}
 		break;
+	case ASN_BASIC_REAL:
+		if(arg->flags & A1C_USE_NATIVE_TYPES) {
+			OUT("value = *(const double *)sptr;\n");
+		} else {
+			OUT("if(asn1_REAL2double(st, &value)) {\n");
+				INDENT(+1);
+				OUT("_ASN_ERRLOG(app_errlog, app_key,\n");
+				OUT("\t\"%%s: value too large (%%s:%%d)\",\n");
+				OUT("\ttd->name, __FILE__, __LINE__);\n");
+				OUT("return -1;\n");
+				INDENT(-1);
+			OUT("}\n");
+		}
+		break;
 	case ASN_BASIC_BOOLEAN:
 		OUT("value = (*(const int *)sptr) ? 1 : 0;\n");
 		break;
diff --git a/libasn1compiler/asn1c_misc.c b/libasn1compiler/asn1c_misc.c
index 2bdbd7c..1c4912d 100644
--- a/libasn1compiler/asn1c_misc.c
+++ b/libasn1compiler/asn1c_misc.c
@@ -150,16 +150,25 @@
 #endif
 	case ASN_BASIC_INTEGER:
 	case ASN_BASIC_ENUMERATED:
-		if((arg->flags & A1C_USE_NATIVE_INTEGERS)) {
+	case ASN_BASIC_REAL:
+		if((arg->flags & A1C_USE_NATIVE_TYPES)) {
 			switch(_format) {
 			case TNF_CTYPE:
 			case TNF_RSAFE:
-				return "int";
-			default:
-				if(expr->expr_type == ASN_BASIC_INTEGER)
-					return "NativeInteger";
+				if(expr->expr_type == ASN_BASIC_REAL)
+					return "double";
 				else
-					return "NativeEnumerated";
+					return "int";
+			default: break;
+			}
+			switch(expr->expr_type) {
+			case ASN_BASIC_INTEGER:
+				return "NativeInteger";
+			case ASN_BASIC_ENUMERATED:
+				return "NativeEnumerated";
+			case ASN_BASIC_REAL:
+				return "NativeReal";
+			default: break;
 			}
 		}
 		/* Fall through */
diff --git a/libasn1compiler/asn1compiler.h b/libasn1compiler/asn1compiler.h
index 6b9219a..8099e6e 100644
--- a/libasn1compiler/asn1compiler.h
+++ b/libasn1compiler/asn1compiler.h
@@ -20,9 +20,9 @@
 	 */
 	A1C_OMIT_SUPPORT_CODE	= 0x0004,
 	/*
-	 * Use native integers instead of INTEGER_t and ENUMERATED_t types.
+	 * Use native data types instead of INTEGER_t et al.
 	 */
-	A1C_USE_NATIVE_INTEGERS	= 0x0008,
+	A1C_USE_NATIVE_TYPES	= 0x0008,
 	/*
 	 * Do not use C99 extensions.
 	 */