generate float instead of double if constraints suggest this
diff --git a/libasn1compiler/asn1c_C.c b/libasn1compiler/asn1c_C.c
index c5ededd..5800bb5 100644
--- a/libasn1compiler/asn1c_C.c
+++ b/libasn1compiler/asn1c_C.c
@@ -122,6 +122,21 @@
return 1;
}
+static int
+REAL_fits_float32(arg_t *arg, asn1p_expr_t *expr) {
+ asn1p_expr_type_e etype = expr_get_type(arg, arg->expr);
+ if(etype == ASN_BASIC_REAL) {
+ asn1cnst_range_t *range = asn1constraint_compute_OER_range(
+ expr->Identifier, etype, expr->combined_constraints, ACT_EL_RANGE,
+ 0, 0, 0);
+ int fits = range->narrowing == NARROW_FLOAT32;
+ asn1constraint_range_free(range);
+ return fits;
+ } else {
+ return 0;
+ }
+}
+
int
asn1c_lang_C_type_common_INTEGER(arg_t *arg) {
asn1p_expr_t *expr = arg->expr;
@@ -1298,6 +1313,7 @@
&& expr_elements_count(arg, expr))
|| (expr->expr_type == ASN_BASIC_INTEGER
&& asn1c_type_fits_long(arg, expr) == FL_FITS_UNSIGN)
+ || REAL_fits_float32(arg, expr)
)
etd_spec = ETD_HAS_SPECIFICS;
else
@@ -1339,6 +1355,16 @@
REDIR(OT_STAT_DEFS);
+ if(REAL_fits_float32(arg, expr)) {
+ if(!(expr->_type_referenced)) OUT("static ");
+ OUT("const asn_NativeReal_specifics_t asn_SPC_%s_specs_%d = {\n",
+ MKID(expr), expr->_type_unique_index);
+ INDENT(+1);
+ OUT("4\t/* Use 'float' type. */\n");
+ INDENT(-1);
+ OUT("};\n");
+ }
+
/*
* Print out asn_DEF_<type>_[all_]tags[] vectors.
*/
@@ -1374,22 +1400,22 @@
p, expr->_type_unique_index);
} else {
OUT("extern asn_TYPE_descriptor_t asn_DEF_%s;\n", p);
- if (etd_spec == ETD_HAS_SPECIFICS) {
- if((expr->expr_type == ASN_BASIC_ENUMERATED) ||
- (expr->expr_type == ASN_BASIC_INTEGER)) {
- if(expr->_type_referenced) {
- OUT("extern const asn_INTEGER_specifics_t "
- "asn_SPC_%s_specs_%d;\n", c_name(arg).base_name, expr->_type_unique_index);
- }
- } else {
+ if(etd_spec == ETD_HAS_SPECIFICS && expr->_type_referenced) {
+ if((expr->expr_type == ASN_BASIC_ENUMERATED)
+ || (expr->expr_type == ASN_BASIC_INTEGER)) {
+ OUT("extern const asn_INTEGER_specifics_t "
+ "asn_SPC_%s_specs_%d;\n",
+ c_name(arg).base_name, expr->_type_unique_index);
+ } else {
asn1p_expr_t *terminal = WITH_MODULE_NAMESPACE(
expr->module, expr_ns,
asn1f_find_terminal_type_ex(arg->asn, expr_ns, expr));
-
- OUT("extern asn_%s_specifics_t ", asn1c_type_name(arg, terminal, TNF_SAFE));
- OUT("asn_SPC_%s_specs_%d;\n", MKID(expr), expr->_type_unique_index);
- }
- }
+ OUT("extern const asn_%s_specifics_t ",
+ asn1c_type_name(arg, terminal, TNF_SAFE));
+ OUT("asn_SPC_%s_specs_%d;\n", MKID(expr),
+ expr->_type_unique_index);
+ }
+ }
OUT("asn_struct_free_f %s_free;\n", p);
OUT("asn_struct_print_f %s_print;\n", p);
OUT("asn_constr_check_f %s_constraint;\n", p);
@@ -1846,14 +1872,6 @@
if(range->incompatible || range->not_OER_visible) {
OUT("{ 0, 0 }");
- } else if(expr_get_type(arg, arg->expr) == ASN_BASIC_REAL) {
- if(range->narrowing == NARROW_FLOAT32) {
- OUT("{ 4, 0 }");
- } else if(range->narrowing == NARROW_FLOAT64) {
- OUT("{ 8, 0 }");
- } else {
- OUT("{ 0, 0 }");
- }
} else if(range->left.type == ARE_VALUE && range->left.value >= 0
&& range->right.type == ARE_MAX) {
OUT("{ 0, 1 }");
diff --git a/libasn1compiler/asn1c_constraint.c b/libasn1compiler/asn1c_constraint.c
index d68e9d1..bd025d5 100644
--- a/libasn1compiler/asn1c_constraint.c
+++ b/libasn1compiler/asn1c_constraint.c
@@ -2,6 +2,7 @@
#include "asn1c_constraint.h"
#include "asn1c_misc.h"
#include "asn1c_out.h"
+#include "asn1c_naming.h"
#include <asn1fix_crange.h> /* constraint groker from libasn1fix */
#include <asn1fix_export.h> /* other exportables from libasn1fix */
@@ -114,7 +115,7 @@
}
break;
case ASN_BASIC_REAL:
- OUT("double value;\n");
+ OUT("%s value;\n", c_name(arg).type.constrained_c_name);
break;
case ASN_BASIC_BOOLEAN:
OUT("BOOLEAN_t value;\n");
@@ -676,7 +677,7 @@
INDENT(-1);
OUT("}\n");
} else {
- OUT("value = *(const double *)sptr;\n");
+ OUT("value = *(const %s *)sptr;\n", c_name(arg).type.c_name);
}
break;
case ASN_BASIC_BOOLEAN:
diff --git a/libasn1compiler/asn1c_misc.c b/libasn1compiler/asn1c_misc.c
index 59cb497..086a8fa 100644
--- a/libasn1compiler/asn1c_misc.c
+++ b/libasn1compiler/asn1c_misc.c
@@ -215,7 +215,7 @@
}
}
- if(_format == TNF_CTYPE) {
+ if(_format == TNF_CTYPE || _format == TNF_CONSTYPE) {
/*
* If the component references the type itself,
* switch to a recursion-safe type naming
@@ -236,18 +236,36 @@
case ASN_BASIC_ENUMERATED:
case ASN_BASIC_REAL:
if((expr->expr_type == ASN_BASIC_REAL
- && !(arg->flags & A1C_USE_WIDE_TYPES))
+ && (_format == TNF_CONSTYPE || !(arg->flags & A1C_USE_WIDE_TYPES)))
|| asn1c_type_fits_long(arg, expr)) {
switch(_format) {
- case TNF_CTYPE:
- case TNF_RSAFE:
- if(expr->expr_type == ASN_BASIC_REAL)
- return "double";
- else if(asn1c_type_fits_long(arg, expr) == FL_FITS_UNSIGN)
- return "unsigned long";
- else
- return "long";
- default:
+ case TNF_CONSTYPE:
+ if(expr->expr_type == ASN_BASIC_REAL) {
+ return "double";
+ } else if(asn1c_type_fits_long(arg, expr) == FL_FITS_UNSIGN) {
+ return "unsigned long";
+ } else {
+ return "long";
+ }
+ case TNF_CTYPE:
+ case TNF_RSAFE:
+ if(expr->expr_type == ASN_BASIC_REAL) {
+ asn1cnst_range_t *range = asn1constraint_compute_OER_range(
+ expr->Identifier, ASN_BASIC_REAL,
+ expr->combined_constraints, ACT_EL_RANGE, 0, 0, 0);
+ if(range->narrowing == NARROW_FLOAT32) {
+ asn1constraint_range_free(range);
+ return "float";
+ } else {
+ asn1constraint_range_free(range);
+ return "double";
+ }
+ } else if(asn1c_type_fits_long(arg, expr) == FL_FITS_UNSIGN) {
+ return "unsigned long";
+ } else {
+ return "long";
+ }
+ default:
typename = 0;
switch(expr->expr_type) {
case ASN_BASIC_INTEGER:
@@ -298,6 +316,7 @@
case TNF_SAFE:
return asn1c_make_identifier(0, exprid, typename, (char*)0);
case TNF_CTYPE: /* C type */
+ case TNF_CONSTYPE: /* C type */
return asn1c_make_identifier(0, exprid,
exprid?"t":typename, exprid?0:"t", (char*)0);
case TNF_RSAFE: /* Recursion-safe type */
diff --git a/libasn1compiler/asn1c_misc.h b/libasn1compiler/asn1c_misc.h
index f9f3c45..77e3827 100644
--- a/libasn1compiler/asn1c_misc.h
+++ b/libasn1compiler/asn1c_misc.h
@@ -23,8 +23,9 @@
TNF_UNMODIFIED = 0x10, /* Return unmodified type name */
TNF_INCLUDE = 0x20, /* Format for #include <> */
TNF_CTYPE = 0x30, /* Format as normal C-ish type (append "_t") */
- TNF_SAFE = 0x40, /* Replace unsafe characters with _ */
- TNF_RSAFE = 0x50, /* Recursion-safe C type format */
+ TNF_CONSTYPE = 0x40, /* Replace unsafe characters with _ */
+ TNF_SAFE = 0x50, /* Replace unsafe characters with _ */
+ TNF_RSAFE = 0x60, /* Recursion-safe C type format */
};
const char *asn1c_type_name(arg_t *arg, asn1p_expr_t *expr, enum tnfmt _format);
diff --git a/libasn1compiler/asn1c_naming.c b/libasn1compiler/asn1c_naming.c
index 82f8db5..6fad84d 100644
--- a/libasn1compiler/asn1c_naming.c
+++ b/libasn1compiler/asn1c_naming.c
@@ -121,6 +121,7 @@
static abuf b_type_part_name;
static abuf b_type_base_name;
static abuf b_type_c_name;
+ static abuf b_type_constrained_c_name;
static abuf b_asn_name;
static abuf b_part_name;
static abuf b_base_name;
@@ -136,6 +137,7 @@
abuf_clear(&b_type_part_name);
abuf_clear(&b_type_base_name);
abuf_clear(&b_type_c_name);
+ abuf_clear(&b_type_constrained_c_name);
abuf_clear(&b_asn_name);
abuf_clear(&b_base_name);
abuf_clear(&b_part_name);
@@ -152,6 +154,8 @@
abuf_str(&b_type_part_name, asn1c_type_name(arg, expr, TNF_SAFE));
abuf_str(&b_type_base_name, asn1c_type_name(arg, expr, TNF_SAFE));
abuf_str(&b_type_c_name, asn1c_type_name(arg, expr, TNF_CTYPE));
+ abuf_str(&b_type_constrained_c_name,
+ asn1c_type_name(arg, expr, TNF_CONSTYPE));
if((arg->flags & A1C_COMPOUND_NAMES)) {
@@ -189,6 +193,7 @@
names.type.base_name = b_type_base_name.buffer;
names.type.part_name = b_type_part_name.buffer;
names.type.c_name = b_type_c_name.buffer;
+ names.type.constrained_c_name = b_type_constrained_c_name.buffer;
names.asn_name = b_asn_name.buffer;
names.part_name = b_part_name.buffer;
names.base_name = b_base_name.buffer;
@@ -269,6 +274,7 @@
FMT_COMPONENT(type.part_name);
FMT_COMPONENT(type.base_name);
FMT_COMPONENT(type.c_name);
+ FMT_COMPONENT(type.constrained_c_name);
FMT_COMPONENT(asn_name);
FMT_COMPONENT(part_name);
FMT_COMPONENT(base_name);
diff --git a/libasn1compiler/asn1c_naming.h b/libasn1compiler/asn1c_naming.h
index f92431b..77af5d5 100644
--- a/libasn1compiler/asn1c_naming.h
+++ b/libasn1compiler/asn1c_naming.h
@@ -11,6 +11,7 @@
const char *part_name; /* "T_Rex" */
const char *base_name; /* "T_Rex" */
const char *c_name; /* "T_Rex_t" */
+ const char *constrained_c_name; /* "long" */
} type;
const char *asn_name; /* "foo" */
const char *part_name; /* "foo", "signed" */