PER visible constraints are used to select the native representation for INTEGER types

git-svn-id: https://asn1c.svn.sourceforge.net/svnroot/asn1c/trunk@957 59561ff5-6e30-0410-9f3c-9617f08c8826
This commit is contained in:
vlm 2005-08-14 02:18:27 +00:00
parent 96853d8f42
commit 75b3a53e15
10 changed files with 4395 additions and 17 deletions

View File

@ -5,6 +5,8 @@
member names are invented on the fly). (Test case 87).
* Generating enumeration tables for INTEGER types (Test case 88).
* Generating enumeration tables for BIT STRING types (Test case 89).
* Conditional INTEGER/ENUMERATED representation: long vs. INTEGER_t
type is chosen based on PER visible constraints (Test case 90).
0.9.17: 2005-Aug-07

View File

@ -218,29 +218,26 @@ asn1c_lang_C_type_BIT_STRING(arg_t *arg) {
asn1p_expr_t *expr = arg->expr;
asn1p_expr_t *v;
int el_count = expr_elements_count(arg, expr);
int eidx = 0;
if(el_count) {
int eidx = 0;
REDIR(OT_DEPS);
OUT("typedef enum ");
out_name_chain(arg, 1);
OUT(" {\n");
TQ_FOR(v, &(expr->members), next) {
switch(v->expr_type) {
case A1TC_UNIVERVAL:
OUT("\t");
out_name_chain(arg, 0);
OUT("_%s", MKID(v->Identifier));
OUT("\t= %" PRIdASN "%s\n",
v->value->value.v_integer,
(eidx+1 < el_count) ? "," : "");
eidx++;
break;
default:
eidx++;
if(v->expr_type != A1TC_UNIVERVAL) {
OUT("/* Unexpected BIT STRING element: %s */\n",
v->Identifier);
break;
continue;
}
OUT("\t");
out_name_chain(arg, 0);
OUT("_%s", MKID(v->Identifier));
OUT("\t= %" PRIdASN "%s\n",
v->value->value.v_integer,
(eidx < el_count) ? "," : "");
}
OUT("} ");
out_name_chain(arg, 0);

View File

@ -62,6 +62,9 @@ asn1c_emit_constraint_checking_code(arg_t *arg) {
switch(etype) {
case ASN_BASIC_INTEGER:
case ASN_BASIC_ENUMERATED:
if(asn1c_type_fits_long(arg, arg->expr) == FL_NOTFIT)
produce_st = 1;
break;
case ASN_BASIC_REAL:
if(!(arg->flags & A1C_USE_NATIVE_TYPES))
produce_st = 1;
@ -556,7 +559,7 @@ emit_value_determination_code(arg_t *arg, asn1p_expr_type_e etype, asn1cnst_rang
switch(etype) {
case ASN_BASIC_INTEGER:
case ASN_BASIC_ENUMERATED:
if(arg->flags & A1C_USE_NATIVE_TYPES) {
if(asn1c_type_fits_long(arg, arg->expr) != FL_NOTFIT) {
OUT("value = *(const long *)sptr;\n");
} else {
if(r_value->el_count == 0

View File

@ -1,7 +1,8 @@
#include "asn1c_internal.h"
#include "asn1c_misc.h"
#include <asn1fix_export.h>
#include <asn1fix_crange.h> /* constraint groker from libasn1fix */
#include <asn1fix_export.h> /* other exportable stuff from libasn1fix */
/*
* Checks that the given string is not a reserved C/C++ keyword.
@ -189,7 +190,9 @@ asn1c_type_name(arg_t *arg, asn1p_expr_t *expr, enum tnfmt _format) {
case ASN_BASIC_INTEGER:
case ASN_BASIC_ENUMERATED:
case ASN_BASIC_REAL:
if((arg->flags & A1C_USE_NATIVE_TYPES)) {
if((expr->expr_type == ASN_BASIC_REAL
&& (arg->flags & A1C_USE_NATIVE_TYPES))
|| asn1c_type_fits_long(arg, expr)) {
switch(_format) {
case TNF_CTYPE:
case TNF_RSAFE:
@ -239,3 +242,84 @@ asn1c_type_name(arg_t *arg, asn1p_expr_t *expr, enum tnfmt _format) {
return typename;
}
/*
* Check whether the specified INTEGER or ENUMERATED type can be represented
* using the generic 'long' type.
*/
enum asn1c_fitslong_e
asn1c_type_fits_long(arg_t *arg, asn1p_expr_t *expr) {
asn1cnst_range_t *range = 0;
asn1cnst_edge_t left;
asn1cnst_edge_t right;
asn1p_expr_t *v;
/*
* Since we don't know the sizeof(long) on the possible target platform
* which will be compiling the code generated by asn1c, let's play it
* simple: long's range is equal to or greater than int32_t.
*/
#define LEFTMIN INT32_MIN
#define RIGHTMAX INT32_MAX
/* Descend to the terminal type */
expr = asn1f_find_terminal_type_ex(arg->asn, expr);
if(expr == 0) return FL_NOTFIT;
/* The "fits into long" operation is relevant only for integer types */
switch(expr->expr_type) {
case ASN_BASIC_INTEGER:
case ASN_BASIC_ENUMERATED:
break;
default:
return FL_NOTFIT;
}
/*
* First, evaluate the range of explicitly given identifiers.
*/
TQ_FOR(v, &(expr->members), next) {
if(v->expr_type != A1TC_UNIVERVAL)
continue;
if(v->value->value.v_integer < LEFTMIN
|| v->value->value.v_integer > RIGHTMAX)
return FL_NOTFIT;
}
/*
* Second, pull up the PER visible range of the INTEGER.
*/
if(expr->combined_constraints)
range = asn1constraint_compute_PER_range(expr->expr_type,
expr->combined_constraints, ACT_EL_RANGE, 0, 0, 0);
if(!range
|| range->empty_constraint
|| range->extensible
|| range->incompatible
|| range->not_PER_visible
) {
asn1constraint_range_free(range);
return (arg->flags & A1C_USE_NATIVE_TYPES)
? FL_FORCED : FL_NOTFIT;
}
left = range->left;
right = range->right;
asn1constraint_range_free(range);
/* If some fixed value is outside of target range, not fit */
if(left.type == ARE_VALUE
&& (left.value < LEFTMIN || left.value > RIGHTMAX))
return FL_NOTFIT;
if(right.type == ARE_VALUE
&& (right.value > RIGHTMAX || right.value < LEFTMIN))
return FL_NOTFIT;
/* If the range is open, fits only if -fnative-types is given */
if(left.type != ARE_VALUE || right.type != ARE_VALUE) {
return (arg->flags & A1C_USE_NATIVE_TYPES)
? FL_FORCED : FL_NOTFIT;
}
return FL_FITSOK;
}

View File

@ -24,4 +24,19 @@ enum tnfmt {
};
char *asn1c_type_name(arg_t *arg, asn1p_expr_t *expr, enum tnfmt _format);
/*
* Check whether the specified INTEGER or ENUMERATED type can be represented
* using the generic 'long' type.
* Return values:
* FL_NOTFIT: No, it cannot be represented using long.
* FL_FITSOK: It can be represented using long.
* FL_FORCED: Probably can't, but -fnative-types is in force.
*/
enum asn1c_fitslong_e {
FL_NOTFIT,
FL_FITSOK,
FL_FORCED,
};
enum asn1c_fitslong_e asn1c_type_fits_long(arg_t *arg, asn1p_expr_t *expr);
#endif /* _ASN1_COMPILER_MISC_H_ */

View File

@ -5,7 +5,7 @@
-- .spelio.software.asn1c.test (9363.1.5.1)
-- .89
ModuleIntegerEnumeration
ModuleBitStringEnumeration
{ iso org(3) dod(6) internet (1) private(4) enterprise(1)
spelio(9363) software(1) asn1c(5) test(1) 89 }
DEFINITIONS ::=

View File

@ -0,0 +1,32 @@
-- OK: Everything is fine
-- iso.org.dod.internet.private.enterprise (1.3.6.1.4.1)
-- .spelio.software.asn1c.test (9363.1.5.1)
-- .90
ModuleConditionalIntegerType
{ iso org(3) dod(6) internet (1) private(4) enterprise(1)
spelio(9363) software(1) asn1c(5) test(1) 90 }
DEFINITIONS ::=
BEGIN
CN-IntegerUnlimited ::= INTEGER
CN-IntegerMinMax ::= INTEGER (MIN..MAX)
CN-IntegerMinLow ::= INTEGER (MIN..1)
NO-IntegerMinHigh ::= INTEGER (MIN..5000000000)
NO-IntegerLowHigh ::= INTEGER (1..5000000000)
CN-IntegerLowMax ::= INTEGER (1..MAX)
NO-IntegerHighMax ::= INTEGER (5000000000..MAX)
NO-IntegerLowestMax ::= INTEGER (-5000000000..MAX)
NO-IntegerOutRange ::= INTEGER (5000000000..5000000001)
NO-IntegerOutValue ::= INTEGER (5000000000)
OK-IntegerInRange1 ::= INTEGER (-100..100)
OK-IntegerInRange2 ::= INTEGER (-100|100)
OK-IntegerInRange3 ::= INTEGER (-2147483648..2147483647)
OK-IntegerInRange4 ::= INTEGER (-2147483648|2147483647)
OK-IntegerInRange5 ::= INTEGER (-2147483648|2147483647,...)
CN-IntegerEnumerated1 ::= INTEGER { a(1), b(2) }
NO-IntegerEnumerated2 ::= INTEGER { a(1), b(5000000000) }
END

View File

@ -0,0 +1,80 @@
ModuleConditionalIntegerType { iso org(3) dod(6) internet(1) private(4)
enterprise(1) spelio(9363) software(1) asn1c(5) test(1) 90 }
DEFINITIONS ::=
BEGIN
CN-IntegerUnlimited ::= INTEGER
-- Practical constraints (CN-IntegerUnlimited): (MIN..MAX)
-- PER-visible constraints (CN-IntegerUnlimited): (MIN..MAX)
CN-IntegerMinMax ::= INTEGER (MIN..MAX)
-- Combined constraints: (MIN..MAX)
-- Practical constraints (CN-IntegerMinMax): (MIN..MAX)
-- PER-visible constraints (CN-IntegerMinMax): (MIN..MAX)
CN-IntegerMinLow ::= INTEGER (MIN..1)
-- Combined constraints: (MIN..1)
-- Practical constraints (CN-IntegerMinLow): (MIN..1)
-- PER-visible constraints (CN-IntegerMinLow): (MIN..1)
NO-IntegerMinHigh ::= INTEGER (MIN..5000000000)
-- Combined constraints: (MIN..5000000000)
-- Practical constraints (NO-IntegerMinHigh): (MIN..5000000000)
-- PER-visible constraints (NO-IntegerMinHigh): (MIN..5000000000)
NO-IntegerLowHigh ::= INTEGER (1..5000000000)
-- Combined constraints: (1..5000000000)
-- Practical constraints (NO-IntegerLowHigh): (1..5000000000)
-- PER-visible constraints (NO-IntegerLowHigh): (1..5000000000)
CN-IntegerLowMax ::= INTEGER (1..MAX)
-- Combined constraints: (1..MAX)
-- Practical constraints (CN-IntegerLowMax): (1..MAX)
-- PER-visible constraints (CN-IntegerLowMax): (1..MAX)
NO-IntegerHighMax ::= INTEGER (5000000000..MAX)
-- Combined constraints: (5000000000..MAX)
-- Practical constraints (NO-IntegerHighMax): (5000000000..MAX)
-- PER-visible constraints (NO-IntegerHighMax): (5000000000..MAX)
NO-IntegerLowestMax ::= INTEGER (-5000000000..MAX)
-- Combined constraints: (-5000000000..MAX)
-- Practical constraints (NO-IntegerLowestMax): (-5000000000..MAX)
-- PER-visible constraints (NO-IntegerLowestMax): (-5000000000..MAX)
NO-IntegerOutRange ::= INTEGER (5000000000..5000000001)
-- Combined constraints: (5000000000..5000000001)
-- Practical constraints (NO-IntegerOutRange): (5000000000..5000000001)
-- PER-visible constraints (NO-IntegerOutRange): (5000000000..5000000001)
NO-IntegerOutValue ::= INTEGER (5000000000)
-- Combined constraints: (5000000000)
-- Practical constraints (NO-IntegerOutValue): (5000000000)
-- PER-visible constraints (NO-IntegerOutValue): (5000000000)
OK-IntegerInRange1 ::= INTEGER (-100..100)
-- Combined constraints: (-100..100)
-- Practical constraints (OK-IntegerInRange1): (-100..100)
-- PER-visible constraints (OK-IntegerInRange1): (-100..100)
OK-IntegerInRange2 ::= INTEGER (-100 | 100)
-- Combined constraints: (-100 | 100)
-- Practical constraints (OK-IntegerInRange2): (-100 | 100)
-- PER-visible constraints (OK-IntegerInRange2): (-100 | 100)
OK-IntegerInRange3 ::= INTEGER (-2147483648..2147483647)
-- Combined constraints: (-2147483648..2147483647)
-- Practical constraints (OK-IntegerInRange3): (-2147483648..2147483647)
-- PER-visible constraints (OK-IntegerInRange3): (-2147483648..2147483647)
OK-IntegerInRange4 ::= INTEGER (-2147483648 | 2147483647)
-- Combined constraints: (-2147483648 | 2147483647)
-- Practical constraints (OK-IntegerInRange4): (-2147483648 | 2147483647)
-- PER-visible constraints (OK-IntegerInRange4): (-2147483648 | 2147483647)
OK-IntegerInRange5 ::= INTEGER (-2147483648 | 2147483647,...)
-- Combined constraints: (-2147483648 | 2147483647,...)
-- Practical constraints (OK-IntegerInRange5): (-2147483648 | 2147483647,...)
-- PER-visible constraints (OK-IntegerInRange5): (-2147483648 | 2147483647,...)
END

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff