Skip to content

Commit

Permalink
Merge pull request vlm#14 from velichkov/real_constrain
Browse files Browse the repository at this point in the history
Fix REAL constraints (part 2)
  • Loading branch information
mouse07410 committed Apr 19, 2017
2 parents 8c9bce1 + 8ec6595 commit 297e492
Show file tree
Hide file tree
Showing 12 changed files with 2,274 additions and 106 deletions.
1 change: 1 addition & 0 deletions asn1c/tests/check-src/check-50.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <Str4.h>
#include <Utf8-4.h>
#include <VisibleIdentifier.h>
#include <SequenceReal.h>

int
main(int ac, char **av) {
Expand Down
32 changes: 27 additions & 5 deletions libasn1compiler/asn1c_constraint.c
Original file line number Diff line number Diff line change
Expand Up @@ -530,15 +530,37 @@ emit_range_comparison_code(arg_t *arg, asn1cnst_range_t *range, const char *varn
}

if(ignore_left) {
OUT("%s <= %lldLL", varname, r->right.value);
if (r->right.type == ARE_DOUBLE) {
OUT("%s <= %LfL", varname, r->right.value_double);
} else {
OUT("%s <= %lldLL", varname, r->right.value);
}
} else if(ignore_right) {
OUT("%s >= %lldLL", varname, r->left.value);
} else if(r->left.value == r->right.value) {
if (r->left.type == ARE_DOUBLE) {
OUT("%s >= %LfL", varname, r->left.value_double);
} else {
OUT("%s >= %lldLL", varname, r->left.value);
}
} else if(r->left.type == ARE_VALUE &&
r->right.type == ARE_VALUE &&
r->left.value == r->right.value) {
OUT("%s == %lldLL", varname, r->right.value);
} else if(r->left.type == ARE_DOUBLE &&
r->right.type == ARE_DOUBLE &&
r->left.value_double == r->right.value_double) {
OUT("%s == %LfL", varname, r->right.value_double);
} else {
OUT("%s >= %lldLL", varname, r->left.value);
if (r->left.type == ARE_DOUBLE) {
OUT("%s >= %LfL", varname, r->left.value_double);
} else {
OUT("%s >= %lldLL", varname, r->left.value);
}
OUT(" && ");
OUT("%s <= %lldLL", varname, r->right.value);
if (r->right.type == ARE_DOUBLE) {
OUT("%s <= %LfL", varname, r->right.value_double);
} else {
OUT("%s <= %lldLL", varname, r->right.value);
}
}
if(r != range) OUT(")");
generated_something = 1;
Expand Down
1 change: 1 addition & 0 deletions libasn1fix/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ libasn1fix_la_SOURCES = \
asn1fix_enum.c asn1fix_enum.h \
asn1fix_cws.c asn1fix_cws.h \
asn1fix_constraint_compat.c
libasn1fix_la_LIBADD = -lm

check_fixer_LDADD = $(noinst_LTLIBRARIES) \
$(top_builddir)/libasn1parser/libasn1parser.la
Expand Down
28 changes: 14 additions & 14 deletions libasn1fix/asn1fix_constraint_compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,8 @@ asn1constraint_compatible(asn1p_expr_type_e expr_type,

#define DECL_RANGE(foo, val1, val2, pv) \
static asn1cnst_range_t range_ ## foo = { \
{ ARE_VALUE, 0, val1 }, \
{ ARE_VALUE, 0, val2 }, \
{ ARE_VALUE, 0, val1, 0}, \
{ ARE_VALUE, 0, val2, 0}, \
0, 0, 0, 0, 0, 0, pv }

#define DECL(foo, val1, val2) DECL_RANGE(foo, val1, val2, 0)
Expand Down Expand Up @@ -155,37 +155,37 @@ asn1constraint_default_alphabet(asn1p_expr_type_e expr_type) {
&range_PlusCommaMinusDot, &range_Digits, &range_Z };

static asn1cnst_range_t range_notPERVisible = {
{ ARE_MIN, 0, 0 },
{ ARE_MAX, 0, 0 },
{ ARE_MIN, 0, 0, 0},
{ ARE_MAX, 0, 0, 0},
0, 0, 0, 0, 0, 0, 1 };
static asn1cnst_range_t range_NumericString = {
{ ARE_VALUE, 0, 0x20 },
{ ARE_VALUE, 0, 0x39 },
{ ARE_VALUE, 0, 0x20, 0},
{ ARE_VALUE, 0, 0x39, 0},
range_NumericString_array,
sizeof(range_NumericString_array)
/sizeof(range_NumericString_array[0]),
0, 0, 0, 0, 0 };
static asn1cnst_range_t range_PrintableString = {
{ ARE_VALUE, 0, 0x20 },
{ ARE_VALUE, 0, 0x7a },
{ ARE_VALUE, 0, 0x20, 0},
{ ARE_VALUE, 0, 0x7a, 0},
range_PrintableString_array,
sizeof(range_PrintableString_array)
/sizeof(range_PrintableString_array[0]),
0, 0, 0, 0, 0 };
static asn1cnst_range_t range_VisibleString = {
{ ARE_VALUE, 0, 0x20 },
{ ARE_VALUE, 0, 0x7e },
{ ARE_VALUE, 0, 0x20, 0},
{ ARE_VALUE, 0, 0x7e, 0},
0, 0, 0, 0, 0, 0, 0 };
static asn1cnst_range_t range_UTCTime = {
{ ARE_VALUE, 0, 0x2b },
{ ARE_VALUE, 0, 0x5a },
{ ARE_VALUE, 0, 0x2b, 0},
{ ARE_VALUE, 0, 0x5a, 0},
range_UTCTime_array,
sizeof(range_UTCTime_array)
/sizeof(range_UTCTime_array[0]),
0, 0, 0, 0, 1 };
static asn1cnst_range_t range_GeneralizedTime = {
{ ARE_VALUE, 0, 0x2b },
{ ARE_VALUE, 0, 0x5a },
{ ARE_VALUE, 0, 0x2b, 0},
{ ARE_VALUE, 0, 0x5a, 0},
range_GeneralizedTime_array,
sizeof(range_GeneralizedTime_array)
/sizeof(range_GeneralizedTime_array[0]),
Expand Down
67 changes: 64 additions & 3 deletions libasn1fix/asn1fix_crange.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#include "asn1fix_internal.h"
#include "asn1fix_constraint.h"
#include "asn1fix_crange.h"
#include <float.h>
//#include <math.h>

#undef FATAL
#define FATAL(fmt, args...) do { \
Expand Down Expand Up @@ -109,13 +111,15 @@ _edge_compare(const asn1cnst_edge_t *el, const asn1cnst_edge_t *er) {
case ARE_MIN: return 0;
case ARE_MAX: return -1;
case ARE_VALUE: return -1;
case ARE_DOUBLE: return -1;
}
break;
case ARE_MAX:
switch(er->type) {
case ARE_MIN: return 1;
case ARE_MAX: return 0;
case ARE_VALUE: return 1;
case ARE_DOUBLE: return 1;
}
break;
case ARE_VALUE:
Expand All @@ -128,6 +132,30 @@ _edge_compare(const asn1cnst_edge_t *el, const asn1cnst_edge_t *er) {
if(el->value > er->value)
return 1;
return 0;
case ARE_DOUBLE:
if(el->value < er->value_double)
return -1;
if(el->value > er->value_double)
return 1;
return 0;
}
break;
case ARE_DOUBLE:
switch(er->type) {
case ARE_MIN: return 1;
case ARE_MAX: return -1;
case ARE_VALUE:
if(el->value_double < er->value)
return -1;
if(el->value_double > er->value)
return 1;
return 0;
case ARE_DOUBLE:
if(el->value_double < er->value_double)
return -1;
if(el->value_double > er->value_double)
return 1;
return 0;
}
break;
}
Expand Down Expand Up @@ -159,6 +187,9 @@ _edge_value(const asn1cnst_edge_t *edge) {
case ARE_VALUE:
snprintf(buf, sizeof(buf), "%" PRIdASN, edge->value);
break;
case ARE_DOUBLE:
snprintf(buf, sizeof(buf), "%Lf", edge->value_double);
break;
default:
assert(!"edge->type");
}
Expand Down Expand Up @@ -272,8 +303,8 @@ static int _range_fill(asn1p_value_t *val, const asn1cnst_range_t *minmax, asn1c
asn1p_constraint_type2str(type), lineno);
return -1;
}
edge->type = ARE_VALUE;
edge->value = val->value.v_double;
edge->type = ARE_DOUBLE;
edge->value_double = val->value.v_double;
return 0;
case ATV_MIN:
if(type != ACT_EL_RANGE && type != ACT_CT_SIZE) {
Expand Down Expand Up @@ -461,6 +492,18 @@ _range_split(asn1cnst_range_t *ra, const asn1cnst_range_t *rb) {
break;
}
nr->right.value--;
} else if(nr->right.type == ARE_DOUBLE) {
if(nr->right.value_double == DBL_MIN) {
/* We've hit the limit here. */
break;
}
//nextafter(0.0, DBL_MAX) and nextafter(0.0, DBL_MIN) returns the same result
//and set FE_UNDERFLOW exception
//nr->right.value_double = nextafter(nr->right.value_double, DBL_MIN);
//With DBL_EPSILON it does not work for some reason
const long double temp = nr->right.value_double - FLT_EPSILON;
assert(temp != nr->right.value_double);
nr->right.value_double = temp;
}
_range_insert(range, nr);
nr = _range_new();
Expand All @@ -481,6 +524,18 @@ _range_split(asn1cnst_range_t *ra, const asn1cnst_range_t *rb) {
break;
}
nr->left.value++;
} else if(nr->left.type == ARE_DOUBLE) {
if(nr->left.value_double == DBL_MAX) {
/* We've hit the limit here. */
break;
}
//nextafter(0.0, DBL_MAX) and nextafter(0.0, DBL_MIN) returns the same result
//and set FE_UNDERFLOW exception
//nr->left.value_double = nextafter(nr->left.value_double, DBL_MAX);
//With DBL_EPSILON it does not work for some reason
const long double temp = nr->left.value_double + FLT_EPSILON;
assert(temp != nr->left.value_double);
nr->left.value_double = temp;
}
_range_insert(range, nr);
nr = _range_new();
Expand Down Expand Up @@ -774,9 +829,15 @@ asn1constraint_compute_PER_range(asn1p_expr_type_e expr_type, const asn1p_constr
* X.691, #9.3.6
* Constraints on restricter character string types
* which are not known-multiplier are not PER-visible.
* X.691 (08/2015)
* 10.3.7 Constraints on restricted character string types which are not (see Rec. ITU-T X.680 | ISO/IEC 8824-1, clause
* 41) known-multiplier character string types are not PER-visible (see 3.7.16).
* 10.3.14 Constraints applied to real types are not PER-visible.
*/
if((expr_type & ASN_STRING_NKM_MASK))
if((expr_type & ASN_STRING_NKM_MASK) ||
(expr_type == ASN_BASIC_REAL) ) {
range->not_PER_visible = 1;
}

if(!ct
|| (range->not_PER_visible && (cpr_flags & CPR_strict_PER_visibility)))
Expand Down
2 changes: 2 additions & 0 deletions libasn1fix/asn1fix_crange.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ typedef struct asn1cnst_edge_s {
ARE_MIN,
ARE_MAX,
ARE_VALUE,
ARE_DOUBLE, /* The value is in the value_double member. Used for REAL constraints */
} type;
int lineno; /* Line where the corresponding token was found */
asn1c_integer_t value; /* Value when type is ARE_VALUE */
long double value_double; /* Value when type is ARE_DOUBLE */
} asn1cnst_edge_t;

typedef struct asn1cnst_range_s {
Expand Down
7 changes: 6 additions & 1 deletion libasn1print/asn1print.c
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,10 @@ asn1print_crange_value(asn1cnst_edge_t *edge, int as_char) {
} else {
safe_printf("%" PRIdASN, edge->value);
}
break;
case ARE_DOUBLE:
safe_printf("%Lf", edge->value_double);
break;
}
return 0;
}
Expand Down Expand Up @@ -516,7 +520,8 @@ asn1print_constraint_explain_type(asn1p_expr_type_e expr_type, asn1p_constraint_
}
asn1print_crange_value(&r->left, as_char);
if(r->left.type != r->right.type
|| r->left.value != r->right.value) {
|| r->left.value != r->right.value
|| r->left.value_double != r->right.value_double) {
safe_printf("..");
asn1print_crange_value(&r->right, as_char);
}
Expand Down
1 change: 1 addition & 0 deletions tests/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
50-constraint-OK.asn1.-EFprint-constraints diff
38 changes: 37 additions & 1 deletion tests/50-constraint-OK.asn1
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,43 @@ BEGIN
Enum0 ::= ENUMERATED { one, two }
Enum1 ::= ENUMERATED { one, two } (one)

Real ::= REAL (1.00..21999.00)
SequenceReal ::= SEQUENCE {
real REAL,

real-const0 REAL (0.0),
real-const1 REAL (1.0),
real-const2 REAL (1.05..21999.95),
real-const30 REAL (0.00|0.01),
real-const3 REAL (1.07|1.08),
real-const31 REAL (-1.0..0.00),
real-const4 REAL (0.0..1.0),
real-min REAL (MIN..0.0),
real-max0 REAL (0.0..MAX),
real-max REAL (1.0..MAX),
--real-exp REAL (1.1e3),
--real-bigr REAL (1.0..1.79769313486231470e+308),

real-intc0 REAL (0),
real-intc1 REAL (1),
--real-intc12 REAL (1|2),
real-intc2 REAL (1..21999),
real-intc3 REAL (0..9223372036854775807),
real-intmin REAL (MIN..1),
real-intmax REAL (1..MAX),

real-mix1 REAL (1.50..21999),
real-mix2 REAL (1..21999.99),

real-ext REAL (...),
real-ext1 REAL (1.1..10.00,...),
real-ext2 REAL (1.1..10.00,...,10.01..11.00),
real-ext21 REAL (1.1..10.00,...,10.00..11.00),
real-ext3 REAL (1, ...),
real-ext4 REAL (1.0, ...),
--real-ext5 REAL (1, ..., 2),
real-ext6 REAL (1..2, ..., 3..4),
...
}

END

Expand Down
Binary file modified tests/50-constraint-OK.asn1.-EFprint-constraints
Binary file not shown.
Loading

0 comments on commit 297e492

Please sign in to comment.