Commit a754934a authored by BenceJanosSzabo's avatar BenceJanosSzabo
Browse files

using negations in template ranges is now possible (artf780941)



Change-Id: I37cd2a3836c7c516c8611d991bdb34aeaea17f08
Signed-off-by: default avatarBenceJanosSzabo <bence.janos.szabo@ericsson.com>
parent fdb34e70
......@@ -1641,8 +1641,8 @@ void Type::chk_xer_use_nil()
complaint = NOTHING_TO_ORDER;
else if (the_enum->u.enums.eis->get_nof_eis() != expected_enum_items)
complaint = BAD_ENUM;
else for (size_t i = 0; i < expected_enum_items; ++i) {
CompField *inner_cf = inner->get_comp_byIndex(i);
else for (size_t index = 0; index < expected_enum_items; ++index) {
CompField *inner_cf = inner->get_comp_byIndex(index);
Type *inner_cft = inner_cf->get_type();
if (inner_cft->xerattrib && inner_cft->xerattrib->attribute_) continue;
// Found a non-attribute component. Its name must match an enumval
......@@ -5714,6 +5714,7 @@ bool Type::chk_this_template_Str(Template *t, namedbool implicit_omit,
Ttcn::ValueRange *vr = t->get_value_range();
Value *v_lower = chk_range_boundary(vr->get_min_v(), "lower", *t);
Value *v_upper = chk_range_boundary(vr->get_max_v(), "upper", *t);
vr->set_typetype(get_typetype_ttcn3(typetype));
if (v_lower && v_upper) {
// both boundaries are available and have correct type
if (tt == T_CSTR) {
......@@ -5902,6 +5903,7 @@ void Type::chk_this_template_Int_Real(Template *t)
Ttcn::ValueRange *vr = t->get_value_range();
Value *v_lower = chk_range_boundary(vr->get_min_v(), "lower", *t);
Value *v_upper = chk_range_boundary(vr->get_max_v(), "upper", *t);
vr->set_typetype(get_typetype_ttcn3(typetype));
if (v_lower && v_upper) {
// both boundaries are available and have correct type
switch (get_typetype_ttcn3(typetype)) {
......@@ -5923,6 +5925,12 @@ void Type::chk_this_template_Int_Real(Template *t)
if (!vr->get_min_v() && v_upper) {
chk_range_boundary_infinity(v_upper, false);
}
if (!vr->get_min_v() && vr->is_min_exclusive() && get_typetype_ttcn3(typetype) == T_INT) {
t->error("invalid lower boundary, -infinity cannot be excluded from an integer template range");
}
if (!vr->get_max_v() && vr->is_max_exclusive() && get_typetype_ttcn3(typetype) == T_INT) {
t->error("invalid upper boundary, infinity cannot be excluded from an integer template range");
}
break;}
default:
t->error("%s cannot be used for type `%s'", t->get_templatetype_str(),
......
......@@ -15,6 +15,7 @@
* Raduly, Csaba
* Szabados, Kristof
* Szabo, Janos Zoltan – initial implementation
* Szabo, Bence Janos
* Tatarka, Gabor
*
******************************************************************************/
......@@ -47,6 +48,9 @@ namespace Ttcn {
: Node(other)
, min_v(other.min_v ? other.min_v->clone() : 0)
, max_v(other.max_v ? other.max_v->clone() : 0)
, min_exclusive(other.min_exclusive)
, max_exclusive(other.max_exclusive)
, type(other.type)
{}
void ValueRange::set_fullname(const string& p_fullname)
......@@ -102,6 +106,10 @@ namespace Ttcn {
if (min_v) min_v->set_code_section(p_code_section);
if (max_v) max_v->set_code_section(p_code_section);
}
void ValueRange::set_typetype(Type::typetype_t t) {
type = t;
}
char *ValueRange::generate_code_init(char *str, const char *name)
{
......@@ -112,11 +120,35 @@ namespace Ttcn {
min_v->generate_code_expr(&expr);
init_stmt = mputprintf(init_stmt, "%s.set_min(%s);\n", name, expr.expr);
}
if (min_exclusive) {
switch (type) {
case Type::T_INT:
case Type::T_REAL:
case Type::T_CSTR:
case Type::T_USTR:
init_stmt = mputprintf(init_stmt, "%s.set_min_exclusive(true);\n", name);
break;
default:
FATAL_ERROR("ValueRange::generate_code_init()");
}
}
if (max_v) {
Code::clean_expr(&expr);
max_v->generate_code_expr(&expr);
init_stmt = mputprintf(init_stmt, "%s.set_max(%s);\n", name, expr.expr);
}
if (max_exclusive) {
switch (type) {
case Type::T_INT:
case Type::T_REAL:
case Type::T_CSTR:
case Type::T_USTR:
init_stmt = mputprintf(init_stmt, "%s.set_max_exclusive(true);\n", name);
break;
default:
FATAL_ERROR("ValueRange::generate_code_init()");
}
}
if (expr.preamble || expr.postamble) {
str = mputstr(str, "{\n");
str = mputstr(str, expr.preamble);
......
......@@ -13,6 +13,7 @@
* Kovacs, Ferenc
* Raduly, Csaba
* Szabados, Kristof
* Szabo, Bence Janos
* Szabo, Janos Zoltan – initial implementation
*
******************************************************************************/
......@@ -41,20 +42,27 @@ namespace Ttcn {
private:
Value *min_v;
Value *max_v;
bool min_exclusive;
bool max_exclusive;
Type::typetype_t type;
/// Copy constructor for clone() only
ValueRange(const ValueRange& p);
/// %Assignment disabled
ValueRange& operator=(const ValueRange& p);
public:
ValueRange(Value *p_min_v, Value *p_max_v)
: Node(), min_v(p_min_v), max_v(p_max_v) { }
ValueRange(Value *p_min_v, bool lower_excl, Value *p_max_v, bool upper_excl)
: Node(), min_v(p_min_v), max_v(p_max_v),
min_exclusive(lower_excl), max_exclusive(upper_excl), type() { }
virtual ~ValueRange();
virtual ValueRange* clone() const;
virtual void set_fullname(const string& p_fullname);
virtual void set_my_scope(Scope *p_scope);
Value *get_min_v() const { return min_v; }
Value *get_max_v() const { return max_v; }
void set_typetype(Type::typetype_t t);
bool is_min_exclusive() const { return min_exclusive; }
bool is_max_exclusive() const { return max_exclusive; }
void set_lowerid_to_ref();
Type::typetype_t get_expr_returntype(Type::expected_value_t exp_val);
Type *get_expr_governor(Type::expected_value_t exp_val);
......
......@@ -3664,7 +3664,13 @@ IfPresentMatch: // 144
Range: // 147
'(' SingleLowerBound DotDot UpperBound optError ')'
{ $$ = new ValueRange($2, $4); }
{ $$ = new ValueRange($2, false, $4, false); }
| '(' '!' SingleLowerBound DotDot UpperBound optError ')'
{ $$ = new ValueRange($3, true, $5, false); }
| '(' SingleLowerBound DotDot '!' UpperBound optError ')'
{ $$ = new ValueRange($2, false, $5, true); }
| '(' '!' SingleLowerBound DotDot '!' UpperBound optError ')'
{ $$ = new ValueRange($3, true, $6, true); }
;
SingleLowerBound:
......@@ -7327,7 +7333,7 @@ CharStringValue: // 478
{
$$ = new Value(Value::V_USTR, new ustring($1.elements, $1.nElements));
for(size_t i = 0; i < $1.nElements; ++i) {
Free((char*)$1.elements[i]);
Free(const_cast<char*>($1.elements[i]));
}
Free($1.elements);
$$->set_location(infile, @$);
......
......@@ -40,6 +40,7 @@
#include "XER.hh"
#include "JSON.hh"
#include "Addfunc.hh"
#include "Optional.hh"
#include "../common/dbgnew.hh"
......@@ -1736,7 +1737,7 @@ int CHARSTRING::JSON_decode(const TTCN_Typedescriptor_t& p_td, JSON_Tokenizer& p
boolean use_default = p_td.json->default_value && 0 == p_tok.get_buffer_length();
if (use_default) {
// No JSON data in the buffer -> use default value
value = (char*)p_td.json->default_value;
value = const_cast<char*>(p_td.json->default_value);
value_len = strlen(value);
} else {
dec_len = p_tok.get_next_token(&token, &value, &value_len);
......@@ -2304,9 +2305,13 @@ boolean CHARSTRING_template::match(const CHARSTRING& other_value,
"(\"%c\") when matching with a charstring value range template.",
value_range.min_value, value_range.max_value);
const char *chars_ptr = other_value;
int min_value_offset = 0;
int max_value_offset = 0;
if (value_range.min_is_exclusive) min_value_offset = 1;
if (value_range.max_is_exclusive) max_value_offset = 1;
for (int i = 0; i < value_length; i++) {
if (chars_ptr[i] < value_range.min_value ||
chars_ptr[i] > value_range.max_value) return FALSE;
if (chars_ptr[i] < (value_range.min_value + min_value_offset) ||
chars_ptr[i] > (value_range.max_value - max_value_offset)) return FALSE;
}
return TRUE;
break; }
......@@ -2401,6 +2406,8 @@ void CHARSTRING_template::set_type(template_sel template_type,
set_selection(VALUE_RANGE);
value_range.min_is_set = FALSE;
value_range.max_is_set = FALSE;
value_range.min_is_exclusive = FALSE;
value_range.max_is_exclusive = FALSE;
break;
case DECODE_MATCH:
set_selection(DECODE_MATCH);
......@@ -2432,6 +2439,7 @@ void CHARSTRING_template::set_min(const CHARSTRING& min_value)
if (length != 1) TTCN_error("The length of the lower bound in a "
"charstring value range template must be 1 instead of %d.", length);
value_range.min_is_set = TRUE;
value_range.min_is_exclusive = FALSE;
value_range.min_value = *(const char*)min_value;
if (value_range.max_is_set && value_range.min_value > value_range.max_value)
TTCN_error("The lower bound (\"%c\") in a charstring value range template "
......@@ -2449,6 +2457,7 @@ void CHARSTRING_template::set_max(const CHARSTRING& max_value)
if (length != 1) TTCN_error("The length of the upper bound in a "
"charstring value range template must be 1 instead of %d.", length);
value_range.max_is_set = TRUE;
value_range.max_is_exclusive = FALSE;
value_range.max_value = *(const char*)max_value;
if (value_range.min_is_set && value_range.min_value > value_range.max_value)
TTCN_error("The upper bound (\"%c\") in a charstring value range template "
......@@ -2456,6 +2465,20 @@ void CHARSTRING_template::set_max(const CHARSTRING& max_value)
value_range.min_value);
}
void CHARSTRING_template::set_min_exclusive(boolean min_exclusive)
{
if (template_selection != VALUE_RANGE)
TTCN_error("Setting the lower bound for a non-range charstring template.");
value_range.min_is_exclusive = min_exclusive;
}
void CHARSTRING_template::set_max_exclusive(boolean max_exclusive)
{
if (template_selection != VALUE_RANGE)
TTCN_error("Setting the upper bound for a non-range charstring template.");
value_range.max_is_exclusive = max_exclusive;
}
void CHARSTRING_template::set_decmatch(Dec_Match_Interface* new_instance)
{
if (template_selection != DECODE_MATCH) {
......@@ -2639,6 +2662,7 @@ void CHARSTRING_template::log() const
break;
case VALUE_RANGE:
TTCN_Logger::log_char('(');
if (value_range.min_is_exclusive) TTCN_Logger::log_char('!');
if (value_range.min_is_set) {
if (TTCN_Logger::is_printable(value_range.min_value)) {
TTCN_Logger::log_char('"');
......@@ -2648,6 +2672,7 @@ void CHARSTRING_template::log() const
(unsigned char)value_range.min_value);
} else TTCN_Logger::log_event_str("<unknown lower bound>");
TTCN_Logger::log_event_str(" .. ");
if (value_range.max_is_exclusive) TTCN_Logger::log_char('!');
if (value_range.max_is_set) {
if (TTCN_Logger::is_printable(value_range.max_value)) {
TTCN_Logger::log_char('"');
......@@ -2726,6 +2751,8 @@ void CHARSTRING_template::set_param(Module_Param& param) {
value_range.max_is_set = TRUE;
value_range.min_value = (char)(lower_uchar.uc_cell);
value_range.max_value = (char)(upper_uchar.uc_cell);
set_min_exclusive(mp->get_is_min_exclusive());
set_max_exclusive(mp->get_is_max_exclusive());
} break;
case Module_Param::MP_Pattern:
clean_up();
......@@ -2805,7 +2832,7 @@ Module_Param* CHARSTRING_template::get_param(Module_Param_Name& param_name) cons
case VALUE_RANGE: {
universal_char lower_bound = { 0, 0, 0, (unsigned char)value_range.min_value };
universal_char upper_bound = { 0, 0, 0, (unsigned char)value_range.max_value };
mp = new Module_Param_StringRange(lower_bound, upper_bound);
mp = new Module_Param_StringRange(lower_bound, upper_bound, value_range.min_is_exclusive, value_range.max_is_exclusive);
break; }
case STRING_PATTERN:
mp = new Module_Param_Pattern(mcopystr(single_value), pattern_value.nocase);
......@@ -2889,6 +2916,8 @@ void CHARSTRING_template::decode_text(Text_Buf& text_buf)
"upper bound in a charstring value range template.");
value_range.min_is_set = TRUE;
value_range.max_is_set = TRUE;
value_range.min_is_exclusive = FALSE;
value_range.max_is_exclusive = FALSE;
break;
default:
TTCN_error("Text decoder: An unknown/unsupported selection was "
......
......@@ -31,7 +31,7 @@
#include "Types.h"
#include "Basetype.hh"
#include "Template.hh"
#include "Optional.hh"
#include "Param_Types.hh"
class INTEGER;
class BITSTRING;
......@@ -43,6 +43,9 @@ class UNIVERSAL_CHARSTRING_ELEMENT;
class Module_Param;
template<typename T>
class OPTIONAL;
/** Runtime class for character strings.
*
* Memory is reserved for the terminating null character
......@@ -364,6 +367,7 @@ private:
} value_list;
struct {
boolean min_is_set, max_is_set;
boolean min_is_exclusive, max_is_exclusive;
char min_value, max_value;
} value_range;
mutable struct {
......@@ -432,6 +436,8 @@ public:
void set_min(const CHARSTRING& min_value);
void set_max(const CHARSTRING& max_value);
void set_min_exclusive(boolean min_exclusive);
void set_max_exclusive(boolean max_exclusive);
void set_decmatch(Dec_Match_Interface* new_instance);
......
......@@ -975,7 +975,7 @@ tagless:
if (value) {
if (is_float(value)) {
if (exer && (p_td.xer_bits & XER_DECIMAL) && p_td.fractionDigits != -1) {
char *p = strchr((char*)value, '.');
const char *p = strchr(value, '.');
if (p != NULL) {
unsigned int fraction_digits_pos = (int)(p - value) + 1 + p_td.fractionDigits;
if (fraction_digits_pos < strlen(value)) {
......@@ -1029,7 +1029,7 @@ tagless:
if (value) {
if (is_float(value)) {
if (exer && (p_td.xer_bits & XER_DECIMAL) && p_td.fractionDigits != -1) {
char *p = strchr((char*)value, '.');
const char *p = strchr(value, '.');
if (p != NULL) {
unsigned int fraction_digits_pos = (int)(p - value) + 1 + p_td.fractionDigits;
if (fraction_digits_pos < strlen(value)) {
......@@ -1115,7 +1115,7 @@ int FLOAT::JSON_decode(const TTCN_Typedescriptor_t& p_td, JSON_Tokenizer& p_tok,
boolean use_default = p_td.json->default_value && 0 == p_tok.get_buffer_length();
if (use_default) {
// No JSON data in the buffer -> use default value
value = (char*)p_td.json->default_value;
value = const_cast<char*>(p_td.json->default_value);
value_len = strlen(value);
} else {
dec_len = p_tok.get_next_token(&token, &value, &value_len);
......@@ -1379,10 +1379,21 @@ boolean FLOAT_template::match(double other_value, boolean /* legacy */) const
return template_selection == VALUE_LIST;
return template_selection == COMPLEMENTED_LIST;
case VALUE_RANGE:
return (!value_range.min_is_present ||
value_range.min_value <= other_value) &&
(!value_range.max_is_present ||
value_range.max_value >= other_value);
return (
// Min boundary is -infinity and (not min exclusive or the value is larger than -infinity)
(!value_range.min_is_present && (!value_range.min_is_exclusive || other_value != MINUS_INFINITY)) ||
// Min boundary is a number and not min exclusive and it is less or equal than the value or
(value_range.min_is_present && !value_range.min_is_exclusive && value_range.min_value <= other_value) ||
// Min boundary is a number and min exclusive and it is less than the value
(value_range.min_is_present && value_range.min_is_exclusive && value_range.min_value < other_value))
&&
// Max boundary is infinity and (not min exclusive or the value is smaller than infinity)
((!value_range.max_is_present && (!value_range.max_is_exclusive || other_value != PLUS_INFINITY)) ||
// Max boundary is a number and not max exclusive and it is more or equal than the value or
(value_range.max_is_present && !value_range.max_is_exclusive && value_range.max_value >= other_value) ||
// Max boundary is a number and max exclusive and it is more than the value
(value_range.max_is_present && value_range.max_is_exclusive && value_range.max_value > other_value));
default:
TTCN_error("Matching with an uninitialized/unsupported float template.");
}
......@@ -1411,6 +1422,8 @@ void FLOAT_template::set_type(template_sel template_type,
set_selection(VALUE_RANGE);
value_range.min_is_present = FALSE;
value_range.max_is_present = FALSE;
value_range.min_is_exclusive = FALSE;
value_range.max_is_exclusive = FALSE;
break;
default:
TTCN_error("Setting an invalid type for a float template.");
......@@ -1435,6 +1448,7 @@ void FLOAT_template::set_min(double min_value)
TTCN_error("The lower limit of the range is greater than the "
"upper limit in a float template.");
value_range.min_is_present = TRUE;
value_range.min_is_exclusive = FALSE;
value_range.min_value = min_value;
}
......@@ -1453,6 +1467,7 @@ void FLOAT_template::set_max(double max_value)
TTCN_error("The upper limit of the range is smaller than the "
"lower limit in a float template.");
value_range.max_is_present = TRUE;
value_range.max_is_exclusive = FALSE;
value_range.max_value = max_value;
}
......@@ -1463,6 +1478,20 @@ void FLOAT_template::set_max(const FLOAT& max_value)
set_max(max_value.float_value);
}
void FLOAT_template::set_min_exclusive(boolean min_exclusive)
{
if (template_selection != VALUE_RANGE)
TTCN_error("Float template is not range when setting lower limit exclusiveness.");
value_range.min_is_exclusive = min_exclusive;
}
void FLOAT_template::set_max_exclusive(boolean max_exclusive)
{
if (template_selection != VALUE_RANGE)
TTCN_error("Float template is not range when setting upper limit exclusiveness.");
value_range.max_is_exclusive = max_exclusive;
}
double FLOAT_template::valueof() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent)
......@@ -1490,9 +1519,11 @@ void FLOAT_template::log() const
break;
case VALUE_RANGE:
TTCN_Logger::log_char('(');
if (value_range.min_is_exclusive) TTCN_Logger::log_char('!');
if (value_range.min_is_present) log_float(value_range.min_value);
else TTCN_Logger::log_event_str("-infinity");
TTCN_Logger::log_event_str(" .. ");
if (value_range.max_is_exclusive) TTCN_Logger::log_char('!');
if (value_range.max_is_present) log_float(value_range.max_value);
else TTCN_Logger::log_event_str("infinity");
TTCN_Logger::log_char(')');
......@@ -1554,6 +1585,8 @@ void FLOAT_template::set_param(Module_Param& param) {
set_type(VALUE_RANGE);
if (mp->has_lower_float()) set_min(mp->get_lower_float());
if (mp->has_upper_float()) set_max(mp->get_upper_float());
set_min_exclusive(mp->get_is_min_exclusive());
set_max_exclusive(mp->get_is_max_exclusive());
break;
case Module_Param::MP_Expression:
switch (mp->get_expr_type()) {
......@@ -1635,7 +1668,7 @@ Module_Param* FLOAT_template::get_param(Module_Param_Name& param_name) const
case VALUE_RANGE:
mp = new Module_Param_FloatRange(
value_range.min_value, value_range.min_is_present,
value_range.max_value, value_range.max_is_present);
value_range.max_value, value_range.max_is_present, value_range.min_is_exclusive, value_range.max_is_exclusive);
break;
default:
break;
......@@ -1704,6 +1737,8 @@ void FLOAT_template::decode_text(Text_Buf& text_buf)
value_range.max_is_present = text_buf.pull_int() != 0;
if (value_range.max_is_present)
value_range.max_value = text_buf.pull_double();
value_range.min_is_exclusive = FALSE;
value_range.max_is_exclusive = FALSE;
break;
default:
TTCN_error("Text decoder: An unknown/unsupported selection was "
......
......@@ -24,12 +24,14 @@
#include "Basetype.hh"
#include "Template.hh"
#include "Optional.hh"
#include "Error.hh"
#include "ttcn3float.hh"
class Module_Param;
template<typename T>
class OPTIONAL;
// float value class
class FLOAT : public Base_Type {
......@@ -198,6 +200,7 @@ private:
struct {
double min_value, max_value;
boolean min_is_present, max_is_present;
boolean min_is_exclusive, max_is_exclusive;
} value_range;
};
......@@ -230,6 +233,8 @@ public:
void set_min(const FLOAT& min_value);
void set_max(double max_value);
void set_max(const FLOAT& max_value);
void set_min_exclusive(boolean min_exclusive);
void set_max_exclusive(boolean max_exclusive);
double valueof() const;
......
......@@ -1742,7 +1742,7 @@ int INTEGER::JSON_decode(const TTCN_Typedescriptor_t& p_td, JSON_Tokenizer& p_to
boolean use_default = p_td.json->default_value && 0 == p_tok.get_buffer_length();
if (use_default) {
// No JSON data in the buffer -> use default value
value = (char*)p_td.json->default_value;
value = const_cast<char*>(p_td.json->default_value);
value_len = strlen(value);
} else {
dec_len = p_tok.get_next_token(&token, &value, &value_len);
......@@ -1930,6 +1930,7 @@ void INTEGER_template::copy_template(const INTEGER_template& other_value)
break;
case VALUE_RANGE:
value_range.min_is_present = other_value.value_range.min_is_present;
value_range.min_is_exclusive = other_value.value_range.min_is_exclusive;
if (value_range.min_is_present) {
value_range.min_value.native_flag = other_value.value_range.min_value.native_flag;
if (likely(value_range.min_value.native_flag))
......@@ -1940,6 +1941,7 @@ void INTEGER_template::copy_template(const INTEGER_template& other_value)
BN_dup(other_value.value_range.min_value.val.openssl);
}
value_range.max_is_present = other_value.value_range.max_is_present;
value_range.max_is_exclusive = other_value.value_range.max_is_exclusive;
if (value_range.max_is_present) {
value_range.max_value.native_flag = other_value.value_range.max_value.native_flag;
if (likely(value_range.max_value.native_flag))
......@@ -2101,15 +2103,27 @@ boolean INTEGER_template::match(int other_value, boolean /* legacy */) const
boolean upper_boundary = !value_range.max_is_present;
// Lower boundary is set.
if (!lower_boundary) {
lower_boundary = (likely(value_range.min_value.native_flag) ?
if (!value_range.min_is_exclusive) {
lower_boundary = (likely(value_range.min_value.native_flag) ?
int_val_t(value_range.min_value.val.native) :
int_val_t(BN_dup(value_range.min_value.val.openssl))) <= other_value;
} else {
lower_boundary = (likely(value_range.min_value.native_flag) ?
int_val_t(value_range.min_value.val.native) :
int_val_t(BN_dup(value_range.min_value.val.openssl))) <= other_value;
int_val_t(BN_dup(value_range.min_value.val.openssl))) < other_value;
}
}
// Upper boundary is set.
if (!upper_boundary) {
upper_boundary = (likely(value_range.max_value.native_flag) ?
if (!value_range.max_is_exclusive) {
upper_boundary = (likely(value_range.max_value.native_flag) ?
int_val_t(value_range.max_value.val.native) :
int_val_t(BN_dup(value_range.max_value.val.openssl))) >= other_value;
} else {
upper_boundary = (likely(value_range.max_value.native_flag) ?
int_val_t(value_range.max_value.val.native) :
int_val_t(BN_dup(value_range.max_value.val.openssl))) >= other_value;
int_val_t(BN_dup(value_range.max_value.val.openssl))) > other_value;
}
}
return lower_boundary && upper_boundary; }
default:
......@@ -2144,15 +2158,27 @@ boolean INTEGER_template::match(const INTEGER& other_value,
boolean upper_boundary = !value_range.max_is_present;
// Lower boundary is set.
if (!lower_boundary) {
lower_boundary = (likely(value_range.min_value.native_flag) ?
int_val_t(value_range.min_value.val.native) :
int_val_t(BN_dup(value_range.min_value.val.openssl))) <= other_value.get_val();
if (!value_range.min_is_exclusive) {
lower_boundary = (likely(value_range.min_value.native_flag) ?
int_val_t(value_range.min_value.val.native) :
int_val_t(BN_dup(value_range.min_value.val.openssl))) <= other_value.get_val();
} else {
lower_boundary = (likely(value_range.min_value.native_flag) ?
int_val_t(value_range.min_value.val.native) :
int_val_t(BN_dup(value_range.min_value.val.openssl))) < other_value.get_val();
}
}
// Upper boundary is set.
if (!upper_boundary) {
if (value_range.max_is_exclusive) {
upper_boundary = (likely(value_range.max_value.native_flag) ?
int_val_t(value_range.max_value.val.native) :
int_val_t(BN_dup(value_range.max_value.val.openssl))) >= other_value.get_val();
int_val_t(BN_dup(value_range.max_value.val.openssl))) > other_value.get_val();
} else {
upper_boundary = (likely(value_range.max_value.native_flag) ?
int_val_t(value_range.max_value.val.native) :
int_val_t(BN_dup(value_range.max_value.val.openssl))) >= other_value.get_val();
}
}
return lower_boundary && upper_boundary; }
default:
......@@ -2186,6 +2212,8 @@ void INTEGER_template::set_type(template_sel template_type,
set_selection(VALUE_RANGE);
value_range.min_is_present = FALSE;
value_range.max_is_present = FALSE;
value_range.min_is_exclusive = FALSE;
value_range.max_is_exclusive = FALSE;
break;
default:
TTCN_error("Setting an invalid type for an integer template.");
......@@ -2215,6 +2243,7 @@ void INTEGER_template::set_min(int min_value)
"limit in an integer template.");
}
value_range.min_is_present = TRUE;
value_range.min_is_exclusive = FALSE;
value_range.min_value.native_flag = TRUE;
value_range.min_value.val.native = min_value;
}
......@@ -2236,6 +2265,7 @@ void INTEGER_template::set_min(const INTEGER& min_value)
"limit in an integer template.");
}
value_range.min_is_present = TRUE;
value_range.min_is_exclusive = FALSE;
value_range.min_value.native_flag = min_value_int.native_flag;
if (likely(value_range.min_value.native_flag))
value_range.min_value.val.native = min_value_int.val.native;
......@@ -2255,10 +2285,25 @@ void INTEGER_template::set_max(int max_value)
"limit in an integer template.");
}
value_range.max_is_present = TRUE;
value_range.max_is_exclusive = FALSE;
value_range.max_value.native_flag = TRUE;
value_range.max_value.val.native = max_value;
}
void INTEGER_template::set_min_exclusive(boolean min_exclusive)
{
if (template_selection != VALUE_RANGE)
TTCN_error("Integer template is not range when setting lower limit exclusiveness.");
value_range.min_is_exclusive = min_exclusive;
}