Commit feade998 authored by Elemer Lelik's avatar Elemer Lelik
Browse files

Sync with 5.4.3

parent 2b4bcb7a
...@@ -256,7 +256,7 @@ extern int add_include_file(const std::string& filename) ...@@ -256,7 +256,7 @@ extern int add_include_file(const std::string& filename)
expstring_t currdirname, dirname, filenamepart, basedir; expstring_t currdirname, dirname, filenamepart, basedir;
currdirname = get_dir_from_path(get_cfg_preproc_current_file().c_str()); currdirname = get_dir_from_path(get_cfg_preproc_current_file().c_str());
dirname = get_dir_from_path(filename.c_str()); dirname = get_dir_from_path(filename.c_str());
basedir = get_absolute_dir(dirname, currdirname); basedir = get_absolute_dir(dirname, currdirname, 1);
Free(currdirname); Free(currdirname);
Free(dirname); Free(dirname);
filenamepart = get_file_from_path(filename.c_str()); filenamepart = get_file_from_path(filename.c_str());
...@@ -294,7 +294,7 @@ extern int preproc_parse_file(const char *filename, string_chain_t **filenames, ...@@ -294,7 +294,7 @@ extern int preproc_parse_file(const char *filename, string_chain_t **filenames,
config_preproc_defines=string_map_new(); config_preproc_defines=string_map_new();
{ {
expstring_t dirname=get_dir_from_path(filename); expstring_t dirname=get_dir_from_path(filename);
expstring_t basedir=get_absolute_dir(dirname, NULL); expstring_t basedir=get_absolute_dir(dirname, NULL, 1);
expstring_t filenamepart=get_file_from_path(filename); expstring_t filenamepart=get_file_from_path(filename);
Free(dirname); Free(dirname);
if (basedir == NULL) { if (basedir == NULL) {
......
...@@ -129,7 +129,7 @@ expstring_t compose_path_name(const char *dir_name, ...@@ -129,7 +129,7 @@ expstring_t compose_path_name(const char *dir_name,
} else return mcopystr(file_name); } else return mcopystr(file_name);
} }
expstring_t get_absolute_dir(const char *dir_name, const char *base_dir) expstring_t get_absolute_dir(const char *dir_name, const char *base_dir, const int with_error)
{ {
expstring_t ret_val; expstring_t ret_val;
/* save the working directory */ /* save the working directory */
...@@ -142,12 +142,18 @@ expstring_t get_absolute_dir(const char *dir_name, const char *base_dir) ...@@ -142,12 +142,18 @@ expstring_t get_absolute_dir(const char *dir_name, const char *base_dir)
return NULL; return NULL;
} }
} }
if (dir_name != NULL && set_working_dir(dir_name)) { if (dir_name != NULL && with_error && set_working_dir(dir_name)) {
/* there was an error: go back to initial_dir */ /* there was an error: go back to initial_dir */
set_working_dir(initial_dir); set_working_dir(initial_dir);
Free(initial_dir); Free(initial_dir);
return NULL; return NULL;
} }
if (dir_name != NULL && !with_error && chdir(dir_name)) {
//No error sign
errno = 0;
Free(initial_dir);
return NULL;
}
ret_val = get_working_dir(); ret_val = get_working_dir();
/* restore the working directory */ /* restore the working directory */
set_working_dir(initial_dir); set_working_dir(initial_dir);
...@@ -174,9 +180,9 @@ expstring_t get_relative_dir(const char *dir_name, const char *base_dir) ...@@ -174,9 +180,9 @@ expstring_t get_relative_dir(const char *dir_name, const char *base_dir)
{ {
expstring_t ret_val = NULL; expstring_t ret_val = NULL;
/* canonize dir_name and the base directory */ /* canonize dir_name and the base directory */
expstring_t canonized_dir_name = get_absolute_dir(dir_name, base_dir); expstring_t canonized_dir_name = get_absolute_dir(dir_name, base_dir, 1);
expstring_t canonized_base_dir = base_dir != NULL ? expstring_t canonized_base_dir = base_dir != NULL ?
get_absolute_dir(base_dir, NULL) : get_working_dir(); get_absolute_dir(base_dir, NULL, 1) : get_working_dir();
size_t i, last_slash = 0; size_t i, last_slash = 0;
if (canonized_dir_name == NULL || canonized_base_dir == NULL) { if (canonized_dir_name == NULL || canonized_base_dir == NULL) {
/* an error occurred */ /* an error occurred */
......
...@@ -68,8 +68,10 @@ extern expstring_t compose_path_name(const char *dir_name, ...@@ -68,8 +68,10 @@ extern expstring_t compose_path_name(const char *dir_name,
* (i.e. symlinks in it are resolved). NULL pointer returned in case of error. * (i.e. symlinks in it are resolved). NULL pointer returned in case of error.
* The string returned shall be deallocated by the caller using \a Free(). * The string returned shall be deallocated by the caller using \a Free().
* Note: The working directory of the current process might change during the * Note: The working directory of the current process might change during the
* function call, but it is restored before the function returns. */ * function call, but it is restored before the function returns.
extern expstring_t get_absolute_dir(const char *dir_name, const char *base_dir); * If the with_error is true, then it won't sign error when set_working_dir
* is called.*/
extern expstring_t get_absolute_dir(const char *dir_name, const char *base_dir, const int with_error);
/** Converts \a dir_name to a relative path name based on \a working_dir. If /** Converts \a dir_name to a relative path name based on \a working_dir. If
* \a working_dir is NULL the current working directory of the process is used. * \a working_dir is NULL the current working directory of the process is used.
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
/* Version numbers */ /* Version numbers */
#define TTCN3_MAJOR 5 #define TTCN3_MAJOR 5
#define TTCN3_MINOR 4 #define TTCN3_MINOR 4
#define TTCN3_PATCHLEVEL 2 #define TTCN3_PATCHLEVEL 3
//#define TTCN3_BUILDNUMBER 0 //#define TTCN3_BUILDNUMBER 0
/* The aggregated version number must be set manually since some stupid /* The aggregated version number must be set manually since some stupid
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
* TTCN3_VERSION = TTCN3_MAJOR * 1000000 + TTCN3_MINOR * 10000 + * TTCN3_VERSION = TTCN3_MAJOR * 1000000 + TTCN3_MINOR * 10000 +
* TTCN3_PATCHLEVEL * 100 + TTCN3_BUILDNUMBER * TTCN3_PATCHLEVEL * 100 + TTCN3_BUILDNUMBER
*/ */
#define TTCN3_VERSION 50402 #define TTCN3_VERSION 50403
/* A monotonically increasing version number. /* A monotonically increasing version number.
* An official release is deemed to have the highest possible build number (99) * An official release is deemed to have the highest possible build number (99)
......
...@@ -1610,6 +1610,9 @@ namespace Common { ...@@ -1610,6 +1610,9 @@ namespace Common {
case T_SET_T: case T_SET_T:
case T_ANYTYPE: case T_ANYTYPE:
break; break;
case T_COMPONENT:
ref->error("Referencing fields of a component is not allowed");
return 0;
default: default:
ref->error("Invalid field reference `%s': type `%s' " ref->error("Invalid field reference `%s': type `%s' "
"does not have fields", id.get_dispname().c_str(), "does not have fields", id.get_dispname().c_str(),
...@@ -2777,11 +2780,14 @@ namespace Common { ...@@ -2777,11 +2780,14 @@ namespace Common {
comp_type->jsonattrib->metainfo_unbound = true; comp_type->jsonattrib->metainfo_unbound = true;
} }
} }
else if (NULL == parent || (T_SEQ_T != parent->typetype && else if (T_SEQOF != get_type_refd_last()->typetype &&
T_SET_T != parent->typetype)) { T_SETOF != get_type_refd_last()->typetype &&
// only allowed if it's a field of a record/set T_ARRAY != get_type_refd_last()->typetype &&
(NULL == parent || (T_SEQ_T != parent->typetype &&
T_SET_T != parent->typetype))) {
// only allowed if it's an array type or a field of a record/set
error("Invalid attribute 'metainfo for unbound', requires record, set, " error("Invalid attribute 'metainfo for unbound', requires record, set, "
"or field of a record or set"); "record of, set of, array or field of a record or set");
} }
} }
} }
......
...@@ -395,6 +395,7 @@ void Type::parse_attributes() ...@@ -395,6 +395,7 @@ void Type::parse_attributes()
case T_SEQ_T: case T_SEQ_T:
case T_SET_T: case T_SET_T:
case T_ANYTYPE: case T_ANYTYPE:
case T_ARRAY:
if(rawattrib==NULL) {rawattrib= new RawAST; new_raw=true;} if(rawattrib==NULL) {rawattrib= new RawAST; new_raw=true;}
if(textattrib==NULL){textattrib= new TextAST; new_text=true;} if(textattrib==NULL){textattrib= new TextAST; new_text=true;}
if(xerattrib==NULL) {xerattrib = new XerAttributes; new_xer = true;} if(xerattrib==NULL) {xerattrib = new XerAttributes; new_xer = true;}
...@@ -459,7 +460,8 @@ void Type::parse_attributes() ...@@ -459,7 +460,8 @@ void Type::parse_attributes()
// This should be bool, but gcc 4.1.2-sol8 generates incorrect code // This should be bool, but gcc 4.1.2-sol8 generates incorrect code
// with -O2 :( // with -O2 :(
const int se_of = (typetype == T_SEQOF || typetype == T_SETOF); const int se_of = (typetype == T_SEQOF || typetype == T_SETOF ||
typetype == T_ARRAY);
const size_t nof_comps = se_of ? 1 : get_nof_comps(); const size_t nof_comps = se_of ? 1 : get_nof_comps();
// Distribute the attributes with qualifiers to the components. // Distribute the attributes with qualifiers to the components.
...@@ -4070,6 +4072,9 @@ bool Type::chk_this_value_Choice(Value *value, Common::Assignment *lhs, ...@@ -4070,6 +4072,9 @@ bool Type::chk_this_value_Choice(Value *value, Common::Assignment *lhs,
alt_type->chk_this_value_ref(alt_value); alt_type->chk_this_value_ref(alt_value);
self_ref |= alt_type->chk_this_value(alt_value, lhs, expected_value, self_ref |= alt_type->chk_this_value(alt_value, lhs, expected_value,
incomplete_allowed, OMIT_NOT_ALLOWED, SUB_CHK, implicit_omit); incomplete_allowed, OMIT_NOT_ALLOWED, SUB_CHK, implicit_omit);
if (alt_value->get_valuetype() == Value::V_NOTUSED) {
value->set_valuetype(Value::V_NOTUSED);
}
break;} break;}
default: default:
value->error("%s value was expected for type `%s'", value->error("%s value was expected for type `%s'",
...@@ -4159,6 +4164,7 @@ bool Type::chk_this_value_Seq_T(Value *value, Common::Assignment *lhs, expected_ ...@@ -4159,6 +4164,7 @@ bool Type::chk_this_value_Seq_T(Value *value, Common::Assignment *lhs, expected_
CompField *last_cf = 0; CompField *last_cf = 0;
size_t next_index = 0; size_t next_index = 0;
size_t seq_index = 0; size_t seq_index = 0;
bool is_empty = n_type_comps > 0; // don't do this check if the record type has no fields
for (size_t v_i = 0; v_i < n_value_comps; v_i++, seq_index++) { for (size_t v_i = 0; v_i < n_value_comps; v_i++, seq_index++) {
NamedValue *nv = value->get_se_comp_byIndex(v_i); NamedValue *nv = value->get_se_comp_byIndex(v_i);
const Identifier& value_id = nv->get_name(); const Identifier& value_id = nv->get_name();
...@@ -4226,8 +4232,16 @@ bool Type::chk_this_value_Seq_T(Value *value, Common::Assignment *lhs, expected_ ...@@ -4226,8 +4232,16 @@ bool Type::chk_this_value_Seq_T(Value *value, Common::Assignment *lhs, expected_
type->chk_this_value_ref(comp_value); type->chk_this_value_ref(comp_value);
self_ref |= type->chk_this_value(comp_value, lhs, expected_value, incomplete_allowed, self_ref |= type->chk_this_value(comp_value, lhs, expected_value, incomplete_allowed,
cf->get_is_optional() ? OMIT_ALLOWED : OMIT_NOT_ALLOWED, SUB_CHK, implicit_omit); cf->get_is_optional() ? OMIT_ALLOWED : OMIT_NOT_ALLOWED, SUB_CHK, implicit_omit);
if (comp_value->get_valuetype() != Value::V_NOTUSED) {
is_empty = false;
}
}
if (is_empty) {
// all of the record's fields are unused (-), set the record to unused
// to avoid unnecessary code generation
value->set_valuetype(Value::V_NOTUSED);
} }
if (!incomplete_allowed || implicit_omit) { else if (!incomplete_allowed || implicit_omit) {
for (size_t i = 0; i < n_type_comps; i++) { for (size_t i = 0; i < n_type_comps; i++) {
const Identifier& id = get_comp_byIndex(i)->get_name(); const Identifier& id = get_comp_byIndex(i)->get_name();
if (!comp_map.has_key(id.get_name())) { if (!comp_map.has_key(id.get_name())) {
...@@ -4251,6 +4265,7 @@ bool Type::chk_this_value_Set_T(Value *value, Common::Assignment *lhs, expected_ ...@@ -4251,6 +4265,7 @@ bool Type::chk_this_value_Set_T(Value *value, Common::Assignment *lhs, expected_
map<string, NamedValue> comp_map; map<string, NamedValue> comp_map;
size_t n_type_comps = get_nof_comps(); size_t n_type_comps = get_nof_comps();
size_t n_value_comps = value->get_nof_comps(); size_t n_value_comps = value->get_nof_comps();
bool is_empty = n_type_comps > 0; // don't do this check if the set type has no fields
for(size_t v_i = 0; v_i < n_value_comps; v_i++) { for(size_t v_i = 0; v_i < n_value_comps; v_i++) {
NamedValue *nv = value->get_se_comp_byIndex(v_i); NamedValue *nv = value->get_se_comp_byIndex(v_i);
const Identifier& value_id = nv->get_name(); const Identifier& value_id = nv->get_name();
...@@ -4282,8 +4297,16 @@ bool Type::chk_this_value_Set_T(Value *value, Common::Assignment *lhs, expected_ ...@@ -4282,8 +4297,16 @@ bool Type::chk_this_value_Set_T(Value *value, Common::Assignment *lhs, expected_
type->chk_this_value_ref(comp_value); type->chk_this_value_ref(comp_value);
self_ref |= type->chk_this_value(comp_value, lhs, expected_value, incomplete_allowed, self_ref |= type->chk_this_value(comp_value, lhs, expected_value, incomplete_allowed,
cf->get_is_optional() ? OMIT_ALLOWED : OMIT_NOT_ALLOWED, SUB_CHK, implicit_omit); cf->get_is_optional() ? OMIT_ALLOWED : OMIT_NOT_ALLOWED, SUB_CHK, implicit_omit);
if (comp_value->get_valuetype() != Value::V_NOTUSED) {
is_empty = false;
}
}
if (is_empty) {
// all of the set's fields are unused (-), set the set to unused to avoid
// unnecessary code generation
value->set_valuetype(Value::V_NOTUSED);
} }
if (!incomplete_allowed || implicit_omit) { else if (!incomplete_allowed || implicit_omit) {
for (size_t i = 0; i < n_type_comps; i++) { for (size_t i = 0; i < n_type_comps; i++) {
const Identifier& id = get_comp_byIndex(i)->get_name(); const Identifier& id = get_comp_byIndex(i)->get_name();
if(!comp_map.has_key(id.get_name())) { if(!comp_map.has_key(id.get_name())) {
...@@ -5460,7 +5483,7 @@ bool Type::chk_this_template_generic(Template *t, namedbool incomplete_allowed, ...@@ -5460,7 +5483,7 @@ bool Type::chk_this_template_generic(Template *t, namedbool incomplete_allowed,
t_comp->set_my_governor(this); t_comp->set_my_governor(this);
chk_this_template_ref(t_comp); chk_this_template_ref(t_comp);
self_ref |= chk_this_template_generic(t_comp, INCOMPLETE_NOT_ALLOWED, self_ref |= chk_this_template_generic(t_comp, INCOMPLETE_NOT_ALLOWED,
omit_in_value_list ? OMIT_ALLOWED : OMIT_NOT_ALLOWED, omit_in_value_list ? allow_omit : OMIT_NOT_ALLOWED,
ANY_OR_OMIT_ALLOWED, sub_chk, implicit_omit, lhs); ANY_OR_OMIT_ALLOWED, sub_chk, implicit_omit, lhs);
if(temptype==Ttcn::Template::COMPLEMENTED_LIST && if(temptype==Ttcn::Template::COMPLEMENTED_LIST &&
t_comp->get_template_refd_last()->get_templatetype() == t_comp->get_template_refd_last()->get_templatetype() ==
......
...@@ -2467,6 +2467,9 @@ namespace Common { ...@@ -2467,6 +2467,9 @@ namespace Common {
u.val_Real = i_mant * pow(static_cast<double>(i_base), u.val_Real = i_mant * pow(static_cast<double>(i_base),
static_cast<double>(i_exp)); static_cast<double>(i_exp));
break; } break; }
case V_NOTUSED:
clean_up();
break;
default: default:
FATAL_ERROR("Value::set_valuetype()"); FATAL_ERROR("Value::set_valuetype()");
} // switch } // switch
...@@ -2535,6 +2538,15 @@ namespace Common { ...@@ -2535,6 +2538,15 @@ namespace Common {
FATAL_ERROR("Value::set_valuetype()"); FATAL_ERROR("Value::set_valuetype()");
} }
break; break;
case V_SET:
case V_CHOICE:
if (p_valuetype == V_NOTUSED) {
clean_up();
}
else {
FATAL_ERROR("Value::set_valuetype()");
}
break;
case V_TTCN3_NULL: case V_TTCN3_NULL:
switch (p_valuetype) { switch (p_valuetype) {
case V_DEFAULT_NULL: case V_DEFAULT_NULL:
...@@ -5927,8 +5939,8 @@ error: ...@@ -5927,8 +5939,8 @@ error:
if (!governor) { if (!governor) {
string str; string str;
ti->append_stringRepr( str); ti->append_stringRepr( str);
ti->error("Cannot determine the argument type of %s in the`%s' operation.\n" ti->error("Cannot determine the argument type of %s in the `%s' operation.\n"
"If type is known, use valuof(<type>: %s) as argument.", "If type is known, use valueof(<type>: %s) as argument.",
str.c_str(), get_opname(), str.c_str()); str.c_str(), get_opname(), str.c_str());
set_valuetype(V_ERROR); set_valuetype(V_ERROR);
} }
...@@ -11097,6 +11109,9 @@ error: ...@@ -11097,6 +11109,9 @@ error:
FATAL_ERROR("Value::generate_code_init()"); FATAL_ERROR("Value::generate_code_init()");
} }
break; break;
case V_NOTUSED:
// unbound value, don't generate anything
break;
default: default:
FATAL_ERROR("Value::generate_code_init()"); FATAL_ERROR("Value::generate_code_init()");
} }
...@@ -11672,8 +11687,7 @@ error: ...@@ -11672,8 +11687,7 @@ error:
expr->expr=mputstr(expr->expr, ".is_bound()"); expr->expr=mputstr(expr->expr, ".is_bound()");
break; break;
case OPTYPE_ISPRESENT: case OPTYPE_ISPRESENT:
expr->expr=mputprintf(expr->expr, ".is_present(%s)", expr->expr=mputprintf(expr->expr, ".is_present()");
omit_in_value_list ? "TRUE" : "");
break; break;
case OPTYPE_SIZEOF: case OPTYPE_SIZEOF:
expr->expr=mputstr(expr->expr, ".size_of()"); expr->expr=mputstr(expr->expr, ".size_of()");
...@@ -12878,6 +12892,9 @@ error: ...@@ -12878,6 +12892,9 @@ error:
FATAL_ERROR("Value::has_single_expr()"); FATAL_ERROR("Value::has_single_expr()");
case V_INT: case V_INT:
return u.val_Int->is_native_fit(); return u.val_Int->is_native_fit();
case V_NOTUSED:
// should only happen when generating code for an unbound record/set value
return false;
default: default:
// other value types (literal values) do not need temporary reference // other value types (literal values) do not need temporary reference
return true; return true;
......
...@@ -66,7 +66,6 @@ namespace Common { ...@@ -66,7 +66,6 @@ namespace Common {
/** value type */ /** value type */
enum valuetype_t { enum valuetype_t {
V_ERROR, /**< erroneous */ V_ERROR, /**< erroneous */
V_NULL, /**< NULL (for ASN.1 NULL type, also in TTCN-3) */ V_NULL, /**< NULL (for ASN.1 NULL type, also in TTCN-3) */
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
compiler \- TTCN-3 and ASN.1 to C++ translator compiler \- TTCN-3 and ASN.1 to C++ translator
.SH SYNOPSIS .SH SYNOPSIS
.B compiler .B compiler
.RB "[\| " \-abcdfgijlLMpqrRsStuwxXyY " \|]" .RB "[\| " \-abcdEfgijlLMpqrRsStuwxXyY " \|]"
.RB "[\| " \-V .RB "[\| " \-V
.IR " verb_level" " \|]" .IR " verb_level" " \|]"
.RB "[\| " \-K .RB "[\| " \-K
...@@ -81,6 +81,10 @@ fields with DEFAULT values as ...@@ -81,6 +81,10 @@ fields with DEFAULT values as
.I omit .I omit
in TTCN-3. in TTCN-3.
.TP .TP
.B \-E
Instructs the variant attribute parser to display warnings instead of errors
for unrecognized/erroneous attributes.
.TP
.B \-f .B \-f
Forces the compiler to Forces the compiler to
.I overwrite .I overwrite
......
...@@ -53,7 +53,7 @@ void def_encdec(const char *p_classname, ...@@ -53,7 +53,7 @@ void def_encdec(const char *p_classname,
"int XER_encode(const XERdescriptor_t&, TTCN_Buffer&, unsigned int, int, " "int XER_encode(const XERdescriptor_t&, TTCN_Buffer&, unsigned int, int, "
"embed_values_enc_struct_t*) const;\n" "embed_values_enc_struct_t*) const;\n"
"int XER_decode(const XERdescriptor_t&, XmlReaderWrap&, unsigned int, " "int XER_decode(const XERdescriptor_t&, XmlReaderWrap&, unsigned int, "
"embed_values_dec_struct_t*);\n" "unsigned int, embed_values_dec_struct_t*);\n"
"static boolean can_start(const char *name, const char *uri, " "static boolean can_start(const char *name, const char *uri, "
"XERdescriptor_t const& xd, unsigned int);\n" "XERdescriptor_t const& xd, unsigned int);\n"
"%s" "%s"
...@@ -217,7 +217,7 @@ void def_encdec(const char *p_classname, ...@@ -217,7 +217,7 @@ void def_encdec(const char *p_classname,
" for (int rd_ok=reader.Read(); rd_ok==1; rd_ok=reader.Read()) {\n" " for (int rd_ok=reader.Read(); rd_ok==1; rd_ok=reader.Read()) {\n"
" if (reader.NodeType() == XML_READER_TYPE_ELEMENT) break;\n" " if (reader.NodeType() == XML_READER_TYPE_ELEMENT) break;\n"
" }\n" " }\n"
" XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL, 0);\n" " XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL, XER_NONE, 0);\n"
" size_t bytes = reader.ByteConsumed();\n" " size_t bytes = reader.ByteConsumed();\n"
" p_buf.set_pos(bytes);\n" " p_buf.set_pos(bytes);\n"
" break;}\n" " break;}\n"
......
...@@ -677,7 +677,7 @@ void defEnumClass(const enum_def *edef, output_struct *output) ...@@ -677,7 +677,7 @@ void defEnumClass(const enum_def *edef, output_struct *output)
"// written by %s in " __FILE__ " at %d\n" "// written by %s in " __FILE__ " at %d\n"
#endif #endif
"int %s::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& p_reader," "int %s::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& p_reader,"
" unsigned int p_flavor, embed_values_dec_struct_t*)\n" " unsigned int p_flavor, unsigned int /*p_flavor2*/, embed_values_dec_struct_t*)\n"
"{\n" "{\n"
" int rd_ok = 1, type;\n" " int rd_ok = 1, type;\n"
......
...@@ -71,7 +71,8 @@ boolean generate_skeleton = FALSE, force_overwrite = FALSE, ...@@ -71,7 +71,8 @@ boolean generate_skeleton = FALSE, force_overwrite = FALSE,
use_runtime_2 = FALSE, gcc_compat = FALSE, asn1_xer = FALSE, use_runtime_2 = FALSE, gcc_compat = FALSE, asn1_xer = FALSE,
check_subtype = TRUE, suppress_context = FALSE, display_up_to_date = FALSE, check_subtype = TRUE, suppress_context = FALSE, display_up_to_date = FALSE,
implicit_json_encoding = FALSE, json_refs_for_all_types = TRUE, implicit_json_encoding = FALSE, json_refs_for_all_types = TRUE,
force_gen_seof = FALSE, omit_in_value_list = FALSE; force_gen_seof = FALSE, omit_in_value_list = FALSE,
warnings_for_bad_variants = FALSE;
// Default code splitting mode is set to 'no splitting'. // Default code splitting mode is set to 'no splitting'.
CodeGenHelper::split_type code_splitting_mode = CodeGenHelper::SPLIT_NONE; CodeGenHelper::split_type code_splitting_mode = CodeGenHelper::SPLIT_NONE;
...@@ -224,7 +225,7 @@ char *canonize_input_file(const char *path_name) ...@@ -224,7 +225,7 @@ char *canonize_input_file(const char *path_name)
break; break;
} }
char *dir_name = get_dir_from_path(path_name); char *dir_name = get_dir_from_path(path_name);
char *abs_dir = get_absolute_dir(dir_name, NULL); char *abs_dir = get_absolute_dir(dir_name, NULL, true);
Free(dir_name); Free(dir_name);
char *file_name = get_file_from_path(path_name); char *file_name = get_file_from_path(path_name);
char *ret_val = compose_path_name(abs_dir, file_name); char *ret_val = compose_path_name(abs_dir, file_name);
...@@ -360,7 +361,7 @@ static boolean is_valid_asn1_filename(const char* file_name) ...@@ -360,7 +361,7 @@ static boolean is_valid_asn1_filename(const char* file_name)
static void usage() static void usage()
{ {
fprintf(stderr, "\n" fprintf(stderr, "\n"
"usage: %s [-abcdfgijlLOpqrRsStuwxXyY] [-K file] [-z file] [-V verb_level]\n" "usage: %s [-abcdEfgijlLOpqrRsStuwxXyY] [-K file] [-z file] [-V verb_level]\n"
" [-o dir] [-U none|type] [-P modulename.top_level_pdu_name] [-Q number] ...\n" " [-o dir] [-U none|type] [-P modulename.top_level_pdu_name] [-Q number] ...\n"
" [-T] module.ttcn [-A] module.asn ...\n" " [-T] module.ttcn [-A] module.asn ...\n"
" or %s -v\n" " or %s -v\n"
...@@ -371,6 +372,7 @@ static void usage() ...@@ -371,6 +372,7 @@ static void usage()
" -b: disable BER encoder/decoder functions\n" " -b: disable BER encoder/decoder functions\n"
" -c: write out checksums in case of error\n" " -c: write out checksums in case of error\n"
" -d: treat default fields as omit\n" " -d: treat default fields as omit\n"
" -E: display only warnings for unrecognized encoding variants\n"
" -f: force overwriting of output files\n" " -f: force overwriting of output files\n"
" -g: emulate GCC error/warning message format\n" " -g: emulate GCC error/warning message format\n"
" -i: use only line numbers in error/warning messages\n" " -i: use only line numbers in error/warning messages\n"
...@@ -455,7 +457,8 @@ int main(int argc, char *argv[]) ...@@ -455,7 +457,8 @@ int main(int argc, char *argv[])
dflag = false, Xflag = false, Rflag = false, gflag = false, aflag = false, dflag = false, Xflag = false, Rflag = false, gflag = false, aflag = false,
s0flag = false, Cflag = false, yflag = false, Uflag = false, Qflag = false, s0flag = false, Cflag = false, yflag = false, Uflag = false, Qflag = false,
Sflag = false, Kflag = false, jflag = false, zflag = false, Fflag = false, Sflag = false, Kflag = false, jflag = false, zflag = false, Fflag = false,
Mflag = false, errflag = false, print_usage = false, ttcn2json = false; Mflag = false, Eflag = false, errflag = false, print_usage = false,
ttcn2json = false;
CodeGenHelper cgh; CodeGenHelper cgh;
...@@ -547,7 +550,7 @@ int main(int argc, char *argv[]) ...@@ -547,7 +550,7 @@ int main(int argc, char *argv[])
if (!ttcn2json) { if (!ttcn2json) {
for ( ; ; ) { for ( ; ; ) {
int c = getopt(argc, argv, "aA:C:K:LP:T:V:bcdfFgilMo:YpqQ:rRs0StuU:vwxXjyz:-"); int c = getopt(argc, argv, "aA:bcC:dEfFgijK:lLMo:pP:qQ:rRsStT:uU:vV:wxXyYz:0-");
if (c == -1) break; if (c == -1) break;
switch (c) { switch (c) {
case 'a': case 'a':
...@@ -714,6 +717,10 @@ int main(int argc, char *argv[]) ...@@ -714,6 +717,10 @@ int main(int argc, char *argv[])
SET_FLAG(M); SET_FLAG(M);
omit_in_value_list = TRUE; omit_in_value_list = TRUE;
break; break;
case 'E':
SET_FLAG(E);
warnings_for_bad_variants = TRUE;
break;
case 'Q': { case 'Q': {
long max_errs; long max_errs;
...@@ -758,7 +765,7 @@ int main(int argc, char *argv[]) ...@@ -758,7 +765,7 @@ int main(int argc, char *argv[])
if (Aflag || Lflag || Pflag || Tflag || Vflag || Yflag || if (Aflag || Lflag || Pflag || Tflag || Vflag || Yflag ||
bflag || fflag || iflag || lflag || oflag || pflag || qflag || bflag || fflag || iflag || lflag || oflag || pflag || qflag ||
rflag || sflag || tflag || uflag || wflag || xflag || Xflag || Rflag || rflag || sflag || tflag || uflag || wflag || xflag || Xflag || Rflag ||
Uflag || yflag || Kflag || jflag || zflag || Fflag || Mflag) { Uflag || yflag || Kflag || jflag || zflag || Fflag || Mflag || Eflag) {
errflag = true; errflag = true;
print_usage = true; print_usage = true;
} }
......
...@@ -36,7 +36,7 @@ extern boolean generate_skeleton, force_overwrite, include_line_info, ...@@ -36,7 +36,7 @@ extern boolean generate_skeleton, force_overwrite, include_line_info,
output_only_linenum, default_as_optional, use_runtime_2, gcc_compat, asn1_xer, output_only_linenum, default_as_optional, use_runtime_2, gcc_compat, asn1_xer,
check_subtype, suppress_context, enable_set_bound_out_param, display_up_to_date, check_subtype, suppress_context, enable_set_bound_out_param, display_up_to_date,
implicit_json_encoding, json_refs_for_all_types, force_gen_seof, implicit_json_encoding, json_refs_for_all_types, force_gen_seof,
omit_in_value_list; omit_in_value_list, warnings_for_bad_variants;
extern const char *expected_platform; extern const char *expected_platform;
......
...@@ -238,6 +238,8 @@ struct makefile_struct { ...@@ -238,6 +238,8 @@ struct makefile_struct {
boolean suppresswarnings; boolean suppresswarnings;
boolean outparamboundness; boolean outparamboundness;
boolean omit_in_value_list; boolean omit_in_value_list;
boolean warnings_for_bad_variants;
boolean disable_predef_ext_folder;
struct string_list* solspeclibraries; /* not owned */ struct string_list* solspeclibraries; /* not owned */
struct string_list* sol8speclibraries; /* not owned */ struct string_list* sol8speclibraries; /* not owned */
struct string_list* linuxspeclibraries; /* not owned */ struct string_list* linuxspeclibraries; /* not owned */
...@@ -301,6 +303,7 @@ static void init_makefile_struct(struct makefile_struct *makefile) ...@@ -301,6 +303,7 @@ static void init_makefile_struct(struct makefile_struct *makefile)
makefile->prep_defines = NULL; makefile->prep_defines = NULL;
makefile->outparamboundness = FALSE; makefile->outparamboundness = FALSE;