diff --git a/common/config_preproc_p.y b/common/config_preproc_p.y index e76ee4f07a61b32f3804bc94e555e6799bed4a2e..bd8e5ceddf66ce63830dad2db923ea8e83fe6300 100644 --- a/common/config_preproc_p.y +++ b/common/config_preproc_p.y @@ -256,7 +256,7 @@ extern int add_include_file(const std::string& filename) expstring_t currdirname, dirname, filenamepart, basedir; currdirname = get_dir_from_path(get_cfg_preproc_current_file().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(dirname); filenamepart = get_file_from_path(filename.c_str()); @@ -294,7 +294,7 @@ extern int preproc_parse_file(const char *filename, string_chain_t **filenames, config_preproc_defines=string_map_new(); { 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); Free(dirname); if (basedir == NULL) { diff --git a/common/path.c b/common/path.c index d9c4f3d27071e081288615d10f9c88165238420d..201e2153e9371d8f6e495f761b252d0e6d8191cc 100644 --- a/common/path.c +++ b/common/path.c @@ -129,7 +129,7 @@ expstring_t compose_path_name(const char *dir_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; /* save the working directory */ @@ -142,12 +142,18 @@ expstring_t get_absolute_dir(const char *dir_name, const char *base_dir) 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 */ set_working_dir(initial_dir); Free(initial_dir); 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(); /* restore the working directory */ set_working_dir(initial_dir); @@ -174,9 +180,9 @@ expstring_t get_relative_dir(const char *dir_name, const char *base_dir) { expstring_t ret_val = NULL; /* 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 ? - 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; if (canonized_dir_name == NULL || canonized_base_dir == NULL) { /* an error occurred */ diff --git a/common/path.h b/common/path.h index e72b743f1b656adb1cbcebdc9d4607363190eeb0..549633ab038ad892199fb9293c4f04d4a7dfa8f2 100644 --- a/common/path.h +++ b/common/path.h @@ -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. * The string returned shall be deallocated by the caller using \a Free(). * Note: The working directory of the current process might change during the - * function call, but it is restored before the function returns. */ -extern expstring_t get_absolute_dir(const char *dir_name, const char *base_dir); + * function call, but it is restored before the function returns. + * 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 * \a working_dir is NULL the current working directory of the process is used. diff --git a/common/version.h b/common/version.h index 959454a68f2e7987aee34336f8ffe7df46a47d72..d8aaafbf8c2a294138798d925a8a56a528fa1db7 100644 --- a/common/version.h +++ b/common/version.h @@ -11,7 +11,7 @@ /* Version numbers */ #define TTCN3_MAJOR 5 #define TTCN3_MINOR 4 -#define TTCN3_PATCHLEVEL 2 +#define TTCN3_PATCHLEVEL 3 //#define TTCN3_BUILDNUMBER 0 /* The aggregated version number must be set manually since some stupid @@ -22,7 +22,7 @@ * TTCN3_VERSION = TTCN3_MAJOR * 1000000 + TTCN3_MINOR * 10000 + * TTCN3_PATCHLEVEL * 100 + TTCN3_BUILDNUMBER */ -#define TTCN3_VERSION 50402 +#define TTCN3_VERSION 50403 /* A monotonically increasing version number. * An official release is deemed to have the highest possible build number (99) diff --git a/compiler2/Type.cc b/compiler2/Type.cc index cc5b039d18c4370a2fd387cb43d4982f775242a6..d99d14a08cf827a107a4f343d67f22a87c4713ae 100644 --- a/compiler2/Type.cc +++ b/compiler2/Type.cc @@ -1610,6 +1610,9 @@ namespace Common { case T_SET_T: case T_ANYTYPE: break; + case T_COMPONENT: + ref->error("Referencing fields of a component is not allowed"); + return 0; default: ref->error("Invalid field reference `%s': type `%s' " "does not have fields", id.get_dispname().c_str(), @@ -2777,11 +2780,14 @@ namespace Common { comp_type->jsonattrib->metainfo_unbound = true; } } - else if (NULL == parent || (T_SEQ_T != parent->typetype && - T_SET_T != parent->typetype)) { - // only allowed if it's a field of a record/set + else if (T_SEQOF != get_type_refd_last()->typetype && + T_SETOF != get_type_refd_last()->typetype && + 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, " - "or field of a record or set"); + "record of, set of, array or field of a record or set"); } } } diff --git a/compiler2/Type_chk.cc b/compiler2/Type_chk.cc index 759fab13a2fe6d21a4909fd635be82ecd5c544f4..99f0da2479e0340ca657d98e6e8be7610ec57b8a 100644 --- a/compiler2/Type_chk.cc +++ b/compiler2/Type_chk.cc @@ -395,6 +395,7 @@ void Type::parse_attributes() case T_SEQ_T: case T_SET_T: case T_ANYTYPE: + case T_ARRAY: if(rawattrib==NULL) {rawattrib= new RawAST; new_raw=true;} if(textattrib==NULL){textattrib= new TextAST; new_text=true;} if(xerattrib==NULL) {xerattrib = new XerAttributes; new_xer = true;} @@ -459,7 +460,8 @@ void Type::parse_attributes() // This should be bool, but gcc 4.1.2-sol8 generates incorrect code // 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(); // Distribute the attributes with qualifiers to the components. @@ -4070,6 +4072,9 @@ bool Type::chk_this_value_Choice(Value *value, Common::Assignment *lhs, alt_type->chk_this_value_ref(alt_value); self_ref |= alt_type->chk_this_value(alt_value, lhs, expected_value, incomplete_allowed, OMIT_NOT_ALLOWED, SUB_CHK, implicit_omit); + if (alt_value->get_valuetype() == Value::V_NOTUSED) { + value->set_valuetype(Value::V_NOTUSED); + } break;} default: 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_ CompField *last_cf = 0; size_t next_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++) { NamedValue *nv = value->get_se_comp_byIndex(v_i); const Identifier& value_id = nv->get_name(); @@ -4226,8 +4232,16 @@ bool Type::chk_this_value_Seq_T(Value *value, Common::Assignment *lhs, expected_ type->chk_this_value_ref(comp_value); 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); + 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++) { const Identifier& id = get_comp_byIndex(i)->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_ map<string, NamedValue> comp_map; size_t n_type_comps = 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++) { NamedValue *nv = value->get_se_comp_byIndex(v_i); const Identifier& value_id = nv->get_name(); @@ -4282,8 +4297,16 @@ bool Type::chk_this_value_Set_T(Value *value, Common::Assignment *lhs, expected_ type->chk_this_value_ref(comp_value); 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); + 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++) { const Identifier& id = get_comp_byIndex(i)->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, t_comp->set_my_governor(this); chk_this_template_ref(t_comp); 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); if(temptype==Ttcn::Template::COMPLEMENTED_LIST && t_comp->get_template_refd_last()->get_templatetype() == diff --git a/compiler2/Value.cc b/compiler2/Value.cc index 3a8ade1950d5d85bcba6e811c4c24009ecb1f27a..1f9de506a5ce821ca40c641bbdafc08e4e5907f4 100644 --- a/compiler2/Value.cc +++ b/compiler2/Value.cc @@ -2467,6 +2467,9 @@ namespace Common { u.val_Real = i_mant * pow(static_cast<double>(i_base), static_cast<double>(i_exp)); break; } + case V_NOTUSED: + clean_up(); + break; default: FATAL_ERROR("Value::set_valuetype()"); } // switch @@ -2535,6 +2538,15 @@ namespace Common { FATAL_ERROR("Value::set_valuetype()"); } 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: switch (p_valuetype) { case V_DEFAULT_NULL: @@ -5927,8 +5939,8 @@ error: if (!governor) { string str; ti->append_stringRepr( str); - ti->error("Cannot determine the argument type of %s in the`%s' operation.\n" - "If type is known, use valuof(<type>: %s) as argument.", + ti->error("Cannot determine the argument type of %s in the `%s' operation.\n" + "If type is known, use valueof(<type>: %s) as argument.", str.c_str(), get_opname(), str.c_str()); set_valuetype(V_ERROR); } @@ -11097,6 +11109,9 @@ error: FATAL_ERROR("Value::generate_code_init()"); } break; + case V_NOTUSED: + // unbound value, don't generate anything + break; default: FATAL_ERROR("Value::generate_code_init()"); } @@ -11672,8 +11687,7 @@ error: expr->expr=mputstr(expr->expr, ".is_bound()"); break; case OPTYPE_ISPRESENT: - expr->expr=mputprintf(expr->expr, ".is_present(%s)", - omit_in_value_list ? "TRUE" : ""); + expr->expr=mputprintf(expr->expr, ".is_present()"); break; case OPTYPE_SIZEOF: expr->expr=mputstr(expr->expr, ".size_of()"); @@ -12878,6 +12892,9 @@ error: FATAL_ERROR("Value::has_single_expr()"); case V_INT: 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: // other value types (literal values) do not need temporary reference return true; diff --git a/compiler2/Value.hh b/compiler2/Value.hh index 38e83875c4ba24cef061fe3b03527dfe30fee36d..fa98bb8f078aefb9da02926540ed8c01e62a5f7a 100644 --- a/compiler2/Value.hh +++ b/compiler2/Value.hh @@ -66,7 +66,6 @@ namespace Common { /** value type */ - enum valuetype_t { V_ERROR, /**< erroneous */ V_NULL, /**< NULL (for ASN.1 NULL type, also in TTCN-3) */ diff --git a/compiler2/compiler.1 b/compiler2/compiler.1 index 9739703d711b7aa72ba35ac3415aecaf0ccf8cf1..1a7ca4c1e8b04d4a1bfe53198c8ef9f4da6f117a 100644 --- a/compiler2/compiler.1 +++ b/compiler2/compiler.1 @@ -3,7 +3,7 @@ compiler \- TTCN-3 and ASN.1 to C++ translator .SH SYNOPSIS .B compiler -.RB "[\| " \-abcdfgijlLMpqrRsStuwxXyY " \|]" +.RB "[\| " \-abcdEfgijlLMpqrRsStuwxXyY " \|]" .RB "[\| " \-V .IR " verb_level" " \|]" .RB "[\| " \-K @@ -81,6 +81,10 @@ fields with DEFAULT values as .I omit in TTCN-3. .TP +.B \-E +Instructs the variant attribute parser to display warnings instead of errors +for unrecognized/erroneous attributes. +.TP .B \-f Forces the compiler to .I overwrite diff --git a/compiler2/encdec.c b/compiler2/encdec.c index 6b90b1377996c2b9a0b47b3b74df1033061ad8f9..d93612e2f74bdc7e35a547f88e0bfee272971448 100644 --- a/compiler2/encdec.c +++ b/compiler2/encdec.c @@ -53,7 +53,7 @@ void def_encdec(const char *p_classname, "int XER_encode(const XERdescriptor_t&, TTCN_Buffer&, unsigned int, int, " "embed_values_enc_struct_t*) const;\n" "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, " "XERdescriptor_t const& xd, unsigned int);\n" "%s" @@ -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" " if (reader.NodeType() == XML_READER_TYPE_ELEMENT) break;\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" " p_buf.set_pos(bytes);\n" " break;}\n" diff --git a/compiler2/enum.c b/compiler2/enum.c index 0d995c74c2a7aa0bd2d0de6d06dd67e143a46ab5..601aa8661a2443cfdc5466b57c576718d4841a0a 100644 --- a/compiler2/enum.c +++ b/compiler2/enum.c @@ -677,7 +677,7 @@ void defEnumClass(const enum_def *edef, output_struct *output) "// written by %s in " __FILE__ " at %d\n" #endif "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" " int rd_ok = 1, type;\n" diff --git a/compiler2/main.cc b/compiler2/main.cc index c4e8ff3874f2aae35cdb4b8758a50293b411de0c..28a4ba75601e90abc53391a3dfb89bc3daee4cc5 100644 --- a/compiler2/main.cc +++ b/compiler2/main.cc @@ -71,7 +71,8 @@ boolean generate_skeleton = FALSE, force_overwrite = FALSE, use_runtime_2 = FALSE, gcc_compat = FALSE, asn1_xer = FALSE, check_subtype = TRUE, suppress_context = FALSE, display_up_to_date = FALSE, 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'. CodeGenHelper::split_type code_splitting_mode = CodeGenHelper::SPLIT_NONE; @@ -224,7 +225,7 @@ char *canonize_input_file(const char *path_name) break; } 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); char *file_name = get_file_from_path(path_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) static void usage() { 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" " [-T] module.ttcn [-A] module.asn ...\n" " or %s -v\n" @@ -371,6 +372,7 @@ static void usage() " -b: disable BER encoder/decoder functions\n" " -c: write out checksums in case of error\n" " -d: treat default fields as omit\n" + " -E: display only warnings for unrecognized encoding variants\n" " -f: force overwriting of output files\n" " -g: emulate GCC error/warning message format\n" " -i: use only line numbers in error/warning messages\n" @@ -455,7 +457,8 @@ int main(int argc, char *argv[]) dflag = false, Xflag = false, Rflag = false, gflag = false, aflag = false, s0flag = false, Cflag = false, yflag = false, Uflag = false, Qflag = 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; @@ -547,7 +550,7 @@ int main(int argc, char *argv[]) if (!ttcn2json) { 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; switch (c) { case 'a': @@ -714,6 +717,10 @@ int main(int argc, char *argv[]) SET_FLAG(M); omit_in_value_list = TRUE; break; + case 'E': + SET_FLAG(E); + warnings_for_bad_variants = TRUE; + break; case 'Q': { long max_errs; @@ -758,7 +765,7 @@ int main(int argc, char *argv[]) if (Aflag || Lflag || Pflag || Tflag || Vflag || Yflag || bflag || fflag || iflag || lflag || oflag || pflag || qflag || 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; print_usage = true; } diff --git a/compiler2/main.hh b/compiler2/main.hh index 10192d71daea2e4a4cab711e6fe02d2aeae924d2..23e1b30df6c856e9d43108f4c384e8b35e459966 100644 --- a/compiler2/main.hh +++ b/compiler2/main.hh @@ -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, check_subtype, suppress_context, enable_set_bound_out_param, display_up_to_date, 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; diff --git a/compiler2/makefile.c b/compiler2/makefile.c index 3bf80cfe56143bf192aa797ab35f49ae374c6745..7c2f905985fddbefd34eeb8bed7d7b24a3aab029 100644 --- a/compiler2/makefile.c +++ b/compiler2/makefile.c @@ -238,6 +238,8 @@ struct makefile_struct { boolean suppresswarnings; boolean outparamboundness; boolean omit_in_value_list; + boolean warnings_for_bad_variants; + boolean disable_predef_ext_folder; struct string_list* solspeclibraries; /* not owned */ struct string_list* sol8speclibraries; /* not owned */ struct string_list* linuxspeclibraries; /* not owned */ @@ -301,6 +303,7 @@ static void init_makefile_struct(struct makefile_struct *makefile) makefile->prep_defines = NULL; makefile->outparamboundness = FALSE; makefile->omit_in_value_list = FALSE; + makefile->warnings_for_bad_variants = FALSE; makefile->solspeclibraries = NULL; makefile->sol8speclibraries = NULL; makefile->linuxspeclibraries = NULL; @@ -518,7 +521,7 @@ static char *get_dir_name(const char *path_name, const char *working_dir) { char *dir_name = get_dir_from_path(path_name); if (dir_name != NULL) { - char *absolute_dir = get_absolute_dir(dir_name, working_dir); + char *absolute_dir = get_absolute_dir(dir_name, working_dir, TRUE); Free(dir_name); if (absolute_dir == NULL || working_dir == NULL) { /* an error occurred */ @@ -1975,13 +1978,13 @@ static void print_makefile(struct makefile_struct *makefile) "AR = ar\n" "ARFLAGS = \n\n" "# Flags for the TTCN-3 and ASN.1 compiler:\n" - "COMPILER_FLAGS =%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n\n" + "COMPILER_FLAGS =%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n\n" "# Execution mode: (either ttcn3 or ttcn3-parallel)\n" "TTCN3_LIB = ttcn3%s%s%s\n\n" #ifdef LICENSE "# The path of your OpenSSL installation:\n" "# If you do not have your own one, leave it unchanged.\n" - "OPENSSL_DIR = $(TTCN3_DIR)\n\n" + "%sOPENSSL_DIR = $(TTCN3_DIR)\n\n" #endif "# The path of your libxml2 installation:\n" "# If you do not have your own one, leave it unchanged.\n" @@ -2012,12 +2015,16 @@ static void print_makefile(struct makefile_struct *makefile) (makefile->suppresswarnings ? " -w" : ""), (makefile->outparamboundness ? " -Y" : ""), (makefile->omit_in_value_list ? " -M" : ""), + (makefile->warnings_for_bad_variants ? " -E" : ""), (makefile->tcov_file_name ? makefile->tcov_file_name : ""), (makefile->profiled_file_list ? " -z $(PROFILED_FILE_LIST)" : ""), /* end of COMPILER FLAGS */ (makefile->use_runtime_2 ? "-rt2" : ""), /* TTCN3_LIB */ (makefile->single_mode ? "" : "-parallel"), (makefile->dynamic ? "-dynamic": "") +#ifdef LICENSE + ,(makefile->disable_predef_ext_folder ? "# " : "") +#endif ); if (!makefile->gnu_make) { fputs("# Note: you can set any directory except ./archive\n", fp); @@ -3719,8 +3726,8 @@ static void generate_makefile(size_t n_arguments, char *arguments[], const char* cxxcompiler, const char* optlevel, const char* optflags, boolean disableber, boolean disableraw, boolean disabletext, boolean disablexer, boolean disablejson, boolean forcexerinasn, boolean defaultasomit, boolean gccmsgformat, boolean linenumbersonlymsg, boolean includesourceinfo, boolean addsourcelineinfo, boolean suppresswarnings, - boolean outparamboundness, boolean omit_in_value_list, struct string_list* solspeclibraries, struct string_list* sol8speclibraries, - struct string_list* linuxspeclibraries, struct string_list* freebsdspeclibraries, + boolean outparamboundness, boolean omit_in_value_list, boolean warnings_for_bad_variants, boolean disable_predef_ext_folder, struct string_list* solspeclibraries, + struct string_list* sol8speclibraries, struct string_list* linuxspeclibraries, struct string_list* freebsdspeclibraries, struct string_list* win32speclibraries, const char* ttcn3preprocessor, struct string_list* linkerlibraries, struct string_list* additionalObjects, struct string_list* linkerlibsearchpath, char* generatorCommandOutput, struct string2_list* target_placement_list) @@ -3770,6 +3777,8 @@ static void generate_makefile(size_t n_arguments, char *arguments[], makefile.suppresswarnings = suppresswarnings; makefile.outparamboundness = outparamboundness; makefile.omit_in_value_list = omit_in_value_list; + makefile.warnings_for_bad_variants = warnings_for_bad_variants; + makefile.disable_predef_ext_folder = disable_predef_ext_folder; makefile.solspeclibraries = solspeclibraries; makefile.sol8speclibraries = sol8speclibraries; makefile.linuxspeclibraries = linuxspeclibraries; @@ -3904,7 +3913,7 @@ static void generate_makefile(size_t n_arguments, char *arguments[], static void usage(void) { fprintf(stderr, "\n" - "usage: %s [-abc" C_flag "dDfFglLmMprRstTVwWXZ] [-K file] [-z file ] [-P dir]" + "usage: %s [-abc" C_flag "dDEfFglLmMprRstTVwWXZ] [-K file] [-z file ] [-P dir]" " [-U none|type] [-e ets_name] [-o dir|file]\n" " [-t project_descriptor.tpd [-b buildconfig]]\n" " [-O file] ... module_name ... testport_name ...\n" @@ -3918,8 +3927,10 @@ static void usage(void) #endif " -d: dump the data used for Makefile generation\n" " -e ets_name: name of the target executable\n" + " -E: display only warnings for unrecognized encoding variants\n" " -f: force overwriting of the output Makefile\n" " -g: generate Makefile for use with GNU make\n" + " -I path: Add path to the search paths when using TPD files\n" " -K file: enable selective code coverage\n" " -l: use dynamic linking\n" " -L: create makefile with library archive as the default target\n" @@ -3992,7 +4003,7 @@ int main(int argc, char *argv[]) gfflag = FALSE, lnflag = FALSE, isflag = FALSE, asflag = FALSE, swflag = FALSE, Vflag = FALSE, Dflag = FALSE, Wflag = FALSE, djflag = FALSE, Zflag = FALSE, Hflag = FALSE, Mflag = FALSE, - zflag = FALSE; + diflag = FALSE, zflag = FALSE, Eflag = FALSE; boolean error_flag = FALSE; char *output_file = NULL; char *ets_name = NULL; @@ -4003,6 +4014,8 @@ int main(int argc, char *argv[]) const char *tpd_file_name = NULL; const char *tpd_build_config = NULL; const char *tcov_file_name = NULL; + size_t n_search_paths = 0; + const char **search_paths = NULL; struct string_list* profiled_file_list = NULL; const char *profiled_file_list_zflag = NULL; const char *file_list_path = NULL; @@ -4047,7 +4060,7 @@ int main(int argc, char *argv[]) } for ( ; ; ) { - int c = getopt(argc, argv, "O:ab:c" C_flag "dDe:fFgK:o:lLmMpP:rRst:TU:vVwWXYz:ZH"); + int c = getopt(argc, argv, "O:ab:c" C_flag "dDe:EfFgI:K:o:lLmMpP:rRst:TU:vVwWXYz:ZH"); if (c == -1) break; switch (c) { case 'O': @@ -4056,6 +4069,12 @@ int main(int argc, char *argv[]) Realloc(other_files, n_other_files * sizeof(*other_files)); other_files[n_other_files - 1] = optarg; break; + case 'I': + n_search_paths++; + search_paths = (const char**) + Realloc(search_paths, n_search_paths * sizeof(*search_paths)); + search_paths[n_search_paths - 1] = optarg; + break; case 'a': SET_FLAG(a); break; @@ -4085,6 +4104,9 @@ int main(int argc, char *argv[]) SET_FLAG(e); ets_name = optarg; break; + case 'E': + SET_FLAG(E); + break; case 'f': SET_FLAG(f); break; @@ -4189,7 +4211,7 @@ int main(int argc, char *argv[]) if ( aflag || bflag || cflag || Cflag || dflag || eflag || fflag || Fflag || gflag || mflag || oflag || lflag || pflag || Pflag || rflag || Rflag || sflag || tflag || Tflag || Vflag || wflag || Xflag || Kflag || Dflag || Wflag || Yflag - || Zflag || Hflag || Mflag || zflag || n_other_files > 0) + || Zflag || Hflag || Mflag || zflag || Eflag || n_other_files > 0 || n_search_paths > 0) error_flag = TRUE; } @@ -4239,6 +4261,30 @@ int main(int argc, char *argv[]) error_flag = TRUE; } + if (n_search_paths > 0 && !tflag) { + ERROR("Using the '-I' option requires use of the '-t' option."); + error_flag = TRUE; + } + + for (size_t i = 0; i < n_search_paths; i++) { + boolean is_abs_path = +#if defined WIN32 && defined MINGW + /* On native Windows the absolute path name shall begin with + * a drive letter, colon and backslash */ + (((search_paths[i][0] < 'A' || search_paths[i][0] > 'Z') && + (search_paths[i][0] < 'a' || search_paths[i][0] > 'z')) || + search_paths[i][1] != ':' || search_paths[i][2] != '\\'); +#else + /* On UNIX-like systems the absolute path name shall begin with + * a slash */ + search_paths[i][0] != '/'; +#endif + if (is_abs_path) { + ERROR("The path after the -I flag must be an absolute path."); + error_flag = TRUE; + } + } + if (error_flag) { usage(); return EXIT_FAILURE; @@ -4351,9 +4397,9 @@ int main(int argc, char *argv[]) &Rflag, &lflag, &mflag, &Pflag, &Lflag, rflag, Fflag, Tflag, output_file, &abs_work_dir, sub_project_dirs, program_name, prj_graph_fp, create_symlink_list,ttcn3_prep_includes, ttcn3_prep_defines,ttcn3_prep_undefines, prep_includes, prep_defines, prep_undefines, &csflag, &quflag, &dsflag, &cxxcompiler, &optlevel, &optflags, &dbflag, &drflag, &dtflag, &dxflag, &djflag, &fxflag, &doflag, &gfflag, &lnflag, &isflag, - &asflag, &swflag, &Yflag, &Mflag, solspeclibraries, sol8speclibraries, linuxspeclibraries, freebsdspeclibraries, win32speclibraries, &ttcn3prep, + &asflag, &swflag, &Yflag, &Mflag, &Eflag, &diflag, solspeclibraries, sol8speclibraries, linuxspeclibraries, freebsdspeclibraries, win32speclibraries, &ttcn3prep, linkerlibraries, additionalObjects, linkerlibsearchpath, Vflag, Dflag, &Zflag, &Hflag, - &generatorCommandOutput, target_placement_list, Wflag, run_command_list, required_configs, &profiled_file_list); + &generatorCommandOutput, target_placement_list, Wflag, run_command_list, required_configs, &profiled_file_list, search_paths, n_search_paths); Free(abs_work_dir); if (prj_graph_fp) { @@ -4390,7 +4436,7 @@ int main(int argc, char *argv[]) Rflag, lflag, mflag, Cflag, code_splitting_mode, tcov_file_name, profiled_file_list, Lflag, Zflag, Hflag, rflag ? sub_project_dirs : NULL, ttcn3_prep_includes, ttcn3_prep_defines, ttcn3_prep_undefines, prep_includes, prep_defines, prep_undefines, csflag, quflag, dsflag, cxxcompiler, optlevel, optflags, dbflag, - drflag, dtflag, dxflag, djflag, fxflag, doflag, gfflag, lnflag, isflag, asflag, swflag, Yflag, Mflag, solspeclibraries, + drflag, dtflag, dxflag, djflag, fxflag, doflag, gfflag, lnflag, isflag, asflag, swflag, Yflag, Mflag, Eflag, diflag, solspeclibraries, sol8speclibraries, linuxspeclibraries, freebsdspeclibraries, win32speclibraries, ttcn3prep, linkerlibraries, additionalObjects, linkerlibsearchpath, generatorCommandOutput, target_placement_list); } @@ -4412,6 +4458,8 @@ int main(int argc, char *argv[]) free_string_list(linkerlibsearchpath); free_string_list(profiled_file_list); + Free(search_paths); + Free(generatorCommandOutput); free_string2_list(target_placement_list); free_string2_list(required_configs); diff --git a/compiler2/record.c b/compiler2/record.c index 1a029b9c355222fc945627b8f8ddf74495e9a10d..1eecf4c7b949fdf2a70c68ddfdbd87355dd4ce1d 100644 --- a/compiler2/record.c +++ b/compiler2/record.c @@ -190,7 +190,6 @@ char* generate_raw_coding(char* src, "p_td, TTCN_Buffer& p_buf, int limit, raw_order_t top_bit_ord, " "boolean, int, boolean)\n" "{\n" - "bound_flag = TRUE;\n" "int prepaddlength = p_buf.increase_pos_padd(p_td.raw->prepadding);\n" "limit -= prepaddlength;\n" "int decoded_length = 0;\n" @@ -421,7 +420,6 @@ char* generate_raw_coding(char* src, "TTCN_Buffer& p_buf, int limit, raw_order_t top_bit_ord, boolean no_err, " "int, boolean)\n" "{ (void)no_err;\n" - " bound_flag = TRUE;\n" " int prepaddlength=p_buf.increase_pos_padd(p_td.raw->prepadding);\n" " limit-=prepaddlength;\n" " size_t last_decoded_pos = p_buf.get_pos_bit();\n" @@ -1965,7 +1963,7 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc) " p_buf.put_s((size_t)p_td.namelens[e_xer]%s-(!is_indented%s), " "(cbyte*)p_td.names[e_xer]);\n" " }\n" - " else if (p_flavor & USE_TYPE_ATTR) {\n" + " else if (p_flavor & (USE_NIL|USE_TYPE_ATTR)) {\n" " size_t buf_len = p_buf.get_len();\n" " const unsigned char * const buf_data = p_buf.get_data();\n" " if (buf_data[buf_len-1-chopped_chars] == '\\n') ++chopped_chars;\n" @@ -2082,7 +2080,7 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc) , sdef->elements[sdef->nElements-1].name ); } - + if (want_namespaces) { /* there were some attributes. close the start tag left open */ src = mputprintf(src, @@ -2366,9 +2364,8 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc) src = mputprintf(src, /* XERSTUFF decodegen for record/SEQUENCE*/ "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" - " bound_flag = TRUE;\n" /* Remove XER_LIST, XER_RECOF from p_flavor. This is not required * for is_exer (which tests another bit), but for subsequent code. */ " int e_xer = is_exer(p_flavor);\n" @@ -2377,9 +2374,10 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc) " const boolean omit_tag = e_xer && ((xerbits & (UNTAGGED|XER_ATTRIBUTE)) " "|| (p_flavor & (USE_NIL|USE_TYPE_ATTR)));\n" "%s" - " const boolean parent_tag = e_xer && (p_flavor & (USE_TYPE_ATTR));\n" + " const boolean parent_tag = e_xer && ((p_flavor & USE_TYPE_ATTR)|| (p_flavor2 & USE_NIL_PARENT_TAG));\n" " (void)parent_tag;\n" " p_flavor &= XER_MASK;\n" /* also removes "toplevel" bit */ + " p_flavor2 = XER_NONE;\n" /* Remove only bit: USE_NIL_PARENT_TAG (for now) */ " int rd_ok, xml_depth=-1, type;\n" " {\n" /* scope for the error contexts */ , name @@ -2389,8 +2387,10 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc) * or if EMBED-VALUES is possible, but isn't. */ ); - if (sdef->xerUseNilPossible) src = mputstr(src, - " boolean nil_attribute = FALSE;\n"); + if (sdef->xerUseNilPossible) { src = mputstr(src, + " boolean nil_attribute = FALSE;\n" + " boolean already_processed = FALSE;\n"); + } src = mputprintf(src, " TTCN_EncDec_ErrorContext ec_0(\"Component '\");\n" @@ -2449,12 +2449,11 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc) /* ******************************************************************** * ATTRIBUTES - ***************************/ + ***************************/ if (num_attributes || sdef->xerUseNilPossible /* maybe QNAME too ? */) { size_t aaa; - src = mputstr(src, " if (!omit_tag || parent_tag) {\n"); - /* Prepare for attributes not present in the XML. + /* Prepare for attributes not present in the XML. * Set all attributes with defaultForEmpty to the D-F-E value. * Set all optional components with ATTRIBUTE to omit. * @@ -2477,6 +2476,8 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc) , sdef->elements[aaa].isOptional ? " = OMIT_VALUE" : ".set_size(0)"); } } + + src = mputstr(src, " if (!omit_tag || parent_tag) {\n"); if (num_attributes==0 /* therefore sdef->xerUseNilPossible is true */ ) { /* Only the "nil" attribute may be present. If there is no USE-NIL, @@ -2492,7 +2493,12 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc) } src = mputstr(src, - " for (rd_ok = p_reader.MoveToFirstAttribute(); rd_ok==1 && " + " if(parent_tag && p_reader.NodeType() == XML_READER_TYPE_ATTRIBUTE) {\n" + " rd_ok = p_reader.Ok();\n" + " } else {\n" + " rd_ok = p_reader.MoveToFirstAttribute();\n" + " }\n" + " for (; rd_ok==1 && " "p_reader.NodeType()==XML_READER_TYPE_ATTRIBUTE; " "rd_ok = p_reader.AdvanceAttribute()) {\n" " if (p_reader.IsNamespaceDecl()) continue;\n"); @@ -2525,13 +2531,24 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc) src = mputprintf(src, " if (check_name(attr_name, %s_xer_, 1) && check_namespace(ns_uri, %s_xer_)) {\n" " ec_1.set_msg(\"%s': \");\n" - " field_%s.XER_decode(%s_xer_, p_reader, p_flavor | (p_td.xer_bits & USE_NIL), 0);\n" + " field_%s.XER_decode(%s_xer_, p_reader, p_flavor | (p_td.xer_bits & USE_NIL), p_flavor2, 0);\n" " } else" , sdef->elements[i].typegen, sdef->elements[i].typegen , sdef->elements[i].dispname /* set_msg */ , sdef->elements[i].name, sdef->elements[i].typegen ); } + + if(sdef->xerUseNilPossible) { + src = mputprintf(src, + " if(p_td.xer_bits & USE_NIL) {\n" + " field_%s.XER_decode(%s_xer_, p_reader, p_flavor | USE_NIL, p_flavor2 | USE_NIL_PARENT_TAG, 0);\n" + " already_processed = TRUE;\n" + " } else" + , sdef->elements[sdef->nElements-1].name + , sdef->elements[sdef->nElements-1].typegen + ); + } if (sdef->control_ns_prefix && !(num_attributes==1 && aa_index!=-1)) { src = mputprintf(src, @@ -2617,7 +2634,7 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc) " if (!(p_td.xer_bits & EMBED_VALUES)) {\n" " ec_1.set_msg(\"%s': \");\n" " field_%s.XER_decode(%s_xer_, p_reader, " - "p_flavor | (p_td.xer_bits & USE_NIL)| (tag_closed ? PARENT_CLOSED : XER_NONE), 0);\n" + "p_flavor | (p_td.xer_bits & USE_NIL)| (tag_closed ? PARENT_CLOSED : XER_NONE), p_flavor2, 0);\n" " }\n" , sdef->elements[0].dispname , sdef->elements[0].name, sdef->elements[0].typegen @@ -2651,7 +2668,7 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc) src = mputprintf(src, " {\n" " ec_1.set_msg(\"%s': \");\n" - " field_%s.XER_decode(%s_xer_, p_reader, p_flavor | (p_td.xer_bits & USE_NIL), 0);\n" + " field_%s.XER_decode(%s_xer_, p_reader, p_flavor | (p_td.xer_bits & USE_NIL), p_flavor2, 0);\n" " }\n" , sdef->elements[i].dispname , sdef->elements[i].name, sdef->elements[i].typegen @@ -2777,7 +2794,7 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc) src = mputprintf(src, " if (check_name(x_name, %s_xer_, 1)) {\n" " ec_1.set_msg(\"%s': \");\n" - " field_%s%s%s%s.XER_decode(%s_xer_, p_reader, p_flavor, %s);\n" + " field_%s%s%s%s.XER_decode(%s_xer_, p_reader, p_flavor, p_flavor2, %s);\n" , sdef->elements[i].typegen , sdef->elements[i].dispname , (sdef->xerUseNilPossible ? sdef->elements[sdef->nElements-1].name: sdef->elements[i].name) @@ -2814,7 +2831,7 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc) " }\n" " if (!next_any) {\n" " ec_1.set_msg(\"%s': \");\n" - " field_%s%s%s%s.XER_decode(%s_xer_, p_reader, p_flavor, 0);\n" + " field_%s%s%s%s.XER_decode(%s_xer_, p_reader, p_flavor, p_flavor2, 0);\n" " field_%s[i] = e_val;\n" " any_found = true;\n" " }\n" @@ -2921,8 +2938,9 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc) " if (e_xer && p_td.dfeValue && p_reader.IsEmptyElement()) {\n" " field_%s = *static_cast<const %s*>(p_td.dfeValue);\n" " }\n" - " else" - , sdef->elements[i].name, sdef->elements[i].type); + " else%s" + , sdef->elements[i].name, sdef->elements[i].type + , sdef->xerUseNilPossible ? " if (!already_processed)" : ""); } /* Decode the field */ src = mputprintf(src, @@ -2946,7 +2964,7 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc) src = mputprintf(src, " field_%s.XER_decode(%s_xer_, p_reader, p_flavor" - " | (p_td.xer_bits & USE_NIL)| (tag_closed ? PARENT_CLOSED : XER_NONE), %s);\n" + " | (p_td.xer_bits & USE_NIL)| (tag_closed ? PARENT_CLOSED : XER_NONE), p_flavor2, %s);\n" " }\n" , sdef->elements[i].name, sdef->elements[i].typegen , sdef->xerEmbedValuesPossible ? "emb_val" : "0"); @@ -3111,7 +3129,6 @@ void defRecordClass1(const struct_def *sdef, output_struct *output) def=mputprintf(def, "class %s {\n", name); } - /* fields */ for (i = 0; i < sdef->nElements; i++) { if(sdef->elements[i].isOptional) def = mputprintf(def, " OPTIONAL<%s> field_%s;\n", @@ -3121,16 +3138,12 @@ void defRecordClass1(const struct_def *sdef, output_struct *output) def = mputprintf(def, " %s field_%s;\n", sdef->elements[i].type, sdef->elements[i].name); } - - /* bound flag */ - def = mputstr(def, " boolean bound_flag;\n"); /* default constructor */ def = mputprintf(def, "public:\n" " %s();\n", name); src = mputprintf(src, "%s::%s()\n" "{\n" - " bound_flag = FALSE;\n" "}\n\n", name, name); /* constructor by fields */ @@ -3164,7 +3177,6 @@ void defRecordClass1(const struct_def *sdef, output_struct *output) } src = mputstr(src, "\n" "{\n" - " bound_flag = TRUE;\n" "}\n\n"); /* copy constructor */ @@ -3172,8 +3184,7 @@ void defRecordClass1(const struct_def *sdef, output_struct *output) src = mputprintf(src, "%s::%s(const %s& other_value)\n" "{\n" "if(!other_value.is_bound()) " - "TTCN_error(\"Copying an unbound value of type %s.\");\n" - "bound_flag = TRUE;\n", + "TTCN_error(\"Copying an unbound value of type %s.\");\n", name, name, name, dispname); for (i = 0; i < sdef->nElements; i++) { src = mputprintf(src, @@ -3196,7 +3207,6 @@ void defRecordClass1(const struct_def *sdef, output_struct *output) "field_%s.clean_up();\n", sdef->elements[i].name); } src = mputstr(src, - "bound_flag = FALSE;\n" "}\n\n"); /* = operator */ @@ -3205,8 +3215,7 @@ void defRecordClass1(const struct_def *sdef, output_struct *output) "{\n" "if (this != &other_value) {\n" " if(!other_value.is_bound()) " - "TTCN_error(\"Assignment of an unbound value of type %s.\");\n" - " bound_flag = TRUE;\n", + "TTCN_error(\"Assignment of an unbound value of type %s.\");\n", name, name, name, dispname); for (i = 0; i < sdef->nElements; i++) { src = mputprintf(src, @@ -3226,7 +3235,6 @@ void defRecordClass1(const struct_def *sdef, output_struct *output) src = mputprintf(src, "boolean %s::operator==(const %s& other_value) const\n" "{\n" - "if (!is_bound() && !other_value.is_bound()) return TRUE;\n" "return ", name, name); for (i = 0; i < sdef->nElements; i++) { if (i > 0) src = mputstr(src, "\n && "); @@ -3245,8 +3253,7 @@ void defRecordClass1(const struct_def *sdef, output_struct *output) " boolean is_bound() const;\n\n"); src = mputprintf(src, "boolean %s::is_bound() const\n" - "{\n" - "if (bound_flag) return TRUE;\n", name); + "{\n", name); for(i=0; i < sdef->nElements; i++) { if(sdef->elements[i].isOptional) { src = mputprintf(src, @@ -3271,8 +3278,7 @@ void defRecordClass1(const struct_def *sdef, output_struct *output) " boolean is_value() const;\n\n"); src = mputprintf(src, "boolean %s::is_value() const\n" - "{\n" - "if (!is_bound()) return FALSE;\n", name); + "{\n", name); for(i=0; i < sdef->nElements; i++) { if(sdef->elements[i].isOptional) { src = mputprintf(src, @@ -3316,18 +3322,17 @@ void defRecordClass1(const struct_def *sdef, output_struct *output) mandatory_fields_count = 0; for (i = 0; i < sdef->nElements; i++) if (!sdef->elements[i].isOptional) mandatory_fields_count++; - - def = mputstr(def, " int size_of() const;\n"); - src = mputprintf(src, - "int %s::size_of() const\n" - "{\n" - " if (!is_bound()) " - "TTCN_error(\"Calculating the size of an unbound record/set value of type %s\");\n" - , name, dispname); - if (sdef->nElements == mandatory_fields_count) { - src = mputprintf(src, " return %lu;\n", (unsigned long) mandatory_fields_count); - } - else { + + if(sdef->nElements == mandatory_fields_count){ + def = mputprintf(def, + " inline int size_of() const\n" + " {return %lu;}\n", (unsigned long) mandatory_fields_count); + }else{ + def = mputstr(def, " int size_of() const;\n"); + src = mputprintf(src, + "int %s::size_of() const\n" + "{\n", + name); src = mputprintf(src, " int ret_val = %lu;\n", (unsigned long) mandatory_fields_count); for (i = 0; i < sdef->nElements; i++) @@ -3335,9 +3340,10 @@ void defRecordClass1(const struct_def *sdef, output_struct *output) src = mputprintf(src, " if (field_%s.ispresent()) ret_val++;\n", sdef->elements[i].name); - src = mputstr(src, " return ret_val;\n"); + src = mputstr(src, + " return ret_val;\n" + "}\n\n"); } - src = mputstr(src, "}\n\n"); /* log function */ def = mputstr(def, " void log() const;\n"); @@ -3362,7 +3368,6 @@ void defRecordClass1(const struct_def *sdef, output_struct *output) src = mputprintf (src, "void %s::set_param(Module_Param& param)\n{\n" - " bound_flag = TRUE;\n" " if (dynamic_cast<Module_Param_Name*>(param.get_id()) != NULL &&\n" " param.get_id()->next_name()) {\n" // Haven't reached the end of the module parameter name @@ -3491,11 +3496,8 @@ void defRecordClass1(const struct_def *sdef, output_struct *output) /* text encoder function */ def = mputstr(def, " void encode_text(Text_Buf& text_buf) const;\n"); - src = mputprintf(src, - "void %s::encode_text(Text_Buf& text_buf) const\n{\n" - "if (!is_bound()) " - "TTCN_error(\"Text encoder: Encoding an unbound record/set value of type %s.\");\n" - , name, dispname); + src = mputprintf(src,"void %s::encode_text(Text_Buf& text_buf) const\n{\n", + name); for (i = 0; i < sdef->nElements; i++) { src = mputprintf(src, "field_%s.encode_text(text_buf);\n", sdef->elements[i].name); @@ -3504,9 +3506,8 @@ void defRecordClass1(const struct_def *sdef, output_struct *output) /* text decoder function */ def = mputstr(def, " void decode_text(Text_Buf& text_buf);\n"); - src = mputprintf(src, - "void %s::decode_text(Text_Buf& text_buf)\n{\n" - "bound_flag = TRUE;\n", name); + src = mputprintf(src, "void %s::decode_text(Text_Buf& text_buf)\n{\n", + name); for (i = 0; i < sdef->nElements; i++) { src = mputprintf(src, "field_%s.decode_text(text_buf);\n", sdef->elements[i].name); @@ -3580,7 +3581,6 @@ void defRecordClass1(const struct_def *sdef, output_struct *output) "boolean %s::BER_decode_TLV(const TTCN_Typedescriptor_t& p_td," " const ASN_BER_TLV_t& p_tlv, unsigned L_form)\n" "{\n" - " bound_flag = TRUE;\n" " BER_chk_descr(p_td);\n" " ASN_BER_TLV_t stripped_tlv;\n" " BER_decode_strip_tags(*p_td.ber, p_tlv, L_form, stripped_tlv);\n" @@ -3782,7 +3782,6 @@ void defRecordClass1(const struct_def *sdef, output_struct *output) "void %s::BER_decode_opentypes(TTCN_Type_list& p_typelist," " unsigned L_form)\n" "{\n" - " bound_flag = TRUE;\n" " p_typelist.push(this);\n" " TTCN_EncDec_ErrorContext ec_0(\"Component '\");\n" " TTCN_EncDec_ErrorContext ec_1;\n" @@ -3869,7 +3868,6 @@ void defRecordClass1(const struct_def *sdef, output_struct *output) src = mputprintf(src, "int %s::TEXT_decode(const TTCN_Typedescriptor_t& p_td," " TTCN_Buffer& p_buf, Limit_Token_List& limit, boolean no_err, boolean){\n" - " bound_flag = TRUE;\n" " int decoded_length=0;\n" " int decoded_field_length=0;\n" " size_t pos=p_buf.get_pos();\n" @@ -4135,7 +4133,6 @@ void defRecordClass1(const struct_def *sdef, output_struct *output) src = mputprintf(src, "int %s::TEXT_decode(const TTCN_Typedescriptor_t& p_td," " TTCN_Buffer& p_buf, Limit_Token_List& limit, boolean no_err, boolean){\n" - " bound_flag = TRUE;\n" " int decoded_length=0;\n" " int decoded_field_length=0;\n" "%s" @@ -4418,10 +4415,10 @@ void defRecordClass1(const struct_def *sdef, output_struct *output) " else if (JSON_TOKEN_OBJECT_START != j_token) {\n" " return JSON_ERROR_INVALID_TOKEN;\n" " }\n" - " bound_flag = TRUE;\n\n" , name); boolean has_metainfo_enabled = FALSE; for (i = 0; i < sdef->nElements; ++i) { + src = mputprintf(src, " boolean %s_found = FALSE;\n", sdef->elements[i].name); if (sdef->elements[i].jsonMetainfoUnbound) { // initialize meta info states src = mputprintf(src, @@ -4461,8 +4458,10 @@ void defRecordClass1(const struct_def *sdef, output_struct *output) src = mputprintf(src, // check field name "if (%d == name_len && 0 == strncmp(fld_name, \"%s\", name_len)) {\n" + " %s_found = TRUE;\n" , (int)strlen(sdef->elements[i].jsonAlias ? sdef->elements[i].jsonAlias : sdef->elements[i].dispname) - , sdef->elements[i].jsonAlias ? sdef->elements[i].jsonAlias : sdef->elements[i].dispname); + , sdef->elements[i].jsonAlias ? sdef->elements[i].jsonAlias : sdef->elements[i].dispname + , sdef->elements[i].name); if (has_metainfo_enabled) { src = mputstr(src, " if (is_metainfo) {\n"); if (sdef->elements[i].jsonMetainfoUnbound) { @@ -4571,7 +4570,7 @@ void defRecordClass1(const struct_def *sdef, output_struct *output) , sdef->elements[i].name, sdef->elements[i].dispname); } src = mputprintf(src, - "if (!field_%s.is_bound()) {\n" + "if (!%s_found) {\n" , sdef->elements[i].name); if (sdef->elements[i].jsonDefaultValue) { src = mputprintf(src, @@ -6145,7 +6144,7 @@ static void defEmptyRecordClass(const struct_def *sdef, "// written by %s in " __FILE__ " at %d\n" #endif "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" " int e_xer = is_exer(p_flavor);\n" " bound_flag = true;\n" @@ -6824,8 +6823,7 @@ void defRecordClass2(const struct_def *sdef, output_struct *output) src = mputprintf(src, "%s::%s(const %s& other_value) : Record_Type(other_value)\n", name, name, name); src = mputstr(src, "{\n" " if(!other_value.is_bound()) " - "TTCN_error(\"Copying an unbound record/set value.\");\n" - "bound_flag = TRUE;\n"); + "TTCN_error(\"Copying an unbound record/set value.\");\n"); for (i = 0; i < sdef->nElements; i++) { src = mputprintf(src, "if (other_value.field_%s.is_bound() )\n" @@ -6870,7 +6868,6 @@ void defRecordClass2(const struct_def *sdef, output_struct *output) src = mputstr(src, "\n" "{\n" "init_vec();\n" - "bound_flag = TRUE;\n" "}\n\n"); } else { /* constructor from null */ def = mputprintf(def, " %s(null_type) {bound_flag = TRUE;}\n", name); diff --git a/compiler2/record_of.c b/compiler2/record_of.c index e72d8d99e8159a649f82a7f7d19f0354c8057fdf..8ac681cd30e91124107e72633553808970cd72d9 100644 --- a/compiler2/record_of.c +++ b/compiler2/record_of.c @@ -1373,7 +1373,7 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output) "// written by %s in " __FILE__ " at %d\n" #endif "int %s::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& p_reader, " - "unsigned int p_flavor, embed_values_dec_struct_t* emb_val)\n{\n" + "unsigned int p_flavor, unsigned int p_flavor2, embed_values_dec_struct_t* emb_val)\n{\n" " boolean e_xer = is_exer(p_flavor);\n" " int xerbits = p_td.xer_bits;\n" " if (p_flavor & XER_TOPLEVEL) xerbits &= ~UNTAGGED;\n" @@ -1453,7 +1453,7 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output) /* Don't move to the #text, that's the callee's responsibility. */ /* The call to the non-const operator[] creates a new element object, * then we call its XER_decode with the temporary XML reader. */ - " (*this)[val_ptr->n_elements].XER_decode(*p_td.oftype_descr, reader_2, p_flavor, 0);\n" + " (*this)[val_ptr->n_elements].XER_decode(*p_td.oftype_descr, reader_2, p_flavor, p_flavor2, 0);\n" " if (p_flavor & EXIT_ON_ERROR && !(*this)[val_ptr->n_elements - 1].is_bound()) {\n" " if (1 == val_ptr->n_elements) {\n" // Failed to decode even the first element @@ -1515,10 +1515,10 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output) " }\n" " ec_1.set_msg(\"%d: \", val_ptr->n_elements);\n" /* The call to the non-const operator[] creates the element */ - " (*this)[val_ptr->n_elements].XER_decode(*p_td.oftype_descr, p_reader, p_flavor, emb_val);\n" - " if (0 != emb_val && !own_tag && val_ptr->n_elements > 1) {\n" - " ++emb_val->embval_index;\n" - " }\n" + " (*this)[val_ptr->n_elements].XER_decode(*p_td.oftype_descr, p_reader, p_flavor, p_flavor2, emb_val);\n" + " }\n" + " if (0 != emb_val && !own_tag && val_ptr->n_elements > 1) {\n" + " ++emb_val->embval_index;\n" " }\n" " }\n" " else if (XML_READER_TYPE_END_ELEMENT == type) {\n" @@ -1563,10 +1563,19 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output) " return -1;\n" " }\n\n" " int enc_len = p_tok.put_next_token(JSON_TOKEN_ARRAY_START, NULL);\n" - " for(int i = 0; i < val_ptr->n_elements; ++i) {\n" - " int ret_val = (*this)[i].JSON_encode(*p_td.oftype_descr, p_tok);\n" - " if (0 > ret_val) break;\n" - " enc_len += ret_val;\n" + " for (int i = 0; i < val_ptr->n_elements; ++i) {\n" + " if (NULL != p_td.json && p_td.json->metainfo_unbound && !(*this)[i].is_bound()) {\n" + // unbound elements are encoded as { "metainfo []" : "unbound" } + " enc_len += p_tok.put_next_token(JSON_TOKEN_OBJECT_START, NULL);\n" + " enc_len += p_tok.put_next_token(JSON_TOKEN_NAME, \"metainfo []\");\n" + " enc_len += p_tok.put_next_token(JSON_TOKEN_STRING, \"\\\"unbound\\\"\");\n" + " enc_len += p_tok.put_next_token(JSON_TOKEN_OBJECT_END, NULL);\n" + " }\n" + " else {\n" + " int ret_val = (*this)[i].JSON_encode(*p_td.oftype_descr, p_tok);\n" + " if (0 > ret_val) break;\n" + " enc_len += ret_val;\n" + " }\n" " }\n" " enc_len += p_tok.put_next_token(JSON_TOKEN_ARRAY_END, NULL);\n" " return enc_len;\n" @@ -1587,10 +1596,34 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output) " return JSON_ERROR_INVALID_TOKEN;\n" " }\n\n" " set_size(0);\n" - " while (true) {\n" + " for (int nof_elements = 0; true; ++nof_elements) {\n" " size_t buf_pos = p_tok.get_buf_pos();\n" + " int ret_val;\n" + " if (NULL != p_td.json && p_td.json->metainfo_unbound) {\n" + // check for metainfo object + " ret_val = p_tok.get_next_token(&token, NULL, NULL);\n" + " if (JSON_TOKEN_OBJECT_START == token) {\n" + " char* value = NULL;\n" + " size_t value_len = 0;\n" + " ret_val += p_tok.get_next_token(&token, &value, &value_len);\n" + " if (JSON_TOKEN_NAME == token && 11 == value_len &&\n" + " 0 == strncmp(value, \"metainfo []\", 11)) {\n" + " ret_val += p_tok.get_next_token(&token, &value, &value_len);\n" + " if (JSON_TOKEN_STRING == token && 9 == value_len &&\n" + " 0 == strncmp(value, \"\\\"unbound\\\"\", 9)) {\n" + " ret_val = p_tok.get_next_token(&token, NULL, NULL);\n" + " if (JSON_TOKEN_OBJECT_END == token) {\n" + " dec_len += ret_val;\n" + " continue;\n" + " }\n" + " }\n" + " }\n" + " }\n" + // metainfo object not found, jump back and let the element type decode it + " p_tok.set_buf_pos(buf_pos);\n" + " }\n" " %s* val = new %s;\n" - " int ret_val = val->JSON_decode(*p_td.oftype_descr, p_tok, p_silent);\n" + " ret_val = val->JSON_decode(*p_td.oftype_descr, p_tok, p_silent);\n" " if (JSON_ERROR_INVALID_TOKEN == ret_val) {\n" " p_tok.set_buf_pos(buf_pos);\n" " delete val;\n" @@ -1604,9 +1637,9 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output) " return JSON_ERROR_FATAL;\n" " }\n" " val_ptr->value_elements = (%s**)reallocate_pointers(\n" - " (void**)val_ptr->value_elements, val_ptr->n_elements, val_ptr->n_elements + 1);\n" - " val_ptr->value_elements[val_ptr->n_elements] = val;\n" - " val_ptr->n_elements++;\n" + " (void**)val_ptr->value_elements, val_ptr->n_elements, nof_elements + 1);\n" + " val_ptr->value_elements[nof_elements] = val;\n" + " val_ptr->n_elements = nof_elements + 1;\n" " dec_len += ret_val;\n" " }\n\n" " dec_len += p_tok.get_next_token(&token, NULL, NULL);\n" @@ -2849,7 +2882,7 @@ void defRecordOfClassMemAllocOptimized(const struct_of_def *sdef, output_struct "// written by %s in " __FILE__ " at %d\n" #endif "int %s::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& p_reader, " - "unsigned int p_flavor, embed_values_dec_struct_t* emb_val)\n{\n" + "unsigned int p_flavor, unsigned int p_flavor2, embed_values_dec_struct_t* emb_val)\n{\n" " boolean e_xer = is_exer(p_flavor);\n" " int xerbits = p_td.xer_bits;\n" " if (p_flavor & XER_TOPLEVEL) xerbits &= ~UNTAGGED;\n" @@ -2926,7 +2959,7 @@ void defRecordOfClassMemAllocOptimized(const struct_of_def *sdef, output_struct /* Don't move to the #text, that's the callee's responsibility. */ /* The call to the non-const operator[] creates a new element object, * then we call its XER_decode with the temporary XML reader. */ - " (*this)[n_elements].XER_decode(*p_td.oftype_descr, reader_2, p_flavor, 0);\n" + " (*this)[n_elements].XER_decode(*p_td.oftype_descr, reader_2, p_flavor, p_flavor2, 0);\n" " if (p_flavor & EXIT_ON_ERROR && !(*this)[n_elements - 1].is_bound()) {\n" " if (1 == n_elements) {\n" // Failed to decode even the first element @@ -2987,10 +3020,10 @@ void defRecordOfClassMemAllocOptimized(const struct_of_def *sdef, output_struct " break;\n" " }\n" /* The call to the non-const operator[] creates the element */ - " operator [](n_elements).XER_decode(*p_td.oftype_descr, p_reader, p_flavor, emb_val);\n" - " if (0 != emb_val && !own_tag && n_elements > 1) {\n" - " ++emb_val->embval_index;\n" - " }\n" + " operator [](n_elements).XER_decode(*p_td.oftype_descr, p_reader, p_flavor, p_flavor2, emb_val);\n" + " }\n" + " if (0 != emb_val && !own_tag && n_elements > 1) {\n" + " ++emb_val->embval_index;\n" " }\n" " }\n" " else if (XML_READER_TYPE_END_ELEMENT == type) {\n" @@ -3032,10 +3065,19 @@ void defRecordOfClassMemAllocOptimized(const struct_of_def *sdef, output_struct " return -1;\n" " }\n\n" " int enc_len = p_tok.put_next_token(JSON_TOKEN_ARRAY_START, NULL);\n" - " for(int i = 0; i < n_elements; ++i) {\n" - " int ret_val = value_elements[i].JSON_encode(*p_td.oftype_descr, p_tok);\n" - " if (0 > ret_val) break;\n" - " enc_len += ret_val;\n" + " for (int i = 0; i < n_elements; ++i) {\n" + " if (NULL != p_td.json && p_td.json->metainfo_unbound && !value_elements[i].is_bound()) {\n" + // unbound elements are encoded as { "metainfo []" : "unbound" } + " enc_len += p_tok.put_next_token(JSON_TOKEN_OBJECT_START, NULL);\n" + " enc_len += p_tok.put_next_token(JSON_TOKEN_NAME, \"metainfo []\");\n" + " enc_len += p_tok.put_next_token(JSON_TOKEN_STRING, \"\\\"unbound\\\"\");\n" + " enc_len += p_tok.put_next_token(JSON_TOKEN_OBJECT_END, NULL);\n" + " }\n" + " else {\n" + " int ret_val = value_elements[i].JSON_encode(*p_td.oftype_descr, p_tok);\n" + " if (0 > ret_val) break;\n" + " enc_len += ret_val;\n" + " }\n" " }\n" " enc_len += p_tok.put_next_token(JSON_TOKEN_ARRAY_END, NULL);\n" " return enc_len;\n" @@ -3056,10 +3098,34 @@ void defRecordOfClassMemAllocOptimized(const struct_of_def *sdef, output_struct " return JSON_ERROR_INVALID_TOKEN;\n" " }\n\n" " set_size(0);\n" - " while (true) {\n" + " for (int nof_elements = 0; true; ++nof_elements) {\n" " size_t buf_pos = p_tok.get_buf_pos();\n" + " int ret_val;\n" + " if (NULL != p_td.json && p_td.json->metainfo_unbound) {\n" + // check for metainfo object + " ret_val = p_tok.get_next_token(&token, NULL, NULL);\n" + " if (JSON_TOKEN_OBJECT_START == token) {\n" + " char* value = NULL;\n" + " size_t value_len = 0;\n" + " ret_val += p_tok.get_next_token(&token, &value, &value_len);\n" + " if (JSON_TOKEN_NAME == token && 11 == value_len &&\n" + " 0 == strncmp(value, \"metainfo []\", 11)) {\n" + " ret_val += p_tok.get_next_token(&token, &value, &value_len);\n" + " if (JSON_TOKEN_STRING == token && 9 == value_len &&\n" + " 0 == strncmp(value, \"\\\"unbound\\\"\", 9)) {\n" + " ret_val = p_tok.get_next_token(&token, NULL, NULL);\n" + " if (JSON_TOKEN_OBJECT_END == token) {\n" + " dec_len += ret_val;\n" + " continue;\n" + " }\n" + " }\n" + " }\n" + " }\n" + // metainfo object not found, jump back and let the element type decode it + " p_tok.set_buf_pos(buf_pos);\n" + " }\n" " %s val;\n" - " int ret_val = val.JSON_decode(*p_td.oftype_descr, p_tok, p_silent);\n" + " ret_val = val.JSON_decode(*p_td.oftype_descr, p_tok, p_silent);\n" " if (JSON_ERROR_INVALID_TOKEN == ret_val) {\n" " p_tok.set_buf_pos(buf_pos);\n" " break;\n" @@ -3070,8 +3136,8 @@ void defRecordOfClassMemAllocOptimized(const struct_of_def *sdef, output_struct " }\n" " return JSON_ERROR_FATAL;\n" " }\n" - " set_size(n_elements + 1);\n" - " value_elements[n_elements - 1] = val;\n" + " set_size(nof_elements + 1);\n" + " value_elements[nof_elements] = val;\n" " dec_len += ret_val;\n" " }\n\n" " dec_len += p_tok.get_next_token(&token, NULL, NULL);\n" diff --git a/compiler2/ttcn3/AST_ttcn3.cc b/compiler2/ttcn3/AST_ttcn3.cc index 67be6443c10ef033b7e1ec356f0b67a8a1b15350..bed275f0f56eda64d4d94dc03e8159af2d8c5da1 100644 --- a/compiler2/ttcn3/AST_ttcn3.cc +++ b/compiler2/ttcn3/AST_ttcn3.cc @@ -4376,6 +4376,8 @@ namespace Ttcn { // the object is initialized by the constructor str = mputprintf(str, "%s %s(%s);\n", type_genname_str, genname_str, body->get_single_expr(false).c_str()); + // make sure the template's code is not generated twice (TR: HU56425) + body->set_code_generated(); } else { // the default constructor is used str = mputprintf(str, "%s %s;\n", type_genname_str, genname_str); diff --git a/compiler2/ttcn3/TtcnTemplate.cc b/compiler2/ttcn3/TtcnTemplate.cc index c136fccf6c9b86ab9ad1f8b1b2e371bdbd5f2b71..d4b86c666b0d56917ebaf3f03cbb99b5230c939c 100644 --- a/compiler2/ttcn3/TtcnTemplate.cc +++ b/compiler2/ttcn3/TtcnTemplate.cc @@ -731,6 +731,7 @@ namespace Ttcn { bool allow_fewer = false; switch (my_governor->get_typetype()) { case Type::T_SEQ_T: case Type::T_SET_T: + case Type::T_SEQ_A: case Type::T_SET_A: allow_fewer = true; break; case Type::T_SIGNATURE: // be precise @@ -1810,6 +1811,7 @@ namespace Ttcn { if (t->templatetype == SPECIFIC_VALUE) break; else if (!refch.add(t->get_fullname())) goto end; else if (t->templatetype != TEMPLATE_REFD) break; + t->u.ref.ref->get_refd_assignment(true); // make sure the parameter list is checked ActualParList *parlist = t->u.ref.ref->get_parlist(); if (parlist) parlist->chk_recursions(refch); Template *t_refd = t->get_template_refd(&refch); diff --git a/compiler2/ttcn3/compiler.l b/compiler2/ttcn3/compiler.l index 063baffe5e181ddb8b09af0a9d4bc44ed97dbc03..1915fbf254e75b2d4ca4960ef052ca0343896518 100644 --- a/compiler2/ttcn3/compiler.l +++ b/compiler2/ttcn3/compiler.l @@ -495,13 +495,18 @@ with RETURN(WithKeyword); xor RETURN(XorKeyword); xor4b RETURN(Xor4bKeyword); + /* modifier keywords */ + +"@nocase" RETURN(NocaseKeyword); +"@lazy" RETURN(LazyKeyword); + /* special TITAN specific keywords */ "@try" RETURN(TitanSpecificTryKeyword); "@catch" RETURN(TitanSpecificCatchKeyword); -"@lazy" RETURN(TitanSpecificLazyKeyword); "@profiler" RETURN(TitanSpecificProfilerKeyword); + /* Predefined function identifiers */ bit2hex RETURN(bit2hexKeyword); diff --git a/compiler2/ttcn3/compiler.y b/compiler2/ttcn3/compiler.y index 65dca47a4a65e589b5210f6fe7e6a739d0d4746d..b7b45b6a07598f863378c5ec14cb4d4c5959bd46 100644 --- a/compiler2/ttcn3/compiler.y +++ b/compiler2/ttcn3/compiler.y @@ -702,10 +702,13 @@ static const string anyname("anytype"); %token XorKeyword %token Xor4bKeyword +/* modifier keywords */ +%token NocaseKeyword +%token LazyKeyword + /* TITAN specific keywords */ %token TitanSpecificTryKeyword %token TitanSpecificCatchKeyword -%token TitanSpecificLazyKeyword %token TitanSpecificProfilerKeyword /* Keywords combined with a leading dot */ @@ -3417,6 +3420,13 @@ CharStringMatch: // 124 $$ = parse_pattern($2, loc); Free($2); } +| PatternKeyword NocaseKeyword PatternChunkList + { + // @nocase is ignored for now + Location loc(infile, @3); + $$ = parse_pattern($3, loc); + Free($3); + } ; PatternChunkList: @@ -7134,7 +7144,7 @@ Reference: // 490 ValueReference optLazyEval: /* empty */ { $$ = false; } -| TitanSpecificLazyKeyword { $$ = true; } +| LazyKeyword { $$ = true; } ; FormalValuePar: // 516 @@ -8453,6 +8463,12 @@ PredefinedOps: $$ = new Value(Value::OPTYPE_REGEXP, $4, $8, $12); $$->set_location(infile, @$); } +| regexpKeyword NocaseKeyword '(' optError TemplateInstance optError ',' optError + TemplateInstance optError ',' optError Expression optError ')' + { + $$ = new Value(Value::OPTYPE_REGEXP, $5, $9, $13); + $$->set_location(infile, @$); + } | regexpKeyword '(' error ')' { Template *t1 = new Template(Template::TEMPLATE_ERROR); @@ -8468,6 +8484,21 @@ PredefinedOps: $$ = new Value(Value::OPTYPE_REGEXP, ti1, ti2, v3); $$->set_location(infile, @$); } +| regexpKeyword NocaseKeyword '(' error ')' + { + Template *t1 = new Template(Template::TEMPLATE_ERROR); + t1->set_location(infile, @4); + TemplateInstance *ti1 = new TemplateInstance(0, 0, t1); + ti1->set_location(infile, @4); + Template *t2 = new Template(Template::TEMPLATE_ERROR); + t2->set_location(infile, @4); + TemplateInstance *ti2 = new TemplateInstance(0, 0, t2); + ti2->set_location(infile, @4); + Value *v3 = new Value(Value::V_ERROR); + v3->set_location(infile, @4); + $$ = new Value(Value::OPTYPE_REGEXP, ti1, ti2, v3); + $$->set_location(infile, @$); + } | encvalueKeyword '(' optError TemplateInstance optError ')' { $$ = new Value(Value::OPTYPE_ENCODE, $4); diff --git a/compiler2/ttcn3/rawAST.l b/compiler2/ttcn3/rawAST.l index ede1166e323463379be9debe1b91e21baad01fe0..5f1eba0d3dfe9319b5226eb5888a16a27ca1d84d 100644 --- a/compiler2/ttcn3/rawAST.l +++ b/compiler2/ttcn3/rawAST.l @@ -680,10 +680,18 @@ void rawAST_error(const char *str) Location loc(infile, yylloc); if (*yytext) { // the most recently parsed token is known - loc.warning("in variant attribute, at or before token `%s': %s", yytext, str); + if (warnings_for_bad_variants) { + loc.warning("in variant attribute, at or before token `%s': %s", yytext, str); + } else { + loc.error("in variant attribute, at or before token `%s': %s", yytext, str); + } } else { // the most recently parsed token is unknown - loc.warning("in variant attribute: %s", str); + if (warnings_for_bad_variants) { + loc.warning("in variant attribute: %s", str); + } else { + loc.error("in variant attribute: %s", str); + } } } diff --git a/compiler2/ttcn3/rawAST.y b/compiler2/ttcn3/rawAST.y index dcc2c8b4621540c5c653af420eaae7db5c0bbd87..0b703d3280c70b9a6879c818bdbd82711778b6ae 100644 --- a/compiler2/ttcn3/rawAST.y +++ b/compiler2/ttcn3/rawAST.y @@ -289,7 +289,7 @@ static void yyprint(FILE *file, int type, const YYSTYPE& value); XDecodeToken %type <cstr> - XTextReservedWord + XTextReservedWord XJsonAlias %type <identifier> XPointerToDef XRecordFieldRef XIdentifierOrReserved @@ -1547,9 +1547,22 @@ XOmitAsNull: ; XNameAs: - XKWname XSpaces XKWas XSpaces XAliasToken { jsonstruct->alias = mcopystr($5); } + XKWname XSpaces XKWas XSpaces XJsonAlias { jsonstruct->alias = mcopystr($5); } ; +XJsonAlias: // include all keywords, so they can be used as aliases for fields, too + XAliasToken { $$ = $1; } +| XKWomit { $$ = "omit"; } +| XKWas { $$ = "as"; } +| XKWnull { $$ = "null"; } +| XKWname { $$ = "name"; } +| XKWvalue { $$ = "value"; } +| XKWdefault { $$ = "default"; } +| XKWextend { $$ = "extend"; } +| XKWmetainfo { $$ = "metainfo"; } +| XKWfor { $$ = "for"; } +| XKWunbound { $$ = "unbound"; } + XAsValue: XKWas XSpaces XKWvalue { jsonstruct->as_value = true; } ; diff --git a/compiler2/ttcn3_makefilegen.1 b/compiler2/ttcn3_makefilegen.1 index 4c41a154c4f362c857c267789032d02536919aa1..fb1c164f9c2124eb1840c69e922ef2453619bca2 100644 --- a/compiler2/ttcn3_makefilegen.1 +++ b/compiler2/ttcn3_makefilegen.1 @@ -3,7 +3,7 @@ ttcn3_makefilegen \- Makefile Generator .SH SYNOPSIS .B ttcn3_makefilegen -.RB "[\| " \-acdfglMpRsw " \|]" +.RB "[\| " \-acdEfglMpRsw " \|]" .RB "[\| " \-e .IR " ETS_name" " \|]" .RB "[\| " \-o @@ -52,6 +52,10 @@ suite) to in the generated Makefile. If this option is omitted, the name of the first TTCN-3 module will be used as default. .TP +.B \-E +Instructs the variant attribute parser to display warnings instead of errors +for unrecognized/erroneous attributes. +.TP .B \-f Forces the Makefile Generator to .I overwrite @@ -64,6 +68,21 @@ only. The resulting Makefile will be smaller and less redundant. It exploits the pattern substitution features of GNU make, which may cause syntax errors with other versions of make. .TP +.BI \-I " path" +Adds the path to the list of search paths. +.I path +must be an +absolute path. Used with the +.B -t +option when the referenced projects +can not be found at the projectRelativeURI location. In that case the +tool will try to find the referenced TPD file using the search paths. +The first TPD file found is taken. If the tpdName attribute is present in + ReferencedProject then the value of tpdName will be used as a TPD name +during search. However if the tpdName attribute is missing then the value +of the name attribute is taken with the .tpd suffix and used during the +search. +.TP .BI \-o " dir|file" Write the Makefile to the given directory or file. The current working directory is the default otherwise. diff --git a/compiler2/union.c b/compiler2/union.c index 6075e77879582f68a6bbfd43e4716e9b8dad39e4..ec34d0ddb3a8a36701aad14581928fa9867670f3 100644 --- a/compiler2/union.c +++ b/compiler2/union.c @@ -366,8 +366,11 @@ void defUnionClass(struct_def const *sdef, output_struct *output) src = mputprintf(src, " if (!strcmp(mp_last->get_id()->get_name(), \"%s\")) {\n" " %s%s().set_param(*mp_last);\n" + // a union's alternative cannot be unbound + " if (!%s%s().is_bound()) clean_up();\n" " return;\n" - " }\n", sdef->elements[i].dispname, at_field, sdef->elements[i].name); + " }\n", sdef->elements[i].dispname, at_field, sdef->elements[i].name, + at_field, sdef->elements[i].name); } src = mputprintf(src, " mp_last->error(\"Field %%s does not exist in type %s.\", mp_last->get_id()->get_name());\n" @@ -1592,7 +1595,7 @@ void defUnionClass(struct_def const *sdef, output_struct *output) #endif src = mputprintf(src, /* XERSTUFF decoder functions for union */ "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" " int e_xer = is_exer(p_flavor);\n" " int type = 0;\n" /* None */ @@ -1709,7 +1712,7 @@ void defUnionClass(struct_def const *sdef, output_struct *output) " ec_2.set_msg(\"%s': \");\n" " if (%s==union_selection) {\n" " matched = %d;\n" - " %s().XER_decode(%s_xer_, p_reader, flavor_1, 0);\n" + " %s().XER_decode(%s_xer_, p_reader, flavor_1, p_flavor2, 0);\n" " }\n" " if (field_%s->is_bound()) break; else clean_up();\n" " }\n", @@ -1766,7 +1769,7 @@ void defUnionClass(struct_def const *sdef, output_struct *output) " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG,\n" " \"Attempting to decode blocked or abstract field.\");\n" " }\n" - " %s%s().XER_decode(%s_xer_, p_reader, flavor_1, 0);\n" + " %s%s().XER_decode(%s_xer_, p_reader, flavor_1, p_flavor2, 0);\n" " if (!%s%s().is_bound()) {\n" " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG, \"Failed to decode field.\");\n" " }\n" @@ -1788,7 +1791,7 @@ void defUnionClass(struct_def const *sdef, output_struct *output) " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG,\n" " \"Attempting to decode blocked or abstract field.\");\n" " }\n" - " %s%s().XER_decode(%s_xer_, p_reader, flavor_1, 0);\n" + " %s%s().XER_decode(%s_xer_, p_reader, flavor_1, p_flavor2, 0);\n" " if (!%s%s().is_bound()) {\n" " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG, \"Failed to decode field.\");\n" " }\n" @@ -1832,8 +1835,8 @@ void defUnionClass(struct_def const *sdef, output_struct *output) if (json_needed) { // JSON encode src = mputprintf(src, - "int %s::JSON_encode(const TTCN_Typedescriptor_t& p_td, JSON_Tokenizer& p_tok) const\n" - "{\n", name); + "int %s::JSON_encode(const TTCN_Typedescriptor_t&%s, JSON_Tokenizer& p_tok) const\n" + "{\n", name, use_runtime_2 ? " p_td" : ""); if (use_runtime_2) { src = mputstr(src, " if (err_descr) return JSON_encode_negtest(err_descr, p_td, p_tok);\n"); } diff --git a/compiler2/xpather.cc b/compiler2/xpather.cc index 829303c1dd4f2caaf4127c16ea5de787a6f74bb5..d1ac0a0c4a3d826a2ba29c666d763645c28393be 100644 --- a/compiler2/xpather.cc +++ b/compiler2/xpather.cc @@ -605,7 +605,7 @@ const char* get_act_config(struct string2_list* cfg, const char* project_name) { return NULL; } -static tpd_result process_tpd_internal(const char *p_tpd_name, const char *actcfg, +static tpd_result process_tpd_internal(const char *p_tpd_name, char* tpdName, const char *actcfg, const char *file_list_path, int *p_argc, char ***p_argv, int *p_optind, char **p_ets_name, char **p_project_name, boolean *p_gflag, boolean *p_sflag, boolean *p_cflag, boolean *p_aflag, boolean *preprocess, @@ -617,11 +617,12 @@ static tpd_result process_tpd_internal(const char *p_tpd_name, const char *actcf struct string_list* prep_defines, struct string_list* prep_undefines, boolean *p_csflag, boolean *p_quflag, boolean* p_dsflag, char** cxxcompiler, char** optlevel, char** optflags, boolean* p_dbflag, boolean* p_drflag, boolean* p_dtflag, boolean* p_dxflag, boolean* p_djflag, boolean* p_fxflag, boolean* p_doflag, boolean* p_gfflag, boolean* p_lnflag, boolean* p_isflag, - boolean* p_asflag, boolean* p_swflag, boolean* p_Yflag, boolean* p_Mflag, struct string_list* solspeclibs, struct string_list* sol8speclibs, + boolean* p_asflag, boolean* p_swflag, boolean* p_Yflag, boolean* p_Mflag, boolean *p_Eflag, boolean* p_diflag, struct string_list* solspeclibs, struct string_list* sol8speclibs, struct string_list* linuxspeclibs, struct string_list* freebsdspeclibs, struct string_list* win32speclibs, char** ttcn3prep, struct string_list* linkerlibs, struct string_list* additionalObjects, struct string_list* linkerlibsearchp, boolean Vflag, boolean Dflag, boolean *p_Zflag, boolean *p_Hflag, char** generatorCommandOutput, struct string2_list* target_placement_list, boolean prefix_workdir, - struct string2_list* run_command_list, map<cstring, int>& seen_tpd_files, struct string2_list* required_configs, struct string_list** profiled_file_list); + struct string2_list* run_command_list, map<cstring, int>& seen_tpd_files, struct string2_list* required_configs, struct string_list** profiled_file_list, + const char **search_paths, size_t n_search_paths); extern "C" tpd_result process_tpd(const char *p_tpd_name, const char *actcfg, const char *file_list_path, int *p_argc, char ***p_argv, @@ -635,18 +636,19 @@ extern "C" tpd_result process_tpd(const char *p_tpd_name, const char *actcfg, struct string_list* prep_defines, struct string_list* prep_undefines, boolean *p_csflag, boolean *p_quflag, boolean* p_dsflag, char** cxxcompiler, char** optlevel, char** optflags, boolean* p_dbflag, boolean* p_drflag, boolean* p_dtflag, boolean* p_dxflag, boolean* p_djflag, boolean* p_fxflag, boolean* p_doflag, boolean* p_gfflag, boolean* p_lnflag, boolean* p_isflag, - boolean* p_asflag, boolean* p_swflag, boolean* p_Yflag, boolean* p_Mflag, struct string_list* solspeclibs, struct string_list* sol8speclibs, + boolean* p_asflag, boolean* p_swflag, boolean* p_Yflag, boolean* p_Mflag, boolean* p_Eflag, boolean* p_diflag, struct string_list* solspeclibs, struct string_list* sol8speclibs, struct string_list* linuxspeclibs, struct string_list* freebsdspeclibs, struct string_list* win32speclibs, char** ttcn3prep, string_list* linkerlibs, string_list* additionalObjects, string_list* linkerlibsearchp, boolean Vflag, boolean Dflag, boolean *p_Zflag, boolean *p_Hflag, char** generatorCommandOutput, struct string2_list* target_placement_list, boolean prefix_workdir, - struct string2_list* run_command_list, struct string2_list* required_configs, struct string_list** profiled_file_list) { + struct string2_list* run_command_list, struct string2_list* required_configs, struct string_list** profiled_file_list, + const char **search_paths, size_t n_search_paths) { map<cstring, int> seen_tpd_files; + char *tpdName = NULL; projGenHelper.setZflag(*p_Zflag); projGenHelper.setWflag(prefix_workdir); projGenHelper.setHflag(*p_Hflag); - - tpd_result success = process_tpd_internal(p_tpd_name, + tpd_result success = process_tpd_internal(p_tpd_name, tpdName, actcfg, file_list_path, p_argc, p_argv, p_optind, p_ets_name, p_project_name, p_gflag, p_sflag, p_cflag, p_aflag, preprocess, p_Rflag, p_lflag, p_mflag, p_Pflag, @@ -657,11 +659,12 @@ extern "C" tpd_result process_tpd(const char *p_tpd_name, const char *actcfg, prep_undefines, p_csflag, p_quflag, p_dsflag, cxxcompiler, optlevel, optflags, p_dbflag, p_drflag, p_dtflag, p_dxflag, p_djflag, p_fxflag, p_doflag, p_gfflag, p_lnflag, p_isflag, - p_asflag, p_swflag, p_Yflag, p_Mflag, solspeclibs, sol8speclibs, + p_asflag, p_swflag, p_Yflag, p_Mflag, p_Eflag, p_diflag, solspeclibs, sol8speclibs, linuxspeclibs, freebsdspeclibs, win32speclibs, ttcn3prep, linkerlibs, additionalObjects, linkerlibsearchp, Vflag, Dflag, p_Zflag, p_Hflag, generatorCommandOutput, target_placement_list, prefix_workdir, - run_command_list, seen_tpd_files, required_configs, profiled_file_list); + run_command_list, seen_tpd_files, required_configs, profiled_file_list, + search_paths, n_search_paths); if (TPD_FAILED == success) exit(EXIT_FAILURE); @@ -693,7 +696,7 @@ extern "C" tpd_result process_tpd(const char *p_tpd_name, const char *actcfg, // process_tpd() may alter these strings; new values will be on the heap. // If process_tpd() preserves the content of such a string (e.g. ets_name), // it must nevertheless make a copy on the heap via mcopystr(). -static tpd_result process_tpd_internal(const char *p_tpd_name, const char *actcfg, +static tpd_result process_tpd_internal(const char *p_tpd_name, char *tpdName, const char *actcfg, const char *file_list_path, int *p_argc, char ***p_argv, int *p_optind, char **p_ets_name, char **p_project_name, boolean *p_gflag, boolean *p_sflag, boolean *p_cflag, boolean *p_aflag, boolean *preprocess, @@ -705,11 +708,12 @@ static tpd_result process_tpd_internal(const char *p_tpd_name, const char *actcf struct string_list* prep_defines, struct string_list* prep_undefines, boolean *p_csflag, boolean *p_quflag, boolean* p_dsflag, char** cxxcompiler, char** optlevel, char** optflags, boolean* p_dbflag, boolean* p_drflag, boolean* p_dtflag, boolean* p_dxflag, boolean* p_djflag, boolean* p_fxflag, boolean* p_doflag, boolean* p_gfflag, boolean* p_lnflag, boolean* p_isflag, - boolean* p_asflag, boolean* p_swflag, boolean* p_Yflag, boolean* p_Mflag, struct string_list* solspeclibs, struct string_list* sol8speclibs, + boolean* p_asflag, boolean* p_swflag, boolean* p_Yflag, boolean* p_Mflag, boolean* p_Eflag, boolean* p_diflag, struct string_list* solspeclibs, struct string_list* sol8speclibs, struct string_list* linuxspeclibs, struct string_list* freebsdspeclibs, struct string_list* win32speclibs, char** ttcn3prep, string_list* linkerlibs, string_list* additionalObjects, string_list* linkerlibsearchp, boolean Vflag, boolean Dflag, boolean *p_Zflag, boolean *p_Hflag, char** generatorCommandOutput, struct string2_list* target_placement_list, boolean prefix_workdir, - struct string2_list* run_command_list, map<cstring, int>& seen_tpd_files, struct string2_list* required_configs, struct string_list** profiled_file_list) + struct string2_list* run_command_list, map<cstring, int>& seen_tpd_files, struct string2_list* required_configs, struct string_list** profiled_file_list, + const char **search_paths, size_t n_search_paths) { tpd_result result = TPD_SUCCESS; // read-only non-pointer aliases @@ -724,7 +728,47 @@ static tpd_result process_tpd_internal(const char *p_tpd_name, const char *actcf assert(local_argc >= local_optind); autostring tpd_dir(get_dir_from_path(p_tpd_name)); - autostring abs_tpd_dir(get_absolute_dir(tpd_dir, NULL)); + autostring abs_tpd_dir(get_absolute_dir(tpd_dir, NULL, FALSE)); + boolean free_name = FALSE; + struct stat buf; + //Only referenced project, when first try is failed, and when not absolute path + if(0 == local_optind && p_tpd_name != NULL && stat(p_tpd_name, &buf) && tpdName != NULL) { + //Find the first search_path that has the tpd + for(size_t i = 0; i<n_search_paths; i++) { + boolean need_slash = search_paths[i][strlen(search_paths[i]) - 1] != '/'; + NOTIFY("Cannot find %s, trying with %s%s%s\n", p_tpd_name, search_paths[i], need_slash ? "/" : "", tpdName); + //Create path + char * prefixed_file_path = (char*)Malloc((strlen(search_paths[i]) + strlen(tpdName) + 1 + need_slash) * sizeof(char)); + strcpy(prefixed_file_path, search_paths[i]); + if(need_slash) { + strcat(prefixed_file_path, "/"); + } + strcat(prefixed_file_path, tpdName); + + tpd_dir = get_dir_from_path(prefixed_file_path); + abs_tpd_dir = get_absolute_dir(tpd_dir, NULL, FALSE); + + if(!stat(prefixed_file_path, &buf)){ + //Ok, tpd found + p_tpd_name = prefixed_file_path; + free_name = TRUE; + NOTIFY("TPD with name %s found at %s.", tpdName, search_paths[i]); + break; + }else { + //tpd not found, continue search + abs_tpd_dir = NULL; + Free(prefixed_file_path); + } + } + //Error if tpd is not found in either search paths + if(NULL == (const char*)abs_tpd_dir) { + //Only write out the name in the error message (without .tpd) + tpdName[strlen(tpdName)-4] ='\0'; + ERROR("Unable to find ReferencedProject with name: %s", (const char*)tpdName); + return TPD_FAILED; + } + } + if (NULL == (const char*)abs_tpd_dir) { ERROR("absolute TPD directory could not be retrieved from %s", (const char*)tpd_dir); return TPD_FAILED; @@ -994,7 +1038,7 @@ static tpd_result process_tpd_internal(const char *p_tpd_name, const char *actcf set_working_dir(real_workdir); // go into the working dir } if (hasWorkDir) { //we created working directory, or its already been created (from a parent makefilegen process maybe) - *abs_work_dir_p = get_absolute_dir(real_workdir, abs_tpd_dir); + *abs_work_dir_p = get_absolute_dir(real_workdir, abs_tpd_dir, TRUE); abs_workdir = (mcopystr(*abs_work_dir_p)); proj_abs_workdir = mcopystr(*abs_work_dir_p); } @@ -1044,9 +1088,12 @@ static tpd_result process_tpd_internal(const char *p_tpd_name, const char *actcf xmlNodeSetPtr nodes = theConfigEx->nodesetval; if (nodes) for (int i = 0; i < nodes->nodeNr; ++i) { xmlNodePtr curnode = nodes->nodeTab[i]; - cstring aa((const char*)curnode->content); - excluded_files.add(aa, *p_project_name); + if (!excluded_files.has_key(aa)) { + excluded_files.add(aa, *p_project_name); + } else { + WARNING("Multiple exclusion of file %s", (const char*)curnode->content); + } } } @@ -1102,7 +1149,7 @@ static tpd_result process_tpd_internal(const char *p_tpd_name, const char *actcf const char* file_path = ruri; expstring_t rel_file_dir = get_dir_from_path(file_path); expstring_t file_name = get_file_from_path(file_path); - expstring_t abs_dir_path = get_absolute_dir(rel_file_dir, abs_tpd_dir); + expstring_t abs_dir_path = get_absolute_dir(rel_file_dir, abs_tpd_dir, TRUE); expstring_t abs_file_name = compose_path_name(abs_dir_path, file_name); if (abs_file_name != NULL) { if (get_path_status(abs_file_name) == PS_FILE) { @@ -1132,7 +1179,7 @@ static tpd_result process_tpd_internal(const char *p_tpd_name, const char *actcf }else { drop = true; ERROR("%s does not exist", abs_file_name); - } + } } if(abs_dir_path != NULL && !drop){ files.add(cpath, ruri); // relativeURI to the TPD location @@ -1181,6 +1228,8 @@ static tpd_result process_tpd_internal(const char *p_tpd_name, const char *actcf xsdbool2boolean(xpathCtx, actcfg, "outParamBoundness", p_Yflag); //not documented, obsolete xsdbool2boolean(xpathCtx, actcfg, "forceOldFuncOutParHandling", p_Yflag); xsdbool2boolean(xpathCtx, actcfg, "omitInValueList", p_Mflag); + xsdbool2boolean(xpathCtx, actcfg, "warningsForBadVariants", p_Eflag); + xsdbool2boolean(xpathCtx, actcfg, "disablePredefinedExternalFolder", p_diflag); projDesc = projGenHelper.getTargetOfProject(*p_project_name); if (projDesc) projDesc->setLinkingStrategy(*p_lflag); @@ -1951,10 +2000,12 @@ static tpd_result process_tpd_internal(const char *p_tpd_name, const char *actcf // Referenced projects { XPathObject subprojects(run_xpath(xpathCtx, - "/TITAN_Project_File_Information/ReferencedProjects/ReferencedProject/attribute::*")); + "/TITAN_Project_File_Information/ReferencedProjects/ReferencedProject")); xmlNodeSetPtr nodes = subprojects->nodesetval; - const char *name = NULL, *projectLocationURI = NULL; + //Go through ReferencedProjects if (nodes) for (int i = 0; i < nodes->nodeNr; ++i) { + const char *name = NULL, *projectLocationURI = NULL; + char *tpdName_loc = NULL; // FIXME: this assumes every ReferencedProject has name and URI. // This is not necessarily so if the referenced project was closed // when the project was exported to TPD. @@ -1963,13 +2014,44 @@ static tpd_result process_tpd_internal(const char *p_tpd_name, const char *actcf // changes the next ReferencedProject to have the projectLocationURI // as the first attribute, it will be joined to the name // of the previous, closed, ReferencedProject. - if (!strcmp((const char*)nodes->nodeTab[i]->name, "name")) { - name = (const char*)nodes->nodeTab[i]->children->content; + + //Go through attributes + for (xmlAttrPtr attr = nodes->nodeTab[i]->properties; attr; attr = attr->next) { + if (!strcmp((const char*)attr->name, "name")) { + name = (const char*)attr->children->content; + } + else if (!strcmp((const char*)attr->name,"projectLocationURI")) { + projectLocationURI = (const char*)attr->children->content; + } + else if (!strcmp((const char*)attr->name, "tpdName")) { + //Allocate memory + tpdName_loc = mcopystr((char*)attr->children->content); + } } - else if (!strcmp((const char*)nodes->nodeTab[i]->name,"projectLocationURI")) { - projectLocationURI = (const char*)nodes->nodeTab[i]->children->content; + //We don't want to orerride an absolute location with -I, tpdName remains NULL + boolean not_abs_path = projectLocationURI && +#if defined WIN32 && defined MINGW + /* On native Windows the absolute path name shall begin with + * a drive letter, colon and backslash */ + (((projectLocationURI[0] < 'A' || projectLocationURI[0] > 'Z') && + (projectLocationURI[0] < 'a' || projectLocationURI[0] > 'z')) || + projectLocationURI[1] != ':' || projectLocationURI[2] != '\\'); +#else + /* On UNIX-like systems the absolute path name shall begin with + * a slash */ + projectLocationURI[0] != '/'; +#endif + if (!tpdName_loc && not_abs_path) { + //Allocate memory: +5 because .tpd + closing 0 + tpdName_loc = (char*)Malloc((strlen(name) + 5) * sizeof(char)); + //Default name: name + .tpd + strcpy(tpdName_loc, name); + strcat(tpdName_loc, ".tpd"); + }else if (!not_abs_path) { + Free(tpdName_loc); + tpdName_loc = NULL; } - + if (name && projectLocationURI) { // collected both // see if there is a specified configuration for the project @@ -1987,16 +2069,21 @@ static tpd_result process_tpd_internal(const char *p_tpd_name, const char *actcf my_quflag = 0, my_dsflag = 0, my_dbflag = 0, my_drflag = 0, my_dtflag = 0, my_dxflag = 0, my_djflag = 0, my_fxflag = 0, my_doflag = 0, my_gfflag = 0, my_lnflag = 0, my_isflag = 0, my_asflag = 0, - my_swflag = 0, my_Yflag = 0, my_Mflag = *p_Mflag; + my_swflag = 0, my_Yflag = 0, my_Mflag = *p_Mflag, my_Eflag = 0, my_diflag = *p_diflag; char *my_ets = NULL; char *my_proj_name = NULL; - autostring abs_projectLocationURI( - compose_path_name(abs_tpd_dir, projectLocationURI)); + autostring abs_projectLocationURI; + if (not_abs_path) { + abs_projectLocationURI = compose_path_name(abs_tpd_dir, projectLocationURI); + } else { + //If absolute directory, then just copy the URI + abs_projectLocationURI = mcopystr(projectLocationURI); + } char* sub_proj_abs_work_dir = NULL; - tpd_result success = process_tpd_internal((const char*)abs_projectLocationURI, + tpd_result success = process_tpd_internal((const char*)abs_projectLocationURI, tpdName_loc, my_actcfg, file_list_path, &my_argc, &my_argv, &my_optind, &my_ets, &my_proj_name, &my_gflag, &my_sflag, &my_cflag, &my_aflag, preprocess, &my_Rflag, &my_lflag, &my_mflag, &my_Pflag, &my_Lflag, recursive, force_overwrite, gen_only_top_level, NULL, &sub_proj_abs_work_dir, @@ -2004,10 +2091,11 @@ static tpd_result process_tpd_internal(const char *p_tpd_name, const char *actcf prep_includes, prep_defines, prep_undefines, &my_csflag, &my_quflag, &my_dsflag, cxxcompiler, optlevel, optflags, &my_dbflag, &my_drflag, &my_dtflag, &my_dxflag, &my_djflag, &my_fxflag, &my_doflag, - &my_gfflag, &my_lnflag, &my_isflag, &my_asflag, &my_swflag, &my_Yflag, &my_Mflag, + &my_gfflag, &my_lnflag, &my_isflag, &my_asflag, &my_swflag, &my_Yflag, &my_Mflag, &my_Eflag, &my_diflag, solspeclibs, sol8speclibs, linuxspeclibs, freebsdspeclibs, win32speclibs, ttcn3prep, linkerlibs, additionalObjects, linkerlibsearchp, Vflag, FALSE, &my_Zflag, - &my_Hflag, NULL, NULL, prefix_workdir, run_command_list, seen_tpd_files, required_configs, profiled_file_list); + &my_Hflag, NULL, NULL, prefix_workdir, run_command_list, seen_tpd_files, required_configs, profiled_file_list, + search_paths, n_search_paths); autostring sub_proj_abs_work_dir_as(sub_proj_abs_work_dir); // ?! @@ -2092,8 +2180,8 @@ static tpd_result process_tpd_internal(const char *p_tpd_name, const char *actcf result = TPD_FAILED; } // else TPD_SKIPPED, keep quiet - - name = projectLocationURI = NULL; // forget both + Free(tpdName_loc); + name = projectLocationURI = tpdName_loc = NULL; // forget all } } // next referenced project } @@ -2122,7 +2210,7 @@ static tpd_result process_tpd_internal(const char *p_tpd_name, const char *actcf const char *fn = files.get_nth_elem(n); // relativeURI to the TPD location autostring dir_n (get_dir_from_path (fn)); autostring file_n(get_file_from_path(fn)); - autostring rel_n (get_absolute_dir(dir_n, abs_tpd_dir)); + autostring rel_n (get_absolute_dir(dir_n, abs_tpd_dir, TRUE)); autostring abs_n (compose_path_name(rel_n, file_n)); if (local_argc == 0) { @@ -2238,6 +2326,10 @@ static tpd_result process_tpd_internal(const char *p_tpd_name, const char *actcf Free(const_cast<char*>(folders.get_nth_elem(i))); } folders.clear(); + + if(free_name) { + Free((char*)p_tpd_name); + } excluded_files.clear(); excluded_folders.clear(); diff --git a/compiler2/xpather.h b/compiler2/xpather.h index a9f6e8c5fa79e64c74a0723c620398ed40e7daa8..51454bc91f53d52205e6d53038bb898544f43d7b 100644 --- a/compiler2/xpather.h +++ b/compiler2/xpather.h @@ -184,6 +184,8 @@ boolean buildObjects(const char* projName, boolean add_referenced); * @param suppresswarnings suppressWarnings -S * @param outparamboundness outParamBoundness -Y * @param omit_in_value_list omitInValueList -M + * @param warnings_for_bad_variants warningsForBadVariants -E + * @param disable_predef_exp_folder disablePredefinedExternalFolder * @param solspeclibs SolarisSpecificLibraries * @param sol8speclibs Solaris8SpecificLibraries * @param linuxspeclibs LinuxSpecificLibraries @@ -198,6 +200,8 @@ boolean buildObjects(const char* projName, boolean add_referenced); * @param target_placement_list a list of (target,placement) strings pairs from the TPD * @param prefix_workdir prefix working directory with project name * @param run_command_list contains the working directories and the makefilegen commands to be called there + * @param search_paths contains the paths that can be tried if a file is not found + * @param n_search_paths contains the size of relative_prefixes * @return TPD_SUCCESS if parsing successful, TPD_SKIPPED if the tpd * was seen already, or TPD_FAILED on error. */ @@ -222,10 +226,10 @@ tpd_result process_tpd(const char *p_tpd_name, const char *actcfg, char** cxxcompiler, char** optlevel, char** optflags, boolean *disableber, boolean *disableraw, boolean *disabletext, boolean *disablexer, boolean *disablejson, boolean *forcexerinasn, boolean *defaultasomit, boolean *gccmessageformat, boolean *linenumber, boolean *includesourceinfo, boolean *addsourcelineinfo, boolean *suppresswarnings, - boolean *outparamboundness, boolean *omit_in_value_list, struct string_list* solspeclibs, struct string_list* sol8speclibs, + boolean *outparamboundness, boolean *omit_in_value_list, boolean *warnings_for_bad_variants, boolean *disable_predef_exp_folder, struct string_list* solspeclibs, struct string_list* sol8speclibs, struct string_list* linuxspeclibs, struct string_list* freebsdspeclibs, struct string_list* win32speclibs, char** ttcn3preprocessor, struct string_list* linkerlibs, struct string_list* additionalObjects, struct string_list* linkerlibsearchpath, boolean Vflag, boolean Dflag, boolean *Zflag, boolean *Hflag, char** generatorCommandOutput, struct string2_list* target_placement_list, boolean prefix_workdir, struct string2_list* run_command_list, - struct string2_list* required_configs, struct string_list** profiled_file_list); + struct string2_list* required_configs, struct string_list** profiled_file_list, const char **search_paths, size_t n_search_paths); #endif /* XPATHER_H_ */ diff --git a/core/ASN_CharacterString.cc b/core/ASN_CharacterString.cc index f1b871527d9e54e389cffa9c2898e9455ee2c5d9..2b5621b289c70939a432cf67ff2687adfd1c6c22 100644 --- a/core/ASN_CharacterString.cc +++ b/core/ASN_CharacterString.cc @@ -803,7 +803,7 @@ int CHARACTER_STRING_identification::XER_encode(const XERdescriptor_t& p_td, } int CHARACTER_STRING_identification::XER_decode(const XERdescriptor_t& p_td, - XmlReaderWrap& reader, unsigned int flavor, embed_values_dec_struct_t*) + XmlReaderWrap& reader, unsigned int flavor, unsigned int flavor2, embed_values_dec_struct_t*) { int exer = is_exer(flavor); // we are supposed to be parked on our element @@ -824,27 +824,27 @@ int CHARACTER_STRING_identification::XER_decode(const XERdescriptor_t& p_td, size_t namelen = strlen(name); switch (namelen) { case 8: // syntaxes - syntaxes().XER_decode(EMBEDDED_PDV_identification_sxs_xer_, reader, flavor, 0); + syntaxes().XER_decode(EMBEDDED_PDV_identification_sxs_xer_, reader, flavor, flavor2, 0); break; case 6: // syntax - syntax().XER_decode(EMBEDDED_PDV_identification_sx_xer_, reader, flavor, 0); + syntax().XER_decode(EMBEDDED_PDV_identification_sx_xer_, reader, flavor, flavor2, 0); break; case 23: // presentation-context-id - presentation__context__id().XER_decode(EMBEDDED_PDV_identification_pci_xer_, reader, flavor, 0); + presentation__context__id().XER_decode(EMBEDDED_PDV_identification_pci_xer_, reader, flavor, flavor2, 0); break; case 19: // context-negotiation - context__negotiation().XER_decode(EMBEDDED_PDV_identification_cn_xer_, reader, flavor, 0); + context__negotiation().XER_decode(EMBEDDED_PDV_identification_cn_xer_, reader, flavor, flavor2, 0); break; case 15: // transfer-syntax - transfer__syntax().XER_decode(EMBEDDED_PDV_identification_ts_xer_, reader, flavor, 0); + transfer__syntax().XER_decode(EMBEDDED_PDV_identification_ts_xer_, reader, flavor, flavor2, 0); break; case 5: // fixed - fixed().XER_decode(EMBEDDED_PDV_identification_fix_xer_, reader, flavor, 0); + fixed().XER_decode(EMBEDDED_PDV_identification_fix_xer_, reader, flavor, flavor2, 0); break; default: @@ -1776,7 +1776,7 @@ int CHARACTER_STRING_identification_syntaxes::XER_encode(const XERdescriptor_t& } int CHARACTER_STRING_identification_syntaxes::XER_decode( - const XERdescriptor_t& /*p_td*/, XmlReaderWrap& reader, unsigned int flavor, embed_values_dec_struct_t*) + const XERdescriptor_t& /*p_td*/, XmlReaderWrap& reader, unsigned int flavor, unsigned int flavor2, embed_values_dec_struct_t*) { // we stand on <syntaxes>, move ahead first for (int success = reader.Read(); success == 1; success = reader.Read()) { @@ -1786,8 +1786,8 @@ int CHARACTER_STRING_identification_syntaxes::XER_decode( break; } // FIXME this assumes the right element - field_abstract.XER_decode(EMBEDDED_PDV_identification_sxs_abs_xer_, reader, flavor, 0); - field_transfer.XER_decode(EMBEDDED_PDV_identification_sxs_xfr_xer_, reader, flavor, 0); + field_abstract.XER_decode(EMBEDDED_PDV_identification_sxs_abs_xer_, reader, flavor, flavor2, 0); + field_transfer.XER_decode(EMBEDDED_PDV_identification_sxs_xfr_xer_, reader, flavor, flavor2, 0); for (int success = 1; success == 1; success = reader.Read()) { int type = reader.NodeType(); @@ -2499,7 +2499,7 @@ int CHARACTER_STRING_identification_context__negotiation::XER_encode(const XERde } int CHARACTER_STRING_identification_context__negotiation::XER_decode( - const XERdescriptor_t& p_td, XmlReaderWrap& reader, unsigned int flavor, embed_values_dec_struct_t*) + const XERdescriptor_t& p_td, XmlReaderWrap& reader, unsigned int flavor, unsigned int flavor2, embed_values_dec_struct_t*) { int exer = is_exer(flavor); int type = reader.NodeType(), depth = -1; @@ -2510,8 +2510,8 @@ int CHARACTER_STRING_identification_context__negotiation::XER_decode( depth = reader.Depth(); success = reader.Read(); } - field_presentation__context__id.XER_decode(EMBEDDED_PDV_identification_cn_pci_xer_, reader, flavor, 0); - field_transfer__syntax .XER_decode(EMBEDDED_PDV_identification_cn_tsx_xer_, reader, flavor, 0); + field_presentation__context__id.XER_decode(EMBEDDED_PDV_identification_cn_pci_xer_, reader, flavor, flavor2, 0); + field_transfer__syntax .XER_decode(EMBEDDED_PDV_identification_cn_tsx_xer_, reader, flavor, flavor2, 0); for (; success == 1; success = reader.Read()) { type = reader.NodeType(); if (XML_READER_TYPE_END_ELEMENT == type) { @@ -3256,7 +3256,7 @@ void CHARACTER_STRING::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_ if (type==XML_READER_TYPE_ELEMENT) break; } - XER_decode(*p_td.xer, reader, XER_coding, 0); + XER_decode(*p_td.xer, reader, XER_coding, XER_NONE, 0); size_t bytes = reader.ByteConsumed(); p_buf.set_pos(bytes); break;} @@ -3345,7 +3345,7 @@ int CHARACTER_STRING::XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf } int CHARACTER_STRING::XER_decode(const XERdescriptor_t& p_td, - XmlReaderWrap& reader, unsigned int flavor, embed_values_dec_struct_t*) + XmlReaderWrap& reader, unsigned int flavor, unsigned int flavor2, embed_values_dec_struct_t*) { int exer = is_exer(flavor); int success = reader.Ok(), depth = -1, type; @@ -3358,13 +3358,13 @@ int CHARACTER_STRING::XER_decode(const XERdescriptor_t& p_td, break; } } - field_identification .XER_decode(CHARACTER_STRING_identification_xer_ , reader, flavor, 0); - field_data__value__descriptor.XER_decode(CHARACTER_STRING_data_value_descriptor_xer_, reader, flavor, 0); + field_identification .XER_decode(CHARACTER_STRING_identification_xer_ , reader, flavor, flavor2, 0); + field_data__value__descriptor.XER_decode(CHARACTER_STRING_data_value_descriptor_xer_, reader, flavor, flavor2, 0); if (field_data__value__descriptor.is_value()) { TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG, "data-value-descriptor not allowed for EMBEDDED PDV"); } - field_string__value .XER_decode(CHARACTER_STRING_data_value_xer_ , reader, flavor, 0); + field_string__value .XER_decode(CHARACTER_STRING_data_value_xer_ , reader, flavor, flavor2, 0); for (success = reader.Read(); success == 1; success = reader.Read()) { type = reader.NodeType(); if (XML_READER_TYPE_END_ELEMENT == type) { diff --git a/core/ASN_CharacterString.hh b/core/ASN_CharacterString.hh index f1cd8f66634538002456651f3552ef6e8bd9f471..1ca8aad637ca27e35898d79cb2a8f237f2011dff 100644 --- a/core/ASN_CharacterString.hh +++ b/core/ASN_CharacterString.hh @@ -89,7 +89,7 @@ public: int XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const; int XER_decode(const XERdescriptor_t& p_td, - XmlReaderWrap& reader, unsigned int flavor, embed_values_dec_struct_t*); + XmlReaderWrap& reader, unsigned int flavor, unsigned int flavor2, embed_values_dec_struct_t*); private: boolean BER_decode_set_selection(const ASN_BER_TLV_t& p_tlv); public: @@ -213,7 +213,7 @@ public: int XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const; int XER_decode(const XERdescriptor_t& p_td, - XmlReaderWrap& reader, unsigned int flavor, embed_values_dec_struct_t*); + XmlReaderWrap& reader, unsigned int flavor, unsigned int flavor2, embed_values_dec_struct_t*); }; class CHARACTER_STRING_identification_syntaxes_template : public Base_Template { @@ -322,7 +322,7 @@ public: int XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const; int XER_decode(const XERdescriptor_t& p_td, - XmlReaderWrap& reader, unsigned int flavor, embed_values_dec_struct_t*); + XmlReaderWrap& reader, unsigned int flavor, unsigned int flavor2, embed_values_dec_struct_t*); }; class CHARACTER_STRING_identification_context__negotiation_template : public Base_Template { @@ -438,7 +438,7 @@ public: ASN_BER_TLV_t* BER_encode_TLV(const TTCN_Typedescriptor_t& p_td, unsigned p_coding) const; boolean BER_decode_TLV(const TTCN_Typedescriptor_t& p_td, const ASN_BER_TLV_t& p_tlv, unsigned L_form); int XER_encode(const XERdescriptor_t&, TTCN_Buffer&, unsigned int, int, embed_values_enc_struct_t*) const; - int XER_decode(const XERdescriptor_t&, XmlReaderWrap& reader, unsigned int, embed_values_dec_struct_t*); + int XER_decode(const XERdescriptor_t&, XmlReaderWrap& reader, unsigned int, unsigned int, embed_values_dec_struct_t*); }; class CHARACTER_STRING_template : public Base_Template { diff --git a/core/ASN_EmbeddedPDV.cc b/core/ASN_EmbeddedPDV.cc index c0bb577180582f94899dfef0c3aa6c83621153e1..e068c708d14b921ab40084e1f92e0ea7828f3a3a 100644 --- a/core/ASN_EmbeddedPDV.cc +++ b/core/ASN_EmbeddedPDV.cc @@ -797,7 +797,7 @@ int EMBEDDED_PDV_identification::XER_encode(const XERdescriptor_t& p_td, } int EMBEDDED_PDV_identification::XER_decode(const XERdescriptor_t& p_td, - XmlReaderWrap& reader, unsigned int flavor, embed_values_dec_struct_t*) + XmlReaderWrap& reader, unsigned int flavor, unsigned int flavor2, embed_values_dec_struct_t*) { int exer = is_exer(flavor); // we are supposed to be parked on our element @@ -817,27 +817,27 @@ int EMBEDDED_PDV_identification::XER_decode(const XERdescriptor_t& p_td, size_t namelen = strlen(name); switch (namelen) { case 8: // syntaxes - syntaxes().XER_decode(EMBEDDED_PDV_identification_sxs_xer_, reader, flavor, 0); + syntaxes().XER_decode(EMBEDDED_PDV_identification_sxs_xer_, reader, flavor, flavor2, 0); break; case 6: // syntax - syntax().XER_decode(EMBEDDED_PDV_identification_sx_xer_, reader, flavor, 0); + syntax().XER_decode(EMBEDDED_PDV_identification_sx_xer_, reader, flavor, flavor2, 0); break; case 23: // presentation-context-id - presentation__context__id().XER_decode(EMBEDDED_PDV_identification_pci_xer_, reader, flavor, 0); + presentation__context__id().XER_decode(EMBEDDED_PDV_identification_pci_xer_, reader, flavor, flavor2, 0); break; case 19: // context-negotiation - context__negotiation().XER_decode(EMBEDDED_PDV_identification_cn_xer_, reader, flavor, 0); + context__negotiation().XER_decode(EMBEDDED_PDV_identification_cn_xer_, reader, flavor, flavor2, 0); break; case 15: // transfer-syntax - transfer__syntax().XER_decode(EMBEDDED_PDV_identification_ts_xer_, reader, flavor, 0); + transfer__syntax().XER_decode(EMBEDDED_PDV_identification_ts_xer_, reader, flavor, flavor2, 0); break; case 5: // fixed - fixed().XER_decode(EMBEDDED_PDV_identification_fix_xer_, reader, flavor, 0); + fixed().XER_decode(EMBEDDED_PDV_identification_fix_xer_, reader, flavor, flavor2, 0); break; default: @@ -1778,7 +1778,7 @@ int EMBEDDED_PDV_identification_syntaxes::XER_encode(const XERdescriptor_t& p_td } int EMBEDDED_PDV_identification_syntaxes::XER_decode(const XERdescriptor_t& /*p_td*/, - XmlReaderWrap& reader, unsigned int flavor, embed_values_dec_struct_t*) + XmlReaderWrap& reader, unsigned int flavor, unsigned int flavor2, embed_values_dec_struct_t*) { // we stand on <syntaxes>, move ahead first int type; for (int success = reader.Read(); success == 1; success = reader.Read()) @@ -1789,8 +1789,8 @@ int EMBEDDED_PDV_identification_syntaxes::XER_decode(const XERdescriptor_t& /*p_ break; } // FIXME this assumes the right element - field_abstract.XER_decode(EMBEDDED_PDV_identification_sxs_abs_xer_, reader, flavor, 0); - field_transfer.XER_decode(EMBEDDED_PDV_identification_sxs_xfr_xer_, reader, flavor, 0); + field_abstract.XER_decode(EMBEDDED_PDV_identification_sxs_abs_xer_, reader, flavor, flavor2, 0); + field_transfer.XER_decode(EMBEDDED_PDV_identification_sxs_xfr_xer_, reader, flavor, flavor2, 0); for (int success = 1; success == 1; success = reader.Read()) { type = reader.NodeType(); @@ -2511,7 +2511,7 @@ int EMBEDDED_PDV_identification_context__negotiation::XER_encode(const XERdescri } int EMBEDDED_PDV_identification_context__negotiation::XER_decode( - const XERdescriptor_t& p_td, XmlReaderWrap& reader, unsigned int flavor, embed_values_dec_struct_t*) + const XERdescriptor_t& p_td, XmlReaderWrap& reader, unsigned int flavor, unsigned int flavor2, embed_values_dec_struct_t*) { int exer = is_exer(flavor); int type = reader.NodeType(), depth = -1; @@ -2522,8 +2522,8 @@ int EMBEDDED_PDV_identification_context__negotiation::XER_decode( depth = reader.Depth(); success = reader.Read(); } - field_presentation__context__id.XER_decode(EMBEDDED_PDV_identification_cn_pci_xer_, reader, flavor, 0); - field_transfer__syntax .XER_decode(EMBEDDED_PDV_identification_cn_tsx_xer_, reader, flavor, 0); + field_presentation__context__id.XER_decode(EMBEDDED_PDV_identification_cn_pci_xer_, reader, flavor, flavor2, 0); + field_transfer__syntax .XER_decode(EMBEDDED_PDV_identification_cn_tsx_xer_, reader, flavor, flavor2, 0); for (; success == 1; success = reader.Read()) { type = reader.NodeType(); if (XML_READER_TYPE_END_ELEMENT == type) { @@ -3267,7 +3267,7 @@ void EMBEDDED_PDV::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, if (type==XML_READER_TYPE_ELEMENT) break; } - XER_decode(*p_td.xer, reader, XER_coding, 0); + XER_decode(*p_td.xer, reader, XER_coding, XER_NONE, 0); size_t bytes = reader.ByteConsumed(); p_buf.set_pos(bytes); break;} @@ -3364,7 +3364,7 @@ int EMBEDDED_PDV::XER_encode(const XERdescriptor_t& p_td, return (int)p_buf.get_len() - encoded_length; } -int EMBEDDED_PDV::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, unsigned int flavor, embed_values_dec_struct_t*) +int EMBEDDED_PDV::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, unsigned int flavor, unsigned int flavor2, embed_values_dec_struct_t*) { int exer = is_exer(flavor); int depth = 1, type, success; @@ -3377,13 +3377,13 @@ int EMBEDDED_PDV::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, break; } } - field_identification .XER_decode(EMBEDDED_PDV_identification_xer_ , reader, flavor, 0); - field_data__value__descriptor.XER_decode(EMBEDDED_PDV_data_value_descriptor_xer_, reader, flavor, 0); + field_identification .XER_decode(EMBEDDED_PDV_identification_xer_ , reader, flavor, flavor2, 0); + field_data__value__descriptor.XER_decode(EMBEDDED_PDV_data_value_descriptor_xer_, reader, flavor, flavor2, 0); if (field_data__value__descriptor.is_value()) { TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG, "data-value-descriptor not allowed for EMBEDDED PDV"); } - field_data__value .XER_decode(EMBEDDED_PDV_data_value_xer_ , reader, flavor, 0); + field_data__value .XER_decode(EMBEDDED_PDV_data_value_xer_ , reader, flavor, flavor2, 0); for (success = reader.Read(); success == 1; success = reader.Read()) { type = reader.NodeType(); if (XML_READER_TYPE_END_ELEMENT == type) { diff --git a/core/ASN_EmbeddedPDV.hh b/core/ASN_EmbeddedPDV.hh index 5e0c9aa677436f4b87c6855b6c71342859522ec2..951f7ba9d9e400237bb73588150e18729adea323 100644 --- a/core/ASN_EmbeddedPDV.hh +++ b/core/ASN_EmbeddedPDV.hh @@ -89,7 +89,7 @@ public: int XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const; int XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, - unsigned int flavor, embed_values_dec_struct_t*); + unsigned int flavor, unsigned int flavor2, embed_values_dec_struct_t*); private: boolean BER_decode_set_selection(const ASN_BER_TLV_t& p_tlv); public: @@ -211,7 +211,7 @@ public: ASN_BER_TLV_t* BER_encode_TLV(const TTCN_Typedescriptor_t& p_td, unsigned p_coding) const; boolean BER_decode_TLV(const TTCN_Typedescriptor_t& p_td, const ASN_BER_TLV_t& p_tlv, unsigned L_form); int XER_encode(const XERdescriptor_t&, TTCN_Buffer&, unsigned int, int, embed_values_enc_struct_t*) const; - int XER_decode(const XERdescriptor_t&, XmlReaderWrap& reader, unsigned int, embed_values_dec_struct_t*); + int XER_decode(const XERdescriptor_t&, XmlReaderWrap& reader, unsigned int, unsigned int, embed_values_dec_struct_t*); }; class EMBEDDED_PDV_identification_syntaxes_template : public Base_Template { @@ -318,7 +318,7 @@ public: ASN_BER_TLV_t* BER_encode_TLV(const TTCN_Typedescriptor_t& p_td, unsigned p_coding) const; boolean BER_decode_TLV(const TTCN_Typedescriptor_t& p_td, const ASN_BER_TLV_t& p_tlv, unsigned L_form); int XER_encode(const XERdescriptor_t&, TTCN_Buffer&, unsigned int, int, embed_values_enc_struct_t*) const; - int XER_decode(const XERdescriptor_t&, XmlReaderWrap& reader, unsigned int, embed_values_dec_struct_t*); + int XER_decode(const XERdescriptor_t&, XmlReaderWrap& reader, unsigned int, unsigned int, embed_values_dec_struct_t*); }; class EMBEDDED_PDV_identification_context__negotiation_template : public Base_Template { @@ -431,7 +431,7 @@ public: ASN_BER_TLV_t* BER_encode_TLV(const TTCN_Typedescriptor_t& p_td, unsigned p_coding) const; boolean BER_decode_TLV(const TTCN_Typedescriptor_t& p_td, const ASN_BER_TLV_t& p_tlv, unsigned L_form); int XER_encode(const XERdescriptor_t&, TTCN_Buffer&, unsigned int, int, embed_values_enc_struct_t*) const; - int XER_decode(const XERdescriptor_t&, XmlReaderWrap&, unsigned int, embed_values_dec_struct_t*); + int XER_decode(const XERdescriptor_t&, XmlReaderWrap&, unsigned int, unsigned int, embed_values_dec_struct_t*); }; class EMBEDDED_PDV_template : public Base_Template { diff --git a/core/ASN_External.cc b/core/ASN_External.cc index ff6e0d5d89b87d32dcc702aa7ee52bb8931be470..cf9d90251f51b0697e27ce2fb4653a1fbec73390 100644 --- a/core/ASN_External.cc +++ b/core/ASN_External.cc @@ -105,7 +105,7 @@ namespace { /* anonymous namespace */ int XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const; int XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, - unsigned int flavor, embed_values_dec_struct_t*); + unsigned int flavor, unsigned int flavor2, embed_values_dec_struct_t*); private: boolean BER_decode_set_selection(const ASN_BER_TLV_t& p_tlv); public: @@ -163,7 +163,7 @@ namespace { /* anonymous namespace */ int XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const; int XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, - unsigned int flavor, embed_values_dec_struct_t*); + unsigned int flavor, unsigned int flavor2, embed_values_dec_struct_t*); }; /** Transform the information from the visible format to the encoding format @@ -440,7 +440,7 @@ namespace { /* anonymous namespace */ } int EXTERNALtransfer_encoding::XER_decode(const XERdescriptor_t& p_td, - XmlReaderWrap& reader, unsigned int flavor, embed_values_dec_struct_t*) + XmlReaderWrap& reader, unsigned int flavor, unsigned int flavor2, embed_values_dec_struct_t*) { int exer = is_exer(flavor); int success = reader.Ok(), type, depth = -1; @@ -463,15 +463,15 @@ namespace { /* anonymous namespace */ switch (*name) { case 's': // single-ASN1-type - single__ASN1__type().XER_decode(EXTERNAL_encoding_singleASN_xer_, reader, flavor, 0); + single__ASN1__type().XER_decode(EXTERNAL_encoding_singleASN_xer_, reader, flavor, flavor2, 0); break; case 'o': // octet-aligned - octet__aligned().XER_decode(EXTERNAL_encoding_octet_aligned_xer_, reader, flavor, 0); + octet__aligned().XER_decode(EXTERNAL_encoding_octet_aligned_xer_, reader, flavor, flavor2, 0); break; case 'a': // arbitrary - arbitrary().XER_decode(EXTERNAL_encoding_arbitrary_xer_, reader, flavor, 0); + arbitrary().XER_decode(EXTERNAL_encoding_arbitrary_xer_, reader, flavor, flavor2, 0); break; default: @@ -582,7 +582,7 @@ namespace { /* anonymous namespace */ } int EXTERNALtransfer::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, - unsigned int flavor, embed_values_dec_struct_t*) + unsigned int flavor, unsigned int flavor2, embed_values_dec_struct_t*) { int exer = is_exer(flavor); int success = reader.Ok(), depth = -1; @@ -596,10 +596,10 @@ namespace { /* anonymous namespace */ } } - field_direct__reference .XER_decode(EXTERNAL_direct_reference_xer_ , reader, flavor, 0); - field_indirect__reference .XER_decode(EXTERNAL_indirect_reference_xer_ , reader, flavor, 0); - field_data__value__descriptor.XER_decode(EXTERNAL_data_value_descriptor_xer_, reader, flavor, 0); - field_encoding .XER_decode(EXTERNAL_encoding_xer_ , reader, flavor, 0); + field_direct__reference .XER_decode(EXTERNAL_direct_reference_xer_ , reader, flavor, flavor2, 0); + field_indirect__reference .XER_decode(EXTERNAL_indirect_reference_xer_ , reader, flavor, flavor2, 0); + field_data__value__descriptor.XER_decode(EXTERNAL_data_value_descriptor_xer_, reader, flavor, flavor2, 0); + field_encoding .XER_decode(EXTERNAL_encoding_xer_ , reader, flavor, flavor2, 0); for (success = reader.Read(); success == 1; success = reader.Read()) { int type = reader.NodeType(); @@ -709,10 +709,10 @@ int EXTERNAL::XER_encode(const XERdescriptor_t& p_td, } int EXTERNAL::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, - unsigned int flavor, embed_values_dec_struct_t*) + unsigned int flavor, unsigned int flavor2, embed_values_dec_struct_t*) { EXTERNALtransfer xfer; - xfer.XER_decode(p_td, reader, flavor, 0); + xfer.XER_decode(p_td, reader, flavor, flavor2, 0); transfer(&xfer); return 1; // decode successful } @@ -3469,7 +3469,7 @@ void EXTERNAL::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTC if (type==XML_READER_TYPE_ELEMENT) break; } - XER_decode(*p_td.xer, reader, XER_coding, 0); + XER_decode(*p_td.xer, reader, XER_coding, XER_NONE, 0); size_t bytes = reader.ByteConsumed(); p_buf.set_pos(bytes); break;} diff --git a/core/ASN_External.hh b/core/ASN_External.hh index 609a1ba1f8ac092bf5396064e83bf41e660a6586..f2bcca0ce12a121eb84bba6056cbd274701d0ba4 100644 --- a/core/ASN_External.hh +++ b/core/ASN_External.hh @@ -412,7 +412,7 @@ public: int XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const; int XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, - unsigned int flavor, embed_values_dec_struct_t*); + unsigned int flavor, unsigned int flavor2, embed_values_dec_struct_t*); }; class EXTERNAL_template : public Base_Template { diff --git a/core/ASN_Null.cc b/core/ASN_Null.cc index 36616c1a7c88186d11aea6c2877a0d785bb12984..994b81dda1632bfa8e56da6330fecada2f30b980 100644 --- a/core/ASN_Null.cc +++ b/core/ASN_Null.cc @@ -160,7 +160,7 @@ void ASN_NULL::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, if (type==XML_READER_TYPE_ELEMENT) break; } - XER_decode(*p_td.xer, reader, XER_coding, 0); + XER_decode(*p_td.xer, reader, XER_coding, XER_NONE, 0); size_t bytes = reader.ByteConsumed(); p_buf.set_pos(bytes); break;} @@ -239,7 +239,7 @@ int ASN_NULL::XER_encode(const XERdescriptor_t& p_td, } int ASN_NULL::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, - unsigned int flavor, embed_values_dec_struct_t*) + unsigned int flavor, unsigned int /*flavor2*/, embed_values_dec_struct_t*) { int exer = is_exer(flavor); TTCN_EncDec_ErrorContext ec("While XER decoding NULL type: "); diff --git a/core/ASN_Null.hh b/core/ASN_Null.hh index f2ed45698745d414d07b5081e702b4b4dabba560..cef26477bbfe0965baa55cb333de2d3fbdd62840 100644 --- a/core/ASN_Null.hh +++ b/core/ASN_Null.hh @@ -72,7 +72,7 @@ public: int XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const; int XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, - unsigned int flavor, embed_values_dec_struct_t*); + unsigned int flavor, unsigned int flavor2, embed_values_dec_struct_t*); /** Encodes accordingly to the JSON encoding rules. * Returns the length of the encoded data. */ diff --git a/core/Array.hh b/core/Array.hh index 0db8bc79f3a011cc4694e167023b3e40408d49ab..51606885084c18555755773c787d8f74f2341dad 100644 --- a/core/Array.hh +++ b/core/Array.hh @@ -495,9 +495,9 @@ void VALUE_ARRAY<T_type,array_size,index_offset>::decode( template <typename T_type, unsigned int array_size, int index_offset> int VALUE_ARRAY<T_type,array_size,index_offset>::JSON_encode( - const TTCN_Typedescriptor_t&, JSON_Tokenizer& p_tok) const + const TTCN_Typedescriptor_t& p_td, JSON_Tokenizer& p_tok) const { - if (!is_bound()) { + if (!is_bound() && (NULL == p_td.json || !p_td.json->metainfo_unbound)) { TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND, "Encoding an unbound array value."); return -1; @@ -505,10 +505,19 @@ int VALUE_ARRAY<T_type,array_size,index_offset>::JSON_encode( int enc_len = p_tok.put_next_token(JSON_TOKEN_ARRAY_START, NULL); - for(unsigned int i = 0; i < array_size; ++i) { - int ret_val = array_elements[i].JSON_encode(*get_elem_descr(), p_tok); - if (0 > ret_val) break; - enc_len += ret_val; + for (unsigned int i = 0; i < array_size; ++i) { + if (NULL != p_td.json && p_td.json->metainfo_unbound && !array_elements[i].is_bound()) { + // unbound elements are encoded as { "metainfo []" : "unbound" } + enc_len += p_tok.put_next_token(JSON_TOKEN_OBJECT_START, NULL); + enc_len += p_tok.put_next_token(JSON_TOKEN_NAME, "metainfo []"); + enc_len += p_tok.put_next_token(JSON_TOKEN_STRING, "\"unbound\""); + enc_len += p_tok.put_next_token(JSON_TOKEN_OBJECT_END, NULL); + } + else { + int ret_val = array_elements[i].JSON_encode(*get_elem_descr(), p_tok); + if (0 > ret_val) break; + enc_len += ret_val; + } } enc_len += p_tok.put_next_token(JSON_TOKEN_ARRAY_END, NULL); @@ -517,7 +526,7 @@ int VALUE_ARRAY<T_type,array_size,index_offset>::JSON_encode( template <typename T_type, unsigned int array_size, int index_offset> int VALUE_ARRAY<T_type,array_size,index_offset>::JSON_decode( - const TTCN_Typedescriptor_t&, JSON_Tokenizer& p_tok, boolean p_silent) + const TTCN_Typedescriptor_t& p_td, JSON_Tokenizer& p_tok, boolean p_silent) { json_token_t token = JSON_TOKEN_NONE; int dec_len = p_tok.get_next_token(&token, NULL, NULL); @@ -529,8 +538,33 @@ int VALUE_ARRAY<T_type,array_size,index_offset>::JSON_decode( return JSON_ERROR_INVALID_TOKEN; } - for(unsigned int i = 0; i < array_size; ++i) { - int ret_val = array_elements[i].JSON_decode(*get_elem_descr(), p_tok, p_silent); + for (unsigned int i = 0; i < array_size; ++i) { + size_t buf_pos = p_tok.get_buf_pos(); + int ret_val; + if (NULL != p_td.json && p_td.json->metainfo_unbound) { + // check for metainfo object + ret_val = p_tok.get_next_token(&token, NULL, NULL); + if (JSON_TOKEN_OBJECT_START == token) { + char* value = NULL; + size_t value_len = 0; + ret_val += p_tok.get_next_token(&token, &value, &value_len); + if (JSON_TOKEN_NAME == token && 11 == value_len && + 0 == strncmp(value, "metainfo []", 11)) { + ret_val += p_tok.get_next_token(&token, &value, &value_len); + if (JSON_TOKEN_STRING == token && 9 == value_len && + 0 == strncmp(value, "\"unbound\"", 9)) { + ret_val = p_tok.get_next_token(&token, NULL, NULL); + if (JSON_TOKEN_OBJECT_END == token) { + dec_len += ret_val; + continue; + } + } + } + } + // metainfo object not found, jump back and let the element type decode it + p_tok.set_buf_pos(buf_pos); + } + ret_val = array_elements[i].JSON_decode(*get_elem_descr(), p_tok, p_silent); if (JSON_ERROR_INVALID_TOKEN == ret_val) { JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_ARRAY_ELEM_TOKEN_ERROR, array_size - i, (array_size - i > 1) ? "s" : ""); diff --git a/core/Basetype.cc b/core/Basetype.cc index 37511128f179cb303c7a4f3b7c5ffa30c52aa3b7..68448fb66dcd2abe83c7e9f0bdc49d95ea7f9146 100644 --- a/core/Basetype.cc +++ b/core/Basetype.cc @@ -149,7 +149,7 @@ void Base_Type::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, for (int success=reader.Read(); success==1; success=reader.Read()) { if (reader.NodeType() == XML_READER_TYPE_ELEMENT) break; } - XER_decode(*(p_td.xer), reader, XER_coding, 0); + XER_decode(*(p_td.xer), reader, XER_coding, XER_NONE, 0); size_t bytes = reader.ByteConsumed(); p_buf.set_pos(bytes); break;} @@ -975,7 +975,7 @@ int Base_Type::XER_encode(const XERdescriptor_t& p_td, } int Base_Type::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap&, - unsigned int, embed_values_dec_struct_t*) { + unsigned int, unsigned int, embed_values_dec_struct_t*) { TTCN_error("XER decoding requested for type '%-.*s' which has no" " XER decoding method.", p_td.namelens[0]-2, p_td.names[0]); return 0; diff --git a/core/Basetype.hh b/core/Basetype.hh index 6c7e77b1b51b0bb5911bb8958fc8c7471e16bf27..e4c8323a32dcaae5b9825878d192d71cb0b1e5da 100644 --- a/core/Basetype.hh +++ b/core/Basetype.hh @@ -499,11 +499,12 @@ public: * @param p_td type descriptor * @param reader Wrapper around the XML processor * @param flavor one of XER_flavor values + * @param flavor2 one of XER_flavor2 values * @param emb_val embed values data (only relevant for record of types) * @return number of bytes "consumed" */ VIRTUAL_IF_RUNTIME_2 int XER_decode(const XERdescriptor_t& p_td, - XmlReaderWrap& reader, unsigned int flavor, embed_values_dec_struct_t* emb_val); + XmlReaderWrap& reader, unsigned int flavor, unsigned int flavor2, embed_values_dec_struct_t* emb_val); /** Return an array of namespace declarations. * @@ -804,7 +805,7 @@ public: int encode_element(int i, const XERdescriptor_t& p_td, const Erroneous_values_t* err_vals, const Erroneous_descriptor_t* emb_descr, TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t* emb_val) const; - virtual int XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, unsigned int, embed_values_dec_struct_t*); + virtual int XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, unsigned int, unsigned int, embed_values_dec_struct_t*); virtual boolean isXerAttribute() const; virtual boolean isXmlValueList() const; @@ -864,16 +865,15 @@ protected: const Base_Type* value; }; Erroneous_descriptor_t* err_descr; - boolean bound_flag; public: - Record_Type() : err_descr(NULL), bound_flag(false) {} + Record_Type() : err_descr(NULL) {} /// @{ /** get pointer to a field */ virtual Base_Type* get_at(int index_value) = 0; virtual const Base_Type* get_at(int index_value) const = 0; /// @} - + /** get the index to a field based on its name and namespace URI, or -1 */ int get_index_byname(const char *name, const char *uri) const; @@ -946,7 +946,7 @@ public: const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const; virtual int XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, - unsigned int, embed_values_dec_struct_t*); + unsigned int, unsigned int, embed_values_dec_struct_t*); /// @{ /// Methods overridden in the derived (generated) class virtual int get_xer_num_attr() const { return 0; /* default */ } @@ -1023,7 +1023,7 @@ public: virtual int XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const; virtual int XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, - unsigned int, embed_values_dec_struct_t*); + unsigned int, unsigned int, embed_values_dec_struct_t*); /** Encodes accordingly to the JSON encoding rules. * Returns the length of the encoded data. */ diff --git a/core/Bitstring.cc b/core/Bitstring.cc index a178fb2d9c761e2158d009b47bd4aeb4b0c0f698..50e897a1de48f79ce5c882b9554655b1849a7e74 100644 --- a/core/Bitstring.cc +++ b/core/Bitstring.cc @@ -711,7 +711,7 @@ void BITSTRING::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, if (type==XML_READER_TYPE_ELEMENT) break; } - XER_decode(*p_td.xer, reader, XER_coding, 0); + XER_decode(*p_td.xer, reader, XER_coding, XER_NONE, 0); size_t bytes = reader.ByteConsumed(); p_buf.set_pos(bytes); break;} @@ -1069,7 +1069,7 @@ int BITSTRING::XER_encode(const XERdescriptor_t& p_td, } int BITSTRING::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, - unsigned int flavor, embed_values_dec_struct_t*) + unsigned int flavor, unsigned int /*flavor2*/, embed_values_dec_struct_t*) { int exer = is_exer(flavor); int success = reader.Ok(), depth = -1, type; diff --git a/core/Bitstring.hh b/core/Bitstring.hh index b890333a9bc63cf9fc26738b01fc9b3f5168b06d..f9b53d30adc2018cf8abf1644a6dc9d21726a63d 100644 --- a/core/Bitstring.hh +++ b/core/Bitstring.hh @@ -175,7 +175,7 @@ public: boolean no_err=FALSE, int sel_field=-1, boolean first_call=TRUE); int XER_encode(const XERdescriptor_t&, TTCN_Buffer&, unsigned int, int, embed_values_enc_struct_t*) const; - int XER_decode(const XERdescriptor_t&, XmlReaderWrap& reader, unsigned int, embed_values_dec_struct_t*); + int XER_decode(const XERdescriptor_t&, XmlReaderWrap& reader, unsigned int, unsigned int, embed_values_dec_struct_t*); /** Encodes accordingly to the JSON encoding rules. * Returns the length of the encoded data. */ diff --git a/core/Boolean.cc b/core/Boolean.cc index 5dd0ca3552e6c869c76046c523774e3750dd3724..e519012fd93845c54fce1ae957a872181fc608ae 100644 --- a/core/Boolean.cc +++ b/core/Boolean.cc @@ -295,7 +295,7 @@ void BOOLEAN::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, if (type==XML_READER_TYPE_ELEMENT) break; } - XER_decode(*p_td.xer, reader, XER_coding, 0); + XER_decode(*p_td.xer, reader, XER_coding, XER_NONE, 0); size_t bytes = reader.ByteConsumed(); p_buf.set_pos(bytes); break;} @@ -624,7 +624,7 @@ int BOOLEAN::XER_encode(const XERdescriptor_t& p_td, } int BOOLEAN::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, - unsigned int flavor, embed_values_dec_struct_t*) + unsigned int flavor, unsigned int /*flavor2*/, embed_values_dec_struct_t*) { const boolean exer = is_exer(flavor); int XMLValueList = !exer && is_record_of(flavor); diff --git a/core/Boolean.hh b/core/Boolean.hh index 2a7a60e664d38b7281abbda0b3e76adca4ceb6fe..95d0414ba1a7bbb9fd451c4e608590fa503b7749 100644 --- a/core/Boolean.hh +++ b/core/Boolean.hh @@ -105,7 +105,7 @@ public: int XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const; int XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, - unsigned int flavor, embed_values_dec_struct_t*); + unsigned int flavor, unsigned int flavor2, embed_values_dec_struct_t*); /** Encodes accordingly to the JSON encoding rules. * Returns the length of the encoded data. */ diff --git a/core/Charstring.cc b/core/Charstring.cc index 48fccff295478e9a9ed5fdffef21cae37e9d5577..9e23390d5ec84d26ac43efc8b349fff3f35519fd 100644 --- a/core/Charstring.cc +++ b/core/Charstring.cc @@ -855,7 +855,7 @@ void CHARSTRING::decode(const TTCN_Typedescriptor_t& p_td, if (type==XML_READER_TYPE_ELEMENT) break; } - XER_decode(*p_td.xer, reader, XER_coding, 0); + XER_decode(*p_td.xer, reader, XER_coding, XER_NONE, 0); size_t bytes = reader.ByteConsumed(); p_buf.set_pos(bytes); break;} @@ -1321,7 +1321,7 @@ unsigned int xlate(cbyte*in, int phase, unsigned char*dest) { } int CHARSTRING::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, - unsigned int flavor, embed_values_dec_struct_t*) { + unsigned int flavor, unsigned int /*flavor2*/, embed_values_dec_struct_t*) { int exer = is_exer(flavor); int success = reader.Ok(), depth = -1; diff --git a/core/Charstring.hh b/core/Charstring.hh index 196745007855883f9ff04edfbdc8d8f48ce0f8af..0322e572b694bb7abab02dd9e942ec9f6c31ae7f 100644 --- a/core/Charstring.hh +++ b/core/Charstring.hh @@ -214,7 +214,7 @@ public: int TEXT_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer&, Limit_Token_List&, boolean no_err=FALSE, boolean first_call=TRUE); int XER_encode(const XERdescriptor_t&, TTCN_Buffer&, unsigned int, int, embed_values_enc_struct_t*) const; - int XER_decode(const XERdescriptor_t&, XmlReaderWrap& reader, unsigned int, embed_values_dec_struct_t*); + int XER_decode(const XERdescriptor_t&, XmlReaderWrap& reader, unsigned int, unsigned int, embed_values_dec_struct_t*); /** Returns the charstring in the format a string would appear in C or TTCN-3 code. * Inserts double quotation marks to the beginning and end of the string and diff --git a/core/Float.cc b/core/Float.cc index ea3f06b0ae06ef414ba6373391b7b437032a4084..e082fa162753d0115c4a0e91dc8f5f02b8c51385 100644 --- a/core/Float.cc +++ b/core/Float.cc @@ -409,7 +409,7 @@ void FLOAT::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, if (type==XML_READER_TYPE_ELEMENT) break; } - XER_decode(*p_td.xer, reader, XER_coding, 0); + XER_decode(*p_td.xer, reader, XER_coding, XER_NONE, 0); size_t bytes = reader.ByteConsumed(); p_buf.set_pos(bytes); break;} @@ -908,7 +908,7 @@ boolean FLOAT::is_float(const char* p_str) } int FLOAT::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, - unsigned int flavor, embed_values_dec_struct_t*) + unsigned int flavor, unsigned int /*flavor2*/, embed_values_dec_struct_t*) { bound_flag = false; int exer = is_exer(flavor); diff --git a/core/Float.hh b/core/Float.hh index 01b162f45bba0373be610a7ccc215987f6ce3c61..879f1533375bc3b72cd9643ba327f860dcfc7aff 100644 --- a/core/Float.hh +++ b/core/Float.hh @@ -136,7 +136,7 @@ public: int XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const; int XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, - unsigned int flavor, embed_values_dec_struct_t*); + unsigned int flavor, unsigned int flavor2, embed_values_dec_struct_t*); /** Encodes accordingly to the JSON encoding rules. * Returns the length of the encoded data. */ diff --git a/core/Hexstring.cc b/core/Hexstring.cc index c61c13f4cd692b5f4b3bebc6ffc3d88c2ab7ee91..2ab090e912619ed5c28246484fc88628bc77812e 100644 --- a/core/Hexstring.cc +++ b/core/Hexstring.cc @@ -711,7 +711,7 @@ void HEXSTRING::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, if (type==XML_READER_TYPE_ELEMENT) break; } - XER_decode(*p_td.xer, reader, XER_coding, 0); + XER_decode(*p_td.xer, reader, XER_coding, XER_NONE, 0); size_t bytes = reader.ByteConsumed(); p_buf.set_pos(bytes); break;} @@ -901,7 +901,7 @@ Because of this, the bit shifting is different. The first three bytes */ int HEXSTRING::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, - unsigned int flavor, embed_values_dec_struct_t*) + unsigned int flavor, unsigned int /*flavor2*/, embed_values_dec_struct_t*) { int exer = is_exer(flavor); int success = reader.Ok(), depth = -1, type; diff --git a/core/Hexstring.hh b/core/Hexstring.hh index 7f1ff249d68d735c83534f5fa672cc4df542d1db..ff21120b57fe643d1c40a8dda7dea6411db0726d 100644 --- a/core/Hexstring.hh +++ b/core/Hexstring.hh @@ -129,7 +129,7 @@ public: int XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const; int XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, - unsigned int flavor, embed_values_dec_struct_t*); + unsigned int flavor, unsigned int flavor2, embed_values_dec_struct_t*); /** Encodes accordingly to the JSON encoding rules. * Returns the length of the encoded data. */ diff --git a/core/Integer.cc b/core/Integer.cc index c209315b02bd18dccbaf8f3078bfaa4d9904451a..51da9911cdbe7a552647014cff6f1a3add8344d6 100644 --- a/core/Integer.cc +++ b/core/Integer.cc @@ -855,7 +855,7 @@ void INTEGER::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, if (type==XML_READER_TYPE_ELEMENT) break; } - XER_decode(*p_td.xer, reader, XER_coding, 0); + XER_decode(*p_td.xer, reader, XER_coding, XER_NONE, 0); size_t bytes = reader.ByteConsumed(); p_buf.set_pos(bytes); break;} @@ -1593,7 +1593,7 @@ int INTEGER::XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, } int INTEGER::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, - unsigned int flavor, embed_values_dec_struct_t*) + unsigned int flavor, unsigned int /*flavor2*/, embed_values_dec_struct_t*) { const boolean exer = is_exer(flavor); int depth = -1, success = reader.Ok(), type; diff --git a/core/Integer.hh b/core/Integer.hh index 54cf6478d2adf86b3d32d8b15d9b5bf8aa22f5cd..6b4c33420253b17586831582009bb639eff55106 100644 --- a/core/Integer.hh +++ b/core/Integer.hh @@ -166,7 +166,7 @@ public: /** @brief Decode according to XML Encoding Rules. **/ int XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, - unsigned int flavor, embed_values_dec_struct_t*); + unsigned int flavor, unsigned int flavor2, embed_values_dec_struct_t*); /** Encodes accordingly to the JSON encoding rules. * Returns the length of the encoded data. */ diff --git a/core/JSON.hh b/core/JSON.hh index 662884b44f4edcb9126b224bc6fbccad88c4a96e..53f371bc5c077816ed747e58b2262d4bdc55feda 100644 --- a/core/JSON.hh +++ b/core/JSON.hh @@ -42,7 +42,13 @@ struct TTCN_JSONdescriptor_t * The decoder sets the field to unbound if the meta info field is present and * the field's value in the JSON code is either null or a valid value for that * field. - * Example: { "field1" : null, "metainfo field1" : "unbound" } */ + * Example: { "field1" : null, "metainfo field1" : "unbound" } + * + * Also usable on record of/set of/array types to indicate that an element is + * unbound. Unbound elements are encoded as a JSON object containing one + * metainfo member. The decoder sets the element to unbound if the object + * with the meta information is found. + * Example: [ value1, value2, { "metainfo []" : "unbound" }, value3 ] */ boolean metainfo_unbound; }; diff --git a/core/Objid.cc b/core/Objid.cc index 77a06a2e7e61e3cb92fe2e9953c0cb6dbbc9ffda..b7b1057220c15aaf1507f82fe9a6b15b08ecf88d 100644 --- a/core/Objid.cc +++ b/core/Objid.cc @@ -325,7 +325,7 @@ void OBJID::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, if (type==XML_READER_TYPE_ELEMENT) break; } - XER_decode(*p_td.xer, reader, XER_coding, 0); + XER_decode(*p_td.xer, reader, XER_coding, XER_NONE, 0); size_t bytes = reader.ByteConsumed(); p_buf.set_pos(bytes); break;} @@ -540,7 +540,7 @@ void OBJID::from_string(char* p_str) } int OBJID::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, - unsigned int flavor, embed_values_dec_struct_t*) + unsigned int flavor, unsigned int /*flavor2*/, embed_values_dec_struct_t*) { int exer = is_exer(flavor); int success = reader.Ok(), depth = -1; diff --git a/core/Objid.hh b/core/Objid.hh index 0a51d1eb7e50a3f2bcfa3a3e9ca9bfbabb6ef0b3..38c0a00112706c3010c8ab24e92a6aadf7c10e5e 100644 --- a/core/Objid.hh +++ b/core/Objid.hh @@ -92,7 +92,7 @@ public: int XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const; int XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, - unsigned int flavor, embed_values_dec_struct_t*); + unsigned int flavor, unsigned int flavor2, embed_values_dec_struct_t*); /** Encodes accordingly to the JSON encoding rules. * Returns the length of the encoded data. */ diff --git a/core/Octetstring.cc b/core/Octetstring.cc index 18daa773a688b592e8c114d5fe4776c98f475bac..3756c4d7856f9a4cd7c5643015d7662cddf5eaf5 100644 --- a/core/Octetstring.cc +++ b/core/Octetstring.cc @@ -690,7 +690,7 @@ void OCTETSTRING::decode(const TTCN_Typedescriptor_t& p_td, if (type==XML_READER_TYPE_ELEMENT) break; } - XER_decode(*p_td.xer, reader, XER_coding, 0); + XER_decode(*p_td.xer, reader, XER_coding, XER_NONE, 0); size_t bytes = reader.ByteConsumed(); p_buf.set_pos(bytes); break;} @@ -939,7 +939,7 @@ int OCTETSTRING::XER_encode(const XERdescriptor_t& p_td, } int OCTETSTRING::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, - unsigned int flavor, embed_values_dec_struct_t*) + unsigned int flavor, unsigned int /*flavor2*/, embed_values_dec_struct_t*) { int exer = is_exer(flavor); int success = reader.Ok(), depth = -1, type; diff --git a/core/Octetstring.hh b/core/Octetstring.hh index ca10f66f2812c5c9bc82f9141f53a9df4f76ea14..a4f03f1c2e034244cfe71ba07afad234cf12b682 100644 --- a/core/Octetstring.hh +++ b/core/Octetstring.hh @@ -157,7 +157,7 @@ public: int XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const; int XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, - unsigned int flavor, embed_values_dec_struct_t*); + unsigned int flavor, unsigned int flavor2, embed_values_dec_struct_t*); /** Encodes accordingly to the JSON encoding rules. * Returns the length of the encoded data. */ diff --git a/core/Optional.hh b/core/Optional.hh index c640b0099d27c4140a8e5ad6b3a59c5a85181d24..9d84211da4b752311d6aae413ad551139039f759 100644 --- a/core/Optional.hh +++ b/core/Optional.hh @@ -281,7 +281,7 @@ public: * @param parent_tag_closed true, if the record's XML tag is closed (is an empty element)*/ bool XER_check_any_elem(XmlReaderWrap& reader, const char* next_field_name, bool parent_tag_closed); int XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, - unsigned int flavor, embed_values_dec_struct_t* emb_val); + unsigned int flavor, unsigned int flavor2, embed_values_dec_struct_t* emb_val); char ** collect_ns(const XERdescriptor_t& p_td, size_t& num, bool& def_ns) const; @@ -1030,7 +1030,7 @@ OPTIONAL<T_type>::XER_check_any_elem(XmlReaderWrap& reader, const char* next_fie template<typename T_type> int OPTIONAL<T_type>::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, - unsigned int flavor, embed_values_dec_struct_t* emb_val) + unsigned int flavor, unsigned int flavor2, embed_values_dec_struct_t* emb_val) { int exer = is_exer(flavor); for (int success = reader.Ok(); success==1; success=reader.Read()) { @@ -1058,11 +1058,14 @@ OPTIONAL<T_type>::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, } set_to_present(); - optional_value->XER_decode(p_td, reader, flavor, emb_val); + optional_value->XER_decode(p_td, reader, flavor, flavor2, emb_val); goto finished; } else break; } + else if(XML_READER_TYPE_ATTRIBUTE == type && (flavor & USE_NIL)){ + goto found_it; + } else { // not attribute if (XML_READER_TYPE_ELEMENT == type) { // we are at an element name = (const char*)reader.LocalName(); @@ -1075,7 +1078,7 @@ OPTIONAL<T_type>::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, found_it: set_to_present(); //success = reader.Read(); // move to next thing TODO should it loop till an element ? - optional_value->XER_decode(p_td, reader, flavor, emb_val); + optional_value->XER_decode(p_td, reader, flavor, flavor2, emb_val); if (!optional_value->is_bound()) { set_to_omit(); } diff --git a/core/Port.hh b/core/Port.hh index 35d2e51237fb3c3c85006b77d1c0610b13fccd6d..0c13b3fc32cccd63029cf7715adf2bf89c2798c1 100644 --- a/core/Port.hh +++ b/core/Port.hh @@ -13,6 +13,7 @@ #include "Types.h" #include "Event_Handler.hh" #include <stddef.h> // only for NULL +#include <sys/select.h> class COMPONENT; class COMPONENT_template; diff --git a/core/Universal_charstring.cc b/core/Universal_charstring.cc index 4eda2c1e91ddf676b68b5202665b65c87eca86f5..acbcc5434ceb7c463872bc70ab5001cb96ba6ebd 100644 --- a/core/Universal_charstring.cc +++ b/core/Universal_charstring.cc @@ -1157,7 +1157,7 @@ void UNIVERSAL_CHARSTRING::decode(const TTCN_Typedescriptor_t& p_td, if (type==XML_READER_TYPE_ELEMENT) break; } - XER_decode(*p_td.xer, reader, XER_coding, 0); + XER_decode(*p_td.xer, reader, XER_coding, XER_NONE, 0); size_t bytes = reader.ByteConsumed(); p_buf.set_pos(bytes); break; } @@ -2030,7 +2030,7 @@ in_word_set (const char *str, unsigned int len) universal_char const uspace = {0,0,0,32}; int UNIVERSAL_CHARSTRING::XER_decode(const XERdescriptor_t& p_td, - XmlReaderWrap& reader, unsigned int flavor, embed_values_dec_struct_t*) + XmlReaderWrap& reader, unsigned int flavor, unsigned int /*flavor2*/, embed_values_dec_struct_t*) { int exer = is_exer(flavor); int success = reader.Ok(), depth = -1; diff --git a/core/Universal_charstring.hh b/core/Universal_charstring.hh index bda37a04e11d7e9a748e4f94750e78a7df2b0a85..6e744884767f362423a5dc725b8eeb5b63ef1189 100644 --- a/core/Universal_charstring.hh +++ b/core/Universal_charstring.hh @@ -330,7 +330,7 @@ public: int TEXT_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer&, Limit_Token_List&, boolean no_err=FALSE, boolean first_call=TRUE); int XER_encode(const XERdescriptor_t&, TTCN_Buffer&, unsigned int, int, embed_values_enc_struct_t*) const; - int XER_decode(const XERdescriptor_t&, XmlReaderWrap& reader, unsigned int, embed_values_dec_struct_t*); + int XER_decode(const XERdescriptor_t&, XmlReaderWrap& reader, unsigned int, unsigned int, embed_values_dec_struct_t*); /** Decodes UTF-8 into the internal representation (UCS4-BE) * * @param n_octets number of UTF-8 bytes (not characters) diff --git a/core/Verdicttype.cc b/core/Verdicttype.cc index d74aff45168687522906df12878b5ecee85ef3ff..d5607e0f2922ad3081a9ee0a267fff8e9925642d 100644 --- a/core/Verdicttype.cc +++ b/core/Verdicttype.cc @@ -239,7 +239,7 @@ void VERDICTTYPE::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, if (type==XML_READER_TYPE_ELEMENT) break; } - XER_decode(*p_td.xer, reader, XER_coding, 0); + XER_decode(*p_td.xer, reader, XER_coding, XER_NONE, 0); size_t bytes = reader.ByteConsumed(); p_buf.set_pos(bytes); break;} @@ -297,7 +297,7 @@ verdicttype VERDICTTYPE::str_to_verdict(const char *v, boolean silent) } int VERDICTTYPE::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& p_reader, - unsigned int p_flavor, embed_values_dec_struct_t*) + unsigned int p_flavor, unsigned int /*flavor2*/, embed_values_dec_struct_t*) { int rd_ok = 1, type; const int e_xer = is_exer(p_flavor); diff --git a/core/Verdicttype.hh b/core/Verdicttype.hh index 0faba13bdffcf709104c0a4ceece023d8635f9fd..eedef15480527b5058c7fda303dcc65932822bc4 100644 --- a/core/Verdicttype.hh +++ b/core/Verdicttype.hh @@ -85,7 +85,7 @@ public: int XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const; int XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, - unsigned int flavor, embed_values_dec_struct_t*); + unsigned int flavor, unsigned int flavor2, embed_values_dec_struct_t*); /** Encodes accordingly to the JSON encoding rules. * Returns the length of the encoded data. */ diff --git a/core/XER.hh b/core/XER.hh index 9f56aac5453449784e4dd4f13a1b47f99df3ca49..f771769802d7511329ec1a96c4546336e02bb336 100644 --- a/core/XER.hh +++ b/core/XER.hh @@ -96,6 +96,10 @@ enum XER_flavor { BLOCKED = 1U << 31 // 0x80000000 either ABSTRACT or BLOCK }; +enum XER_flavor2 { + USE_NIL_PARENT_TAG = 1U << 0 // Content field has attribute that was read by parent +}; + /** WHITESPACE actions. * Note that WHITESPACE_COLLAPSE includes the effect of WHITESPACE_REPLACE * and the code relies on WHITESPACE_COLLAPSE having the higher value. */ diff --git a/core/XmlReader.hh b/core/XmlReader.hh index c6c480fd4a66abf6b3a1432dda0ea7934617b059..eaefece20a43c83f14e1ffb9bbc870d9780909e0 100644 --- a/core/XmlReader.hh +++ b/core/XmlReader.hh @@ -76,7 +76,7 @@ public: * @return 1 on success, 0 if no more nodes to read, -1 on error */ int Read(); int ReadDbg(const char *where); - + #if 0 /** Return the child nodes of the current node. * diff --git a/core2/Basetype2.cc b/core2/Basetype2.cc index e9d18e49c74db2bca9193bf12696fed7dc44b372..b94c5bcb9949adee075f9f7973e4cfc15b597469 100644 --- a/core2/Basetype2.cc +++ b/core2/Basetype2.cc @@ -1450,9 +1450,18 @@ int Record_Of_Type::JSON_encode(const TTCN_Typedescriptor_t& p_td, JSON_Tokenize int enc_len = p_tok.put_next_token(JSON_TOKEN_ARRAY_START, NULL); for (int i = 0; i < get_nof_elements(); ++i) { - int ret_val = get_at(i)->JSON_encode(*p_td.oftype_descr, p_tok); - if (0 > ret_val) break; - enc_len += ret_val; + if (NULL != p_td.json && p_td.json->metainfo_unbound && !get_at(i)->is_bound()) { + // unbound elements are encoded as { "metainfo []" : "unbound" } + enc_len += p_tok.put_next_token(JSON_TOKEN_OBJECT_START, NULL); + enc_len += p_tok.put_next_token(JSON_TOKEN_NAME, "metainfo []"); + enc_len += p_tok.put_next_token(JSON_TOKEN_STRING, "\"unbound\""); + enc_len += p_tok.put_next_token(JSON_TOKEN_OBJECT_END, NULL); + } + else { + int ret_val = get_at(i)->JSON_encode(*p_td.oftype_descr, p_tok); + if (0 > ret_val) break; + enc_len += ret_val; + } } enc_len += p_tok.put_next_token(JSON_TOKEN_ARRAY_END, NULL); @@ -1507,7 +1516,15 @@ int Record_Of_Type::JSON_encode_negtest(const Erroneous_descriptor_t* p_err_desc enc_len += err_vals->value->errval->JSON_encode(*(err_vals->value->type_descr), p_tok); } } - } else { + } + else if (NULL != p_td.json && p_td.json->metainfo_unbound && !get_at(i)->is_bound()) { + // unbound elements are encoded as { "metainfo []" : "unbound" } + enc_len += p_tok.put_next_token(JSON_TOKEN_OBJECT_START, NULL); + enc_len += p_tok.put_next_token(JSON_TOKEN_NAME, "metainfo []"); + enc_len += p_tok.put_next_token(JSON_TOKEN_STRING, "\"unbound\""); + enc_len += p_tok.put_next_token(JSON_TOKEN_OBJECT_END, NULL); + } + else { int ret_val; if (NULL != emb_descr) { ret_val = get_at(i)->JSON_encode_negtest(emb_descr, *p_td.oftype_descr, p_tok); @@ -1554,11 +1571,35 @@ int Record_Of_Type::JSON_decode(const TTCN_Typedescriptor_t& p_td, JSON_Tokenize } set_size(0); - while (true) { + for (int nof_elements = 0; true; ++nof_elements) { // Read value tokens until we reach some other token size_t buf_pos = p_tok.get_buf_pos(); + int ret_val; + if (NULL != p_td.json && p_td.json->metainfo_unbound) { + // check for metainfo object + ret_val = p_tok.get_next_token(&token, NULL, NULL); + if (JSON_TOKEN_OBJECT_START == token) { + char* value = NULL; + size_t value_len = 0; + ret_val += p_tok.get_next_token(&token, &value, &value_len); + if (JSON_TOKEN_NAME == token && 11 == value_len && + 0 == strncmp(value, "metainfo []", 11)) { + ret_val += p_tok.get_next_token(&token, &value, &value_len); + if (JSON_TOKEN_STRING == token && 9 == value_len && + 0 == strncmp(value, "\"unbound\"", 9)) { + ret_val = p_tok.get_next_token(&token, NULL, NULL); + if (JSON_TOKEN_OBJECT_END == token) { + dec_len += ret_val; + continue; + } + } + } + } + // metainfo object not found, jump back and let the element type decode it + p_tok.set_buf_pos(buf_pos); + } Base_Type* val = create_elem(); - int ret_val = val->JSON_decode(*p_td.oftype_descr, p_tok, p_silent); + ret_val = val->JSON_decode(*p_td.oftype_descr, p_tok, p_silent); if (JSON_ERROR_INVALID_TOKEN == ret_val) { // undo the last action on the buffer p_tok.set_buf_pos(buf_pos); @@ -1574,12 +1615,12 @@ int Record_Of_Type::JSON_decode(const TTCN_Typedescriptor_t& p_td, JSON_Tokenize } if (NULL == refd_ind_ptr) { val_ptr->value_elements = (Base_Type**)reallocate_pointers( - (void**)val_ptr->value_elements, val_ptr->n_elements, val_ptr->n_elements + 1); - val_ptr->value_elements[val_ptr->n_elements] = val; - val_ptr->n_elements++; + (void**)val_ptr->value_elements, val_ptr->n_elements, nof_elements + 1); + val_ptr->value_elements[nof_elements] = val; + val_ptr->n_elements = nof_elements + 1; } else { - get_at(get_nof_elements())->set_value(val); + get_at(nof_elements)->set_value(val); delete val; } dec_len += ret_val; @@ -1701,7 +1742,7 @@ void Record_Of_Type::decode(const TTCN_Typedescriptor_t& p_td, for (int success=reader.Read(); success==1; success=reader.Read()) { if (reader.NodeType() == XML_READER_TYPE_ELEMENT) break; } - XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL, 0); + XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL, XER_NONE, 0); size_t bytes = reader.ByteConsumed(); p_buf.set_pos(bytes); break;} @@ -2199,7 +2240,7 @@ int Record_Of_Type::XER_encode_negtest(const Erroneous_descriptor_t* p_err_descr } int Record_Of_Type::XER_decode(const XERdescriptor_t& p_td, - XmlReaderWrap& reader, unsigned int flavor, embed_values_dec_struct_t* emb_val) + XmlReaderWrap& reader, unsigned int flavor, unsigned int flavor2, embed_values_dec_struct_t* emb_val) { int exer = is_exer(flavor); int xerbits = p_td.xer_bits; @@ -2278,7 +2319,7 @@ int Record_Of_Type::XER_decode(const XERdescriptor_t& p_td, // The call to the non-const operator[], I mean get_at(), creates // a new element (because it is indexing one past the last element). // Then we call its XER_decode with the temporary XML reader. - get_at(get_nof_elements())->XER_decode(sub_xer, reader2, flavor, 0); + get_at(get_nof_elements())->XER_decode(sub_xer, reader2, flavor, flavor2, 0); if (flavor & EXIT_ON_ERROR && !is_elem_bound(get_nof_elements() - 1)) { if (1 == get_nof_elements()) { // Failed to decode even the first element @@ -2344,10 +2385,10 @@ int Record_Of_Type::XER_decode(const XERdescriptor_t& p_td, } ec_1.set_msg("%d: ", get_nof_elements()); /* The call to the non-const get_at() creates the element */ - get_at(get_nof_elements())->XER_decode(*p_td.oftype_descr, reader, flavor, emb_val); - if (0 != emb_val && !own_tag && get_nof_elements() > 1) { - ++emb_val->embval_index; - } + get_at(get_nof_elements())->XER_decode(*p_td.oftype_descr, reader, flavor, flavor2, emb_val); + } + if (0 != emb_val && !own_tag && get_nof_elements() > 1) { + ++emb_val->embval_index; } } else if (XML_READER_TYPE_END_ELEMENT == type) { @@ -2534,7 +2575,6 @@ boolean operator!=(null_type null_value, boolean Record_Type::is_bound() const { - if (bound_flag) return TRUE; int field_cnt = get_count(); for (int field_idx=0; field_idx<field_cnt; field_idx++) { const Base_Type* temp = get_at(field_idx); @@ -2548,9 +2588,6 @@ boolean Record_Type::is_bound() const boolean Record_Type::is_value() const { - if (!is_bound()) { - return FALSE; - } int field_cnt = get_count(); for (int field_idx=0; field_idx<field_cnt; field_idx++) { const Base_Type* temp = get_at(field_idx); @@ -2570,7 +2607,6 @@ void Record_Type::clean_up() for (int field_idx=0; field_idx<field_cnt; field_idx++) { get_at(field_idx)->clean_up(); } - bound_flag = FALSE; } void Record_Type::log() const @@ -2592,7 +2628,6 @@ void Record_Type::log() const } void Record_Type::set_param(Module_Param& param) { - bound_flag = TRUE; if (dynamic_cast<Module_Param_Name*>(param.get_id()) != NULL && param.get_id()->next_name()) { // Haven't reached the end of the module parameter name @@ -2703,10 +2738,6 @@ void Record_Type::set_implicit_omit() int Record_Type::size_of() const { - if (!is_bound()) { - TTCN_error("Calculating the size of an unbound record/set value of type %s", - get_descriptor()->name); - } int opt_count = optional_count(); if (opt_count==0) return get_count(); const int* optional_indexes = get_optional_indexes(); @@ -2730,7 +2761,6 @@ void Record_Type::encode_text(Text_Buf& text_buf) const void Record_Type::decode_text(Text_Buf& text_buf) { - bound_flag = TRUE; int field_cnt = get_count(); for (int field_idx=0; field_idx<field_cnt; field_idx++) get_at(field_idx)->decode_text(text_buf); @@ -2739,9 +2769,6 @@ void Record_Type::decode_text(Text_Buf& text_buf) boolean Record_Type::is_equal(const Base_Type* other_value) const { const Record_Type* other_record = static_cast<const Record_Type*>(other_value); - if (!is_bound() && !other_record->is_bound()) { - return TRUE; - } int field_cnt = get_count(); for (int field_idx=0; field_idx<field_cnt; field_idx++) { const Base_Type* elem = get_at(field_idx); @@ -2773,7 +2800,6 @@ void Record_Type::set_value(const Base_Type* other_value) } } err_descr = other_record->err_descr; - bound_flag = TRUE; } void Record_Type::encode(const TTCN_Typedescriptor_t& p_td, @@ -2896,7 +2922,7 @@ void Record_Type::decode(const TTCN_Typedescriptor_t& p_td, for (int success=reader.Read(); success==1; success=reader.Read()) { if (reader.NodeType() == XML_READER_TYPE_ELEMENT) break; } - XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL, 0); + XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL, XER_NONE, 0); size_t bytes = reader.ByteConsumed(); p_buf.set_pos(bytes); break;} @@ -3054,7 +3080,6 @@ ASN_BER_TLV_t* Record_Type::BER_encode_TLV_negtest(const Erroneous_descriptor_t* boolean Record_Type::BER_decode_TLV(const TTCN_Typedescriptor_t& p_td, const ASN_BER_TLV_t& p_tlv, unsigned L_form) { - bound_flag = TRUE; BER_chk_descr(p_td); ASN_BER_TLV_t stripped_tlv; BER_decode_strip_tags(*p_td.ber, p_tlv, L_form, stripped_tlv); @@ -3161,7 +3186,6 @@ boolean Record_Type::BER_decode_TLV(const TTCN_Typedescriptor_t& p_td, void Record_Type::BER_decode_opentypes(TTCN_Type_list& p_typelist, unsigned L_form) { - bound_flag = TRUE; p_typelist.push(this); TTCN_EncDec_ErrorContext ec_0("Component '"); TTCN_EncDec_ErrorContext ec_1; @@ -3358,7 +3382,6 @@ int Record_Type::RAW_encode_negtest(const Erroneous_descriptor_t *p_err_descr, int Record_Type::RAW_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& buff, int limit, raw_order_t top_bit_ord, boolean no_err, int, boolean) { - bound_flag = TRUE; int field_cnt = get_count(); int opt_cnt = optional_count(); int mand_num = field_cnt - opt_cnt; // expected mandatory fields @@ -3632,7 +3655,6 @@ int Record_Type::TEXT_encode_negtest(const Erroneous_descriptor_t* p_err_descr, int Record_Type::TEXT_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& buff, Limit_Token_List& limit, boolean no_err, boolean /*first_call*/) { - bound_flag = TRUE; if (is_set()) { int decoded_length=0; int decoded_field_length=0; @@ -4166,7 +4188,7 @@ int Record_Type::XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, - (!indenting || delay_close || (exer && (p_td.xer_bits & HAS_1UNTAGGED))), (cbyte*)p_td.names[exer]); } - else if (flavor & USE_TYPE_ATTR) { + else if (flavor & (USE_NIL|USE_TYPE_ATTR)) { // reopen the parent's start tag by overwriting the '>' size_t buf_len = p_buf.get_len(); const unsigned char * const buf_data = p_buf.get_data(); @@ -5082,9 +5104,8 @@ int Record_Type::XER_encode_negtest(const Erroneous_descriptor_t* p_err_descr, } int Record_Type::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, - unsigned int flavor, embed_values_dec_struct_t*) + unsigned int flavor, unsigned int flavor2, embed_values_dec_struct_t*) { - bound_flag = TRUE; int exer = is_exer(flavor); int success, type; int depth=-1; // depth of the start tag @@ -5096,10 +5117,11 @@ int Record_Type::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, boolean tag_closed = (flavor & PARENT_CLOSED) != 0; // If the parent has USE-TYPE, our ATTRIBUTE members can be found // in the parent's tag (the reader is sitting on it). - const boolean parent_tag = exer && (flavor & (/*USE_NIL|*/ USE_TYPE_ATTR)); + const boolean parent_tag = exer && ((flavor & USE_TYPE_ATTR) || (flavor2 & USE_NIL_PARENT_TAG)); // Filter out flags passed by our parent. These are not for the fields. flavor &= XER_MASK; // also removes XER_TOPLEVEL + flavor2 = XER_NONE; // Remove only bit: USE_NIL_PARENT_TAG (for now) const int field_cnt = get_count(); const int num_attributes = get_xer_num_attr(); @@ -5112,7 +5134,7 @@ int Record_Type::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, // fields); normal processing start at this field. const int start_at = uo_index + ((p_td.xer_bits & USE_ORDER) != 0); const int first_nonattr = start_at + num_attributes; - + // The index of the ANY-ATTRIBUTES member, if any int aa_index = -1; for (int k = 0; k < first_nonattr; ++k) { @@ -5180,12 +5202,15 @@ int Record_Type::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, TTCN_EncDec_ErrorContext ec_0("Component '"); TTCN_EncDec_ErrorContext ec_1; boolean usenil_attribute = FALSE; // true if found and said yes + // If nillable and the nillable field is a record type, that has attributes + // then it will become true, and skips the processing of the fields after + boolean already_processed = FALSE; if (!exer) { if (!reader.IsEmptyElement()) reader.Read(); // First, the (would-be) attributes (unaffected by USE-ORDER) for (i = 0; i < first_nonattr; i++) { ec_1.set_msg("%s': ", fld_name(i)); - get_at(i)->XER_decode(*xer_descr(i), reader, flavor, 0); + get_at(i)->XER_decode(*xer_descr(i), reader, flavor, flavor2, 0); } // next field } else if (own_tag || parent_tag) { // EXER and not UNTAGGED: do attributes @@ -5213,7 +5238,12 @@ int Record_Type::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, } /* * * * * * * * * Attributes * * * * * * * * * * * * * */ - for (success = reader.MoveToFirstAttribute(); + if(parent_tag && reader.NodeType() == XML_READER_TYPE_ATTRIBUTE) { + success = reader.Ok(); + } else { + success = reader.MoveToFirstAttribute(); + } + for (; success == 1 && reader.NodeType() == XML_READER_TYPE_ATTRIBUTE; success = reader.AdvanceAttribute()) { @@ -5227,7 +5257,7 @@ int Record_Type::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, if (field_index != -1) { // There is a field. Let it decode the attribute. ec_1.set_msg("%s': ", fld_name(field_index)); - get_at(field_index)->XER_decode(*xer_descr(field_index), reader, flavor, 0); + get_at(field_index)->XER_decode(*xer_descr(field_index), reader, flavor, flavor2, 0); continue; } @@ -5249,8 +5279,13 @@ int Record_Type::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, continue; } // it is the "nil" attribute + // else, let the nillable field decode the next attributes, it is possible + // that it belongs to him + get_at(field_cnt-1)->XER_decode(*xer_descr(field_cnt-1), reader, flavor | USE_NIL, flavor2 | USE_NIL_PARENT_TAG, 0); + already_processed = TRUE; + continue; } // type has USE-NIL - + if (parent_tag) { const char *prefix = (const char*)reader.Prefix(); // prefix may be NULL, control_ns->px is never NULL or empty @@ -5311,7 +5346,7 @@ int Record_Type::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, continue; } } - + // Nobody wanted the attribute. That is an error. ec_0.set_msg(" "); ec_1.set_msg(" "); TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG, @@ -5333,7 +5368,7 @@ int Record_Type::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, // AdvanceAttribute did MoveToElement. Move into the content (if any). if (!reader.IsEmptyElement()) reader.Read(); } // end if (own_tag) - + /* * * * * * * * Non-attributes (elements) * * * * * * * * * * * */ embed_values_dec_struct_t* emb_val = 0; bool emb_val_optional = false; @@ -5450,7 +5485,7 @@ int Record_Type::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, static_cast<Enum_Type*>(use_order->get_at(i - begin)) ->from_int(in_dex); Base_Type *b = jumbled->get_at(k); - b->XER_decode(*jumbled->xer_descr(k), reader, flavor, emb_val); + b->XER_decode(*jumbled->xer_descr(k), reader, flavor, flavor2, emb_val); field_name_found = true; break; } @@ -5476,7 +5511,7 @@ int Record_Type::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, static_cast<Enum_Type*>(use_order->get_at(i - begin)) ->from_int(in_dex); Base_Type *b = jumbled->get_at(k); - b->XER_decode(*jumbled->xer_descr(k), reader, flavor, emb_val); + b->XER_decode(*jumbled->xer_descr(k), reader, flavor, flavor2, emb_val); last_any_elem = k; field_name_found = true; break; @@ -5561,12 +5596,12 @@ int Record_Type::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, optional_any_elem_check = opt_field->XER_check_any_elem(reader, next_field_name, tag_closed); } } - if (optional_any_elem_check) { + if (optional_any_elem_check && !already_processed) { int new_flavor = flavor ; if (i == field_cnt-1) new_flavor |= (p_td.xer_bits & USE_NIL); if (tag_closed) new_flavor |= PARENT_CLOSED; - get_at(i)->XER_decode(*xer_descr(i), reader, new_flavor, emb_val); + get_at(i)->XER_decode(*xer_descr(i), reader, new_flavor, flavor2, emb_val); } } if (!get_at(i)->is_present()) { @@ -5808,14 +5843,15 @@ int Record_Type::JSON_decode(const TTCN_Typedescriptor_t& p_td, JSON_Tokenizer& } else if (JSON_TOKEN_OBJECT_START != token) { return JSON_ERROR_INVALID_TOKEN; - } - bound_flag = TRUE; + } const int field_count = get_count(); // initialize meta info states int* metainfo = new int[field_count]; + boolean* field_found = new boolean[field_count]; for (int i = 0; i < field_count; ++i) { + field_found[i] = FALSE; metainfo[i] = (NULL != fld_descr(i)->json && fld_descr(i)->json->metainfo_unbound) ? JSON_METAINFO_NONE : JSON_METAINFO_NOT_APPLICABLE; } @@ -5855,6 +5891,7 @@ int Record_Type::JSON_decode(const TTCN_Typedescriptor_t& p_td, JSON_Tokenizer& } if (strlen(expected_name) == name_len && 0 == strncmp(expected_name, name, name_len)) { + field_found[field_idx] = TRUE; break; } } @@ -5942,7 +5979,7 @@ int Record_Type::JSON_decode(const TTCN_Typedescriptor_t& p_td, JSON_Tokenizer& // no meta info was found for this field, report the delayed error JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_FIELD_TOKEN_ERROR, fld_name(field_idx)); } - else if (!field->is_bound()) { + else if (!field_found[field_idx]) { if (NULL != fld_descr(field_idx)->json && NULL != fld_descr(field_idx)->json->default_value) { get_at(field_idx)->JSON_decode(*fld_descr(field_idx), DUMMY_BUFFER, p_silent); } @@ -6145,7 +6182,7 @@ void Empty_Record_Type::decode(const TTCN_Typedescriptor_t& p_td, for (int success=reader.Read(); success==1; success=reader.Read()) { if (reader.NodeType() == XML_READER_TYPE_ELEMENT) break; } - XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL, 0); + XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL, XER_NONE, 0); size_t bytes = reader.ByteConsumed(); p_buf.set_pos(bytes); break;} @@ -6268,7 +6305,7 @@ int Empty_Record_Type::XER_encode(const XERdescriptor_t& p_td, } int Empty_Record_Type::XER_decode(const XERdescriptor_t& p_td, - XmlReaderWrap& reader, unsigned int flavor, embed_values_dec_struct_t*) + XmlReaderWrap& reader, unsigned int flavor, unsigned int /*flavor2*/, embed_values_dec_struct_t*) { int exer = is_exer(flavor); bound_flag = true; diff --git a/etc/xsd/TPD.xsd b/etc/xsd/TPD.xsd index 7d952d119c3beb2086ed6e89c6ceda6b130e3738..81d6d5550bce011e95715a6bdb8be41cdf811331 100644 --- a/etc/xsd/TPD.xsd +++ b/etc/xsd/TPD.xsd @@ -105,6 +105,7 @@ XML Schema for TITAN_Project_File_Information <xs:element name="suppressWarnings" minOccurs="0" maxOccurs="1" type="xs:boolean" /> <xs:element name="outParamBoundness" minOccurs="0" maxOccurs="1" type="xs:boolean" /> <xs:element name="omitInValueList" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="warningsForBadVariants" minOccurs="0" maxOccurs="1" type="xs:boolean" /> <xs:element name="quietly" minOccurs="0" maxOccurs="1" type="xs:boolean" /> <xs:element name="namingRules" minOccurs="0" maxOccurs="1" type="xs:normalizedString" /> <xs:element name="disableSubtypeChecking" minOccurs="0" maxOccurs="1" type="xs:boolean" /> @@ -408,6 +409,7 @@ XML Schema for TITAN_Project_File_Information <xs:complexType> <xs:attribute name="name" type="xs:normalizedString" use="required" /> <xs:attribute name="projectLocationURI" type="xs:normalizedString" use="required" /> + <xs:attribute name="tpdName" type="xs:normalizedString" use="optional" /> </xs:complexType> </xs:element> </xs:sequence> diff --git a/function_test/Semantic_Analyser/TTCN3_SA_1_TD.script b/function_test/Semantic_Analyser/TTCN3_SA_1_TD.script index 2d389814d32772eb95f810debb0f5c73b157bb40..2bf1fac408105a1bce4e004e68b412971e6bffe8 100644 --- a/function_test/Semantic_Analyser/TTCN3_SA_1_TD.script +++ b/function_test/Semantic_Analyser/TTCN3_SA_1_TD.script @@ -7077,7 +7077,7 @@ module ModuleA { } <END_MODULE> <RESULT IF_PASS COUNT 1> -(?im)\berror\b.+?invalid.+?field.+?reference.+?Nonexi08 +(?im)\berror\b.+?Referencing.+?fields.+?component.+?not.+?allowed <END_RESULT> <RESULT IF_PASS COUNT 1> (?is)\berror: diff --git a/function_test/Semantic_Analyser/xer/bogus_SE.ttcn b/function_test/Semantic_Analyser/xer/bogus_SE.ttcn index 191d38250ed2b6027b62a8ee96c32d4ac9099928..c531ba810a61923e3725ed463855fdcc81b6fc5d 100644 --- a/function_test/Semantic_Analyser/xer/bogus_SE.ttcn +++ b/function_test/Semantic_Analyser/xer/bogus_SE.ttcn @@ -8,7 +8,7 @@ module bogus { //^In TTCN-3 module `bogus':// type integer i //^In type definition// - with { variant "variant" } //^warning: in variant attribute.+?syntax error, unexpected XIdentifier, expecting \$end// + with { variant "variant" } //^error: in variant attribute.+?syntax error, unexpected XIdentifier, expecting \$end// } with { diff --git a/regression_test/XML/EXER-whitepaper/UseNil.ttcnpp b/regression_test/XML/EXER-whitepaper/UseNil.ttcnpp index e857b51ce0cd9afdedd8c452e9989dab7c583b8d..3cd779dfe4a93d691a273853490b064a4255231b 100644 --- a/regression_test/XML/EXER-whitepaper/UseNil.ttcnpp +++ b/regression_test/XML/EXER-whitepaper/UseNil.ttcnpp @@ -536,6 +536,229 @@ testcase decode_multi_nil() runs on Nil { /* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */ +// Encoding nillable field, which is a record type without attributes + +type record NilTypeRec { + record { + TypeWithoutAttr nil optional + } field +} with { + variant(field) "useNil"; +} + +type record TypeWithoutAttr { + charstring inner_field +} + +const NilTypeRec c_nil_rec_absent := { + field := { + nil := omit + } +}; + +const universal charstring str_nil_rec_absent := +"<NilTypeRec xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>\n" & +"\t<field xsi:nil='true'/>\n" & +"</NilTypeRec>\n\n"; + +const NilTypeRec c_nil_rec_present_no_attr := { + field := { + nil := { + inner_field := "field" + } + } +}; + +const universal charstring str_nil_rec_present_no_attr := +"<NilTypeRec>\n" & +"\t<field>\n" & +"\t\t<inner_field>field</inner_field>\n" & +"\t</field>\n" & +"</NilTypeRec>\n\n"; + +DECLARE_EXER_ENCODERS(NilTypeRec, typerec); + +testcase encode_NilTypeRec() runs on Nil { + CHECK_METHOD(exer_enc_typerec, c_nil_rec_absent, str_nil_rec_absent); + CHECK_METHOD(exer_enc_typerec, c_nil_rec_present_no_attr, str_nil_rec_present_no_attr); +} + +testcase decode_NilTypeRec() runs on Nil { + CHECK_DECODE(exer_dec_typerec, str_nil_rec_absent, NilTypeRec, c_nil_rec_absent); + CHECK_DECODE(exer_dec_typerec, str_nil_rec_present_no_attr, NilTypeRec, c_nil_rec_present_no_attr); +} + +/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */ + +// Encoding nillable field, which is a record type with attributes + +type record NilTypeRecInAttr { + record { + TypeWithAttr nil optional + } field +} with { + variant(field) "useNil"; +} + +type record TypeWithAttr { + charstring attr1 optional, + charstring inner_field +} with { + variant (attr1) "attribute"; +} + +const NilTypeRecInAttr c_nil_rec_absent2 := { + field := { + nil := omit + } +}; + +const universal charstring str_nil_rec_absent2 := +"<NilTypeRecInAttr xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>\n" & +"\t<field xsi:nil='true'/>\n" & +"</NilTypeRecInAttr>\n\n"; + +const NilTypeRecInAttr c_nil_rec_present_attr_omit := { + field := { + nil := { + attr1 := omit, + inner_field := "field" + } + } +}; + +const universal charstring str_nil_rec_present_attr_omit := +"<NilTypeRecInAttr>\n" & +"\t<field>\n" & +"\t\t<inner_field>field</inner_field>\n" & +"\t</field>\n" & +"</NilTypeRecInAttr>\n\n"; + +const NilTypeRecInAttr c_nil_rec_present_attr_present := { + field := { + nil := { + attr1 := "attr", + inner_field := "field" + } + } +}; + +const universal charstring str_nil_rec_present_attr_present := +"<NilTypeRecInAttr>\n" & +"\t<field attr1='attr'>\n" & +"\t\t<inner_field>field</inner_field>\n" & +"\t</field>\n" & +"</NilTypeRecInAttr>\n\n"; + +DECLARE_EXER_ENCODERS(NilTypeRecInAttr, typerecinattr); + +testcase encode_NilTypeRecInAttr() runs on Nil { + CHECK_METHOD(exer_enc_typerecinattr, c_nil_rec_absent2, str_nil_rec_absent2); + CHECK_METHOD(exer_enc_typerecinattr, c_nil_rec_present_attr_omit, str_nil_rec_present_attr_omit); + CHECK_METHOD(exer_enc_typerecinattr, c_nil_rec_present_attr_present, str_nil_rec_present_attr_present); +} + +testcase decode_NilTypeRecInAttr() runs on Nil { + CHECK_DECODE(exer_dec_typerecinattr, str_nil_rec_absent2, NilTypeRecInAttr, c_nil_rec_absent2); + CHECK_DECODE(exer_dec_typerecinattr, str_nil_rec_present_attr_omit, NilTypeRecInAttr, c_nil_rec_present_attr_omit); + //CHECK_DECODE(exer_dec_typerecinattr, str_nil_rec_present_attr_present, NilTypeRecInAttr, c_nil_rec_present_attr_present); +} + +/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */ + +// Encoding nillable field with attribute, which is a record type that has attributes + +type record NilTypeRecAttr { + record { + charstring outer_attr optional, + TypeWithAttr nil optional + } field +} with { + variant(field.outer_attr) "attribute"; + variant(field) "useNil"; +} + +const NilTypeRecAttr c_nil_absent := { + field := { + outer_attr := "outer", + nil := omit + } +}; + +const universal charstring str_nil_absent := +"<NilTypeRecAttr xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>\n" & +"\t<field outer_attr='outer' xsi:nil='true'/>\n" & +"</NilTypeRecAttr>\n\n"; + +const NilTypeRecAttr c_nil_present := { + field := { + outer_attr := "outer", + nil := { + attr1 := "a", + inner_field := "field" + } + } +}; + +const universal charstring str_nil_present := +"<NilTypeRecAttr>\n" & +"\t<field outer_attr='outer' attr1='a'>\n" & +"\t\t<inner_field>field</inner_field>\n" & +"\t</field>\n" & +"</NilTypeRecAttr>\n\n"; + +const NilTypeRecAttr c_nil_present2 := { + field := { + outer_attr := omit, + nil := { + attr1 := "a", + inner_field := "field" + } + } +}; + +const universal charstring str_nil_present2 := +"<NilTypeRecAttr>\n" & +"\t<field attr1='a'>\n" & +"\t\t<inner_field>field</inner_field>\n" & +"\t</field>\n" & +"</NilTypeRecAttr>\n\n"; + +const NilTypeRecAttr c_nil_present_attr_absent := { + field := { + outer_attr := "outer", + nil := { + attr1 := omit, + inner_field := "field" + } + } +}; + +const universal charstring str_nil_present_attr_absent := +"<NilTypeRecAttr>\n" & +"\t<field outer_attr='outer'>\n" & +"\t\t<inner_field>field</inner_field>\n" & +"\t</field>\n" & +"</NilTypeRecAttr>\n\n"; + +DECLARE_EXER_ENCODERS(NilTypeRecAttr, typeattr); + +testcase encode_NilTypeRecAttr() runs on Nil { + CHECK_METHOD(exer_enc_typeattr, c_nil_absent, str_nil_absent); + CHECK_METHOD(exer_enc_typeattr, c_nil_present, str_nil_present); + CHECK_METHOD(exer_enc_typeattr, c_nil_present2, str_nil_present2); + CHECK_METHOD(exer_enc_typeattr, c_nil_present_attr_absent, str_nil_present_attr_absent); +} + +testcase decode_NilTypeRecAttr() runs on Nil { + CHECK_DECODE(exer_dec_typeattr, str_nil_absent, NilTypeRecAttr, c_nil_absent); + CHECK_DECODE(exer_dec_typeattr, str_nil_present, NilTypeRecAttr, c_nil_present); + CHECK_DECODE(exer_dec_typeattr, str_nil_present2, NilTypeRecAttr, c_nil_present2); + CHECK_DECODE(exer_dec_typeattr, str_nil_present_attr_absent, NilTypeRecAttr, c_nil_present_attr_absent); +} + +/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */ + control { execute(encode_nil_absent()); execute(encode_nil_present()); @@ -561,6 +784,15 @@ control { execute(encode_multi_nil()); execute(decode_multi_nil()); + + execute(encode_NilTypeRec()); + execute(decode_NilTypeRec()); + + execute(encode_NilTypeRecInAttr()); + execute(decode_NilTypeRecInAttr()); + + execute(encode_NilTypeRecAttr()); + execute(decode_NilTypeRecAttr()); } } diff --git a/regression_test/XML/HR49727/UsefulTtcn3Types.ttcn b/regression_test/XML/HR49727/UsefulTtcn3Types.ttcn index bac9ef5017b44b25cce102d390d94fc632c07a63..2f45065b901fc2e8ff44097cd155dd1f9976779e 100644 --- a/regression_test/XML/HR49727/UsefulTtcn3Types.ttcn +++ b/regression_test/XML/HR49727/UsefulTtcn3Types.ttcn @@ -1,10 +1,23 @@ -/****************************************************************************** - * Copyright (c) 2000-2015 Ericsson Telecom AB - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - ******************************************************************************/ +/******************************************************************************* +* Copyright (c) 2000-2016 Ericsson Telecom AB +* +* XSD to TTCN-3 Translator version: CRL 113 200/5 R4C +* +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +*******************************************************************************/ +// +// File: UsefulTtcn3Types.ttcn +// Description: +// References: +// Rev: +// Prodnr: +// Updated: +// Contact: http://ttcn.ericsson.se +// +//////////////////////////////////////////////////////////////////////////////// module UsefulTtcn3Types { diff --git a/regression_test/XML/HR49727/XSD.ttcn b/regression_test/XML/HR49727/XSD.ttcn index fe79336e97a3633e0cf9930af187e4b0ac8a1522..972cf66863d442827ab05418cdaf09682ac8d0cb 100644 --- a/regression_test/XML/HR49727/XSD.ttcn +++ b/regression_test/XML/HR49727/XSD.ttcn @@ -1,10 +1,23 @@ -/****************************************************************************** - * Copyright (c) 2000-2015 Ericsson Telecom AB - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - ******************************************************************************/ +/******************************************************************************* +* Copyright (c) 2000-2016 Ericsson Telecom AB +* +* XSD to TTCN-3 Translator version: CRL 113 200/5 R4C +* +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +*******************************************************************************/ +// +// File: XSD.ttcn +// Description: +// References: +// Rev: +// Prodnr: +// Updated: +// Contact: http://ttcn.ericsson.se +// +//////////////////////////////////////////////////////////////////////////////// module XSD { import from UsefulTtcn3Types all; diff --git a/regression_test/XML/XmlWorkflow/Tgc/UsefulTtcn3Types.ttcn b/regression_test/XML/XmlWorkflow/Tgc/UsefulTtcn3Types.ttcn index bac9ef5017b44b25cce102d390d94fc632c07a63..2f45065b901fc2e8ff44097cd155dd1f9976779e 100644 --- a/regression_test/XML/XmlWorkflow/Tgc/UsefulTtcn3Types.ttcn +++ b/regression_test/XML/XmlWorkflow/Tgc/UsefulTtcn3Types.ttcn @@ -1,10 +1,23 @@ -/****************************************************************************** - * Copyright (c) 2000-2015 Ericsson Telecom AB - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - ******************************************************************************/ +/******************************************************************************* +* Copyright (c) 2000-2016 Ericsson Telecom AB +* +* XSD to TTCN-3 Translator version: CRL 113 200/5 R4C +* +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +*******************************************************************************/ +// +// File: UsefulTtcn3Types.ttcn +// Description: +// References: +// Rev: +// Prodnr: +// Updated: +// Contact: http://ttcn.ericsson.se +// +//////////////////////////////////////////////////////////////////////////////// module UsefulTtcn3Types { diff --git a/regression_test/XML/XmlWorkflow/Tgc/XSD.ttcn b/regression_test/XML/XmlWorkflow/Tgc/XSD.ttcn index fe79336e97a3633e0cf9930af187e4b0ac8a1522..972cf66863d442827ab05418cdaf09682ac8d0cb 100644 --- a/regression_test/XML/XmlWorkflow/Tgc/XSD.ttcn +++ b/regression_test/XML/XmlWorkflow/Tgc/XSD.ttcn @@ -1,10 +1,23 @@ -/****************************************************************************** - * Copyright (c) 2000-2015 Ericsson Telecom AB - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - ******************************************************************************/ +/******************************************************************************* +* Copyright (c) 2000-2016 Ericsson Telecom AB +* +* XSD to TTCN-3 Translator version: CRL 113 200/5 R4C +* +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +*******************************************************************************/ +// +// File: XSD.ttcn +// Description: +// References: +// Rev: +// Prodnr: +// Updated: +// Contact: http://ttcn.ericsson.se +// +//////////////////////////////////////////////////////////////////////////////// module XSD { import from UsefulTtcn3Types all; diff --git a/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_including_module_e.ttcn b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_including_module_e.ttcn new file mode 100644 index 0000000000000000000000000000000000000000..a84927226dd5f6311324d70a39dc58c2ba337f37 --- /dev/null +++ b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_including_module_e.ttcn @@ -0,0 +1,63 @@ +/******************************************************************************* +* Copyright (c) 2000-2016 Ericsson Telecom AB +* +* XSD to TTCN-3 Translator version: CRL 113 200/5 R3C +* +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +*******************************************************************************/ +// +// File: www_example_org_including_module_e.ttcn +// Description: +// References: +// Rev: +// Prodnr: +// Updated: Thu Feb 25 18:57:57 2015 +// Contact: http://ttcn.ericsson.se +// +//////////////////////////////////////////////////////////////////////////////// +// Generated from file(s): +// - including_module_e.xsd +// /* xml version = "1.0" encoding = "UTF-8" */ +// /* targetnamespace = "www.example.org/including/module/e" */ +//////////////////////////////////////////////////////////////////////////////// +// Modification header(s): +//----------------------------------------------------------------------------- +// Modified by: +// Modification date: +// Description: +// Modification contact: +//------------------------------------------------------------------------------ +//////////////////////////////////////////////////////////////////////////////// + + +module www_example_org_including_module { + + +import from XSD all; + + +type record Type +{ + XSD.String base +} +with { + variant (base) "untagged"; +}; + + +type Type Elem +with { + variant "element"; +}; + + +} +with { + encode "XML"; + variant "namespace as 'www.example.org/including/module'"; + variant "controlNamespace 'http://www.w3.org/2001/XMLSchema-instance' prefix 'xsi'"; + variant "elementFormQualified"; +} diff --git a/regression_test/XML/XmlWorkflow/XmlTest_xsds/UsefulTtcn3Types.ttcn b/regression_test/XML/XmlWorkflow/XmlTest_xsds/UsefulTtcn3Types.ttcn index bac9ef5017b44b25cce102d390d94fc632c07a63..2f45065b901fc2e8ff44097cd155dd1f9976779e 100644 --- a/regression_test/XML/XmlWorkflow/XmlTest_xsds/UsefulTtcn3Types.ttcn +++ b/regression_test/XML/XmlWorkflow/XmlTest_xsds/UsefulTtcn3Types.ttcn @@ -1,10 +1,23 @@ -/****************************************************************************** - * Copyright (c) 2000-2015 Ericsson Telecom AB - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - ******************************************************************************/ +/******************************************************************************* +* Copyright (c) 2000-2016 Ericsson Telecom AB +* +* XSD to TTCN-3 Translator version: CRL 113 200/5 R4C +* +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +*******************************************************************************/ +// +// File: UsefulTtcn3Types.ttcn +// Description: +// References: +// Rev: +// Prodnr: +// Updated: +// Contact: http://ttcn.ericsson.se +// +//////////////////////////////////////////////////////////////////////////////// module UsefulTtcn3Types { diff --git a/regression_test/XML/XmlWorkflow/XmlTest_xsds/XSD.ttcn b/regression_test/XML/XmlWorkflow/XmlTest_xsds/XSD.ttcn index 5205cfda3f50c2bb60274ec627953fa517ab3753..59c9f36406e827873fad7c018000c61a5ee20b60 100644 --- a/regression_test/XML/XmlWorkflow/XmlTest_xsds/XSD.ttcn +++ b/regression_test/XML/XmlWorkflow/XmlTest_xsds/XSD.ttcn @@ -1,10 +1,23 @@ -/****************************************************************************** - * Copyright (c) 2000-2015 Ericsson Telecom AB - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - ******************************************************************************/ +/******************************************************************************* +* Copyright (c) 2000-2016 Ericsson Telecom AB +* +* XSD to TTCN-3 Translator version: CRL 113 200/5 R4C +* +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +*******************************************************************************/ +// +// File: XSD.ttcn +// Description: +// References: +// Rev: +// Prodnr: +// Updated: +// Contact: http://ttcn.ericsson.se +// +//////////////////////////////////////////////////////////////////////////////// module XSD { import from UsefulTtcn3Types all; diff --git a/regression_test/XML/XmlWorkflow/src/UsefulTtcn3Types.ttcn b/regression_test/XML/XmlWorkflow/src/UsefulTtcn3Types.ttcn index bac9ef5017b44b25cce102d390d94fc632c07a63..2f45065b901fc2e8ff44097cd155dd1f9976779e 100644 --- a/regression_test/XML/XmlWorkflow/src/UsefulTtcn3Types.ttcn +++ b/regression_test/XML/XmlWorkflow/src/UsefulTtcn3Types.ttcn @@ -1,10 +1,23 @@ -/****************************************************************************** - * Copyright (c) 2000-2015 Ericsson Telecom AB - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - ******************************************************************************/ +/******************************************************************************* +* Copyright (c) 2000-2016 Ericsson Telecom AB +* +* XSD to TTCN-3 Translator version: CRL 113 200/5 R4C +* +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +*******************************************************************************/ +// +// File: UsefulTtcn3Types.ttcn +// Description: +// References: +// Rev: +// Prodnr: +// Updated: +// Contact: http://ttcn.ericsson.se +// +//////////////////////////////////////////////////////////////////////////////// module UsefulTtcn3Types { diff --git a/regression_test/XML/XmlWorkflow/src/XSD.ttcn b/regression_test/XML/XmlWorkflow/src/XSD.ttcn index fe79336e97a3633e0cf9930af187e4b0ac8a1522..972cf66863d442827ab05418cdaf09682ac8d0cb 100644 --- a/regression_test/XML/XmlWorkflow/src/XSD.ttcn +++ b/regression_test/XML/XmlWorkflow/src/XSD.ttcn @@ -1,10 +1,23 @@ -/****************************************************************************** - * Copyright (c) 2000-2015 Ericsson Telecom AB - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - ******************************************************************************/ +/******************************************************************************* +* Copyright (c) 2000-2016 Ericsson Telecom AB +* +* XSD to TTCN-3 Translator version: CRL 113 200/5 R4C +* +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +*******************************************************************************/ +// +// File: XSD.ttcn +// Description: +// References: +// Rev: +// Prodnr: +// Updated: +// Contact: http://ttcn.ericsson.se +// +//////////////////////////////////////////////////////////////////////////////// module XSD { import from UsefulTtcn3Types all; diff --git a/regression_test/XML/XmlWorkflow/src/xmlTest.prj b/regression_test/XML/XmlWorkflow/src/xmlTest.prj index 61f6eb52cb8948f35c5910b51d1ecf815c36c7d4..7626b6be925cee23389d1be8f10584e67dbf78a0 100644 --- a/regression_test/XML/XmlWorkflow/src/xmlTest.prj +++ b/regression_test/XML/XmlWorkflow/src/xmlTest.prj @@ -155,6 +155,8 @@ <File path="../xsd/type_substitution_complex_cascade.xsd" /> <File path="../xsd/type_substitution_simple_cascade.xsd" /> <File path="../xsd/attribute_enumeration_variant.xsd" /> + <File path="../xsd/including_module.xsd" /> + <File path="../xsd/included_without_namespace.xsd" /> </File_Group> <File_Group name="XmlTest_xsds" > <File path="../XmlTest_xsds/XmlTest_boolean.xsd" /> @@ -386,6 +388,7 @@ <File path="../XmlTest_expectedTtcns/www_XmlTest_org_complex_unique_e.ttcn" /> <File path="../XmlTest_expectedTtcns/www_XmlTest_org_element_nameInheritance_e.ttcn" /> <File path="../XmlTest_expectedTtcns/www_example_org_attribute_enumeration_variant_e.ttcn" /> + <File path="../XmlTest_expectedTtcns/www_example_org_including_module_e.ttcn" /> </File_Group> <File_Group name="XmlTest_src" > <File path="xmlTest_Shell.ttcn" /> diff --git a/regression_test/XML/XmlWorkflow/src/xmlTest_Testcases.ttcn b/regression_test/XML/XmlWorkflow/src/xmlTest_Testcases.ttcn index bf5f0da3389534aee5a474002dbe3c9e83fb1db7..0f3edcfeb597d2f468ed7357db887a647c494ab7 100644 --- a/regression_test/XML/XmlWorkflow/src/xmlTest_Testcases.ttcn +++ b/regression_test/XML/XmlWorkflow/src/xmlTest_Testcases.ttcn @@ -1607,6 +1607,19 @@ group ComplexType { } }//tc_ + //========================================================================= + // tc_complex_include_without_namespace + //========================================================================= + //Positive test: The including schema includes a schema without a namespace + testcase tc_complex_include_without_namespace() runs on xmlTest_CT { + f_shellCommandWithVerdict("xsd2ttcn including_module.xsd included_without_namespace.xsd","",c_shell_successWithoutWarningAndError); + + if(getverdict==pass) { + f_compareFiles( + "www_example_org_including_module_e.ttcn","www_example_org_including_module.ttcn", c_numOfDiff_headerAndModuleName); + } + }//tc_ + //========================================================================= // tc_complex_include_neg1_converter //========================================================================= @@ -1895,6 +1908,21 @@ group Elements{ f_encDecTest_Anything1(vl_pdu,vl_expectedEncodedPdu,vl_expectedDecodedPdu); }//tc_ + testcase tc_element_anyType_embed_encDec() runs on xmlTest_CT { + var Anything1 vl_pdu:= { + embed_values := {"The ordered ", " has arrived ", "Wait for further information.", "Ok"}, + attr :={"someattr=\"1\""}, + elem_list := { + "<ns:a xmlns:ns=\"http://www.example.org/other\">product</ns:a>", + "<ns:b xmlns:ns=\"http://www.example.org/other_1\">2</ns:b>", + "<ns:c xmlns:ns=\"http://www.example.org/other_13\">2</ns:c>" + } + } + var charstring vl_expectedEncodedPdu:= + "<ns31:anything1 xmlns:ns31='www.XmlTest.org/element_anyType' someattr=\"1\">The ordered <ns:a xmlns:ns=\"http://www.example.org/other\">product</ns:a> has arrived <ns:b xmlns:ns=\"http://www.example.org/other_1\">2</ns:b>Wait for further information.<ns:c xmlns:ns=\"http://www.example.org/other_13\">2</ns:c>Ok</ns31:anything1>\n"; + f_encDecTest_Anything1(vl_pdu,vl_expectedEncodedPdu,vl_pdu); + }//tc_ + //=============================================================== // tc_element_anyType_deeper_encDec //=============================================================== @@ -2602,6 +2630,7 @@ control { execute(tc_complex_unique_converter()); execute(tc_complex_include_converter()); execute(tc_complex_include_neg1_converter()); + execute(tc_complex_include_without_namespace()); execute(tc_complex_import_pos1_converter()); execute(tc_complex_import_pos2_converter()); execute(tc_complex_import_neg1_converter()); @@ -2623,6 +2652,7 @@ control { execute(tc_element_anyType_2attrOnly_encDec());//Passed execute(tc_element_anyType_elemOnly_encDec());//Passed, TR: HL29711 execute(tc_element_anyType_encDec());//Passed, HL29711 + execute(tc_element_anyType_embed_encDec()); execute(tc_element_anyType_deeper_encDec()); execute(tc_element_anyType_longer_encDec()); execute(tc_element_recOfElements_converter()); //Passed: TR: HL27438 diff --git a/regression_test/XML/XmlWorkflow/xsd/included_without_namespace.xsd b/regression_test/XML/XmlWorkflow/xsd/included_without_namespace.xsd new file mode 100644 index 0000000000000000000000000000000000000000..d8da3d39cb106873a5b7832c9e89c53ff47968e3 --- /dev/null +++ b/regression_test/XML/XmlWorkflow/xsd/included_without_namespace.xsd @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" + elementFormDefault="qualified" attributeFormDefault="unqualified"> + +<xs:complexType name="Type"> + <xs:simpleContent> + <xs:extension base="xs:string"> + </xs:extension> + </xs:simpleContent> +</xs:complexType> + +</xs:schema> diff --git a/regression_test/XML/XmlWorkflow/xsd/including_module.xsd b/regression_test/XML/XmlWorkflow/xsd/including_module.xsd new file mode 100644 index 0000000000000000000000000000000000000000..b4ee23bc986792943b41b2088707e52a2ccc0ad2 --- /dev/null +++ b/regression_test/XML/XmlWorkflow/xsd/including_module.xsd @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xs:schema targetNamespace="www.example.org/including/module" + xmlns="www.example.org/including/module" + xmlns:xs="http://www.w3.org/2001/XMLSchema" + elementFormDefault="qualified" + attributeFormDefault="unqualified"> + +<xs:include schemaLocation="included_without_namespace.xsd"/> + +<xs:element name="Elem" type="Type"/> + +</xs:schema> diff --git a/regression_test/charstrOper/TcharstrOper.ttcn b/regression_test/charstrOper/TcharstrOper.ttcn index f35d373e198137c3c0deaf4146ccd4d998fcddb3..7bbd0c6af086cdbb42d11817ed3e86c0158941a1 100644 --- a/regression_test/charstrOper/TcharstrOper.ttcn +++ b/regression_test/charstrOper/TcharstrOper.ttcn @@ -387,6 +387,9 @@ type mycstr7 mycstr8 length(1) type charstring mycstr9 (mycstr2) type charstring mycstr10 length(0..infinity) // Full set. +type charstring mycstr11 (pattern "abc?xyz"); +type charstring mycstr12 (pattern @nocase "abc*xyz"); + const mycstr7 c_mycstr1 := "a" const mycstr9 c_mycstr2 := "abcd" @@ -405,15 +408,21 @@ testcase charstrSubtypes() runs on charstrOper_comptype { var template mycstr4 vt_mycstr2 := "ab" // Length with range. var template mycstr6 vt_mycstr3 := "a" // Value range list. var template mycstr7 vt_mycstr4 := vt_mycstr3 // Value range with length. + var template mycstr11 vt_mycstr5 := "abc1xyz"; // Pattern (case sensitive) + var template mycstr12 vt_mycstr6 := "abc123xyz"; // Pattern (case insensitive) var mycstr2 v_mycstr1 := valueof(vt_mycstr1) var mycstr4 v_mycstr2 := valueof(vt_mycstr2) var mycstr6 v_mycstr3 := valueof(vt_mycstr3) var mycstr7 v_mycstr4 := valueof(vt_mycstr4) + var mycstr11 v_mycstr5 := valueof(vt_mycstr5) + var mycstr12 v_mycstr6 := valueof(vt_mycstr6) if (valueof(vt_mycstr1) == v_mycstr1 and v_mycstr2 == valueof(vt_mycstr2)) { setverdict(pass) } else { setverdict(fail) } if (valueof(vt_mycstr3) == v_mycstr3 and v_mycstr4 == valueof(vt_mycstr4)) { setverdict(pass) } else { setverdict(fail) } + if (valueof(vt_mycstr5) == v_mycstr5 and v_mycstr6 == valueof(vt_mycstr6)) { setverdict(pass) } + else { setverdict(fail) } if (c_mycstr1 == f_cstr2() and " " == f_cstr1()) { setverdict(pass) } else { setverdict(fail) } } diff --git a/regression_test/compileonly/mfgen-tpd/Makefile b/regression_test/compileonly/mfgen-tpd/Makefile index 2a04889d7beb6e8fa1c99467c0e9d3fec5064cd2..680e14aa9f230f90de5b634faaef1029fa0d0f56 100644 --- a/regression_test/compileonly/mfgen-tpd/Makefile +++ b/regression_test/compileonly/mfgen-tpd/Makefile @@ -23,15 +23,17 @@ DIRLIST := buildconfig_param invalid_buildconfig_param invalid_buildconfig_tpd H # The default target. ifeq ($(findstring c,$(MFGEN_FLAGS)),) # no -c # Build in "reverse" order to reduce false positives -all: BuildConsumer BuildSupplier BuildSubplier HP35732 HQ56829 BuildDirs HQ60308 +all: BuildConsumer BuildSupplier BuildSubplier HP35732 HQ56829 BuildDirs HQ60308 SearchPaths else # Build from supplier to consumer because central dirs must be ready # when the toplevel is built -all: BuildSubplier BuildSupplier BuildConsumer COMMON NAS HP35732 HQ56829 BuildDirs +all: BuildSubplier BuildSupplier BuildConsumer COMMON NAS HP35732 HQ56829 BuildDirs SearchPaths .NOTPARALLEL: endif +WORKING_DIR := $(shell pwd) + # The run target is not normally used in compileonly. # It can be built manually. run: @@ -82,16 +84,21 @@ NAS: && $(TTCN3_DIR)/bin/ttcn3_makefilegen -fD $(MFGEN_FLAGS) $(COVERAGE_FLAG) -t ../NAS_EPS_v9.7.0_CNL113729.tpd \ && $(MAKEPROG) +SearchPaths: + cd search_paths/main && \ + $(TTCN3_DIR)/bin/ttcn3_makefilegen -fg -t Main.tpd -I/something -I$(WORKING_DIR)/search_paths/dep3/Test3/ -I$(WORKING_DIR)/search_paths/dep2/Test2 -I$(WORKING_DIR)/search_paths/dep2/dep2_1/Test2_1 && \ + cd bin && $(MAKEPROG) + /tmp/issue: -touch $@ clean: @for dir in $(DIRLIST); do $(MAKE) -C $$dir $@ || exit; done if [ -f HQ60308/Makefile ]; then $(MAKEPROG) -C HQ60308 $@ || exit ; else : ; fi - -rm -rf consumer/bin supplier/bin subplier/bin HP35732 COMMON/bin NAS_EPS_v9.7.0_CNL113729/bin HQ60308/Makefile + -rm -rf consumer/bin supplier/bin subplier/bin HP35732 COMMON/bin NAS_EPS_v9.7.0_CNL113729/bin HQ60308/Makefile search_paths/main/bin distclean: clean -rm -f *.out -.PHONY: all clean distclean run BuildDirs BuildConsumer BuildSupplier BuildSubplier HP35732 HQ56829 HQ56834 HQ56848 COMMON NAS HQ60308 +.PHONY: all clean distclean run BuildDirs BuildConsumer BuildSupplier BuildSubplier HP35732 HQ56829 HQ56834 HQ56848 COMMON NAS HQ60308 SearchPaths diff --git a/regression_test/compileonly/mfgen-tpd/search_paths/dep1/Test/src/MyExample.cfg b/regression_test/compileonly/mfgen-tpd/search_paths/dep1/Test/src/MyExample.cfg new file mode 100644 index 0000000000000000000000000000000000000000..8fe1bdf00a00e4116eb8049f05cadc30c26fe9ca --- /dev/null +++ b/regression_test/compileonly/mfgen-tpd/search_paths/dep1/Test/src/MyExample.cfg @@ -0,0 +1,8 @@ +[LOGGING] +LogFile := "../log/MyExample-%n.log" +FileMask := LOG_ALL +ConsoleMask := ERROR | TESTCASE | STATISTICS +LogSourceInfo := Stack + +[EXECUTE] +MyExample.control diff --git a/regression_test/compileonly/mfgen-tpd/search_paths/dep1/Test/src/MyExample.ttcn b/regression_test/compileonly/mfgen-tpd/search_paths/dep1/Test/src/MyExample.ttcn new file mode 100644 index 0000000000000000000000000000000000000000..d2eace0bc376daa9788a901764020904179bb909 --- /dev/null +++ b/regression_test/compileonly/mfgen-tpd/search_paths/dep1/Test/src/MyExample.ttcn @@ -0,0 +1,51 @@ +/****************************************************************************** + * Copyright (c) 2000-2016 Ericsson Telecom AB + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + ******************************************************************************/ +// TTCN-3 version of "Hello, world!" +module MyExample +{ + +import from MyExample2 all; +import from MyExample2_1 all; +import from MyExample3 all; + +type port PCOType message +{ + inout charstring; +} + +type component MTCType +{ + port PCOType MyPCO_PT; +} + +testcase tc_HelloW() runs on MTCType system MTCType +{ + map(mtc:MyPCO_PT, system:MyPCO_PT); + MyPCO_PT.send("Hello, world!"); + setverdict(pass); +} + +testcase tc_HelloW2() runs on MTCType system MTCType +{ + timer TL_T := 15.0; + map(mtc:MyPCO_PT, system:MyPCO_PT); + MyPCO_PT.send("Hello, world!"); + TL_T.start; + alt { + [] MyPCO_PT.receive("Hello, TTCN-3!") { TL_T.stop; setverdict(pass); } + [] TL_T.timeout { setverdict(inconc); } + [] MyPCO_PT.receive { TL_T.stop; setverdict(fail); } + } +} + +control +{ + execute(tc_HelloW()); + execute(tc_HelloW2()); +} +} diff --git a/regression_test/compileonly/mfgen-tpd/search_paths/dep1/Test/src/PCOType.cc b/regression_test/compileonly/mfgen-tpd/search_paths/dep1/Test/src/PCOType.cc new file mode 100644 index 0000000000000000000000000000000000000000..456c41d3022bc603be45584c98c3860eadc20481 --- /dev/null +++ b/regression_test/compileonly/mfgen-tpd/search_paths/dep1/Test/src/PCOType.cc @@ -0,0 +1,108 @@ +// This Test Port skeleton source file was generated by the +// TTCN-3 Compiler of the TTCN-3 Test Executor version CRL 113 200/4 R2A +// for Arpad Lovassy (earplov@esekilxxen1841) on Tue Jul 22 16:49:55 2014 + +// Copyright Ericsson Telecom AB 2000-2016 + +// You may modify this file. Complete the body of empty functions and// add your member functions here. + +#include "PCOType.hh" +#include "memory.h" + +#include <stdio.h> + +namespace MyExample { + +PCOType::PCOType(const char *par_port_name) + : PCOType_BASE(par_port_name) +{ + +} + +PCOType::~PCOType() +{ + +} + +void PCOType::set_parameter(const char * /*parameter_name*/, + const char * /*parameter_value*/) +{ + +} + +void PCOType::Event_Handler(const fd_set *read_fds, + const fd_set *write_fds, const fd_set *error_fds, + double time_since_last_call) +{ + size_t buf_len = 0, buf_size = 32; + char *buf = (char*)Malloc(buf_size); + for ( ; ; ) { + int c = getc(stdin); + if (c == EOF) { + if (buf_len > 0) incoming_message(CHARSTRING(buf_len, buf)); + Uninstall_Handler(); + break; + } else if (c == '\n') { + incoming_message(CHARSTRING(buf_len, buf)); + break; + } else { + if (buf_len >= buf_size) { + buf_size *= 2; + buf = (char*)Realloc(buf, buf_size); + } + buf[buf_len++] = c; + } + } + Free(buf); +} + +/*void PCOType::Handle_Fd_Event(int fd, boolean is_readable, + boolean is_writable, boolean is_error) {}*/ + +void PCOType::Handle_Fd_Event_Error(int /*fd*/) +{ + +} + +void PCOType::Handle_Fd_Event_Writable(int /*fd*/) +{ + +} + +void PCOType::Handle_Fd_Event_Readable(int /*fd*/) +{ + +} + +/*void PCOType::Handle_Timeout(double time_since_last_call) {}*/ + +void PCOType::user_map(const char *system_port) +{ + fd_set readfds; + FD_ZERO(&readfds); + FD_SET(fileno(stdin), &readfds); + Install_Handler(&readfds, NULL, NULL, 0.0); +} + +void PCOType::user_unmap(const char *system_port) +{ + Uninstall_Handler(); +} + +void PCOType::user_start() +{ + +} + +void PCOType::user_stop() +{ + +} + +void PCOType::outgoing_send(const CHARSTRING& send_par) +{ + puts((const char*)send_par); + fflush(stdout); +} + +} /* end of namespace */ diff --git a/regression_test/compileonly/mfgen-tpd/search_paths/dep1/Test/src/PCOType.hh b/regression_test/compileonly/mfgen-tpd/search_paths/dep1/Test/src/PCOType.hh new file mode 100644 index 0000000000000000000000000000000000000000..b86781a55670d1fd61917ce376e9bede36cf5000 --- /dev/null +++ b/regression_test/compileonly/mfgen-tpd/search_paths/dep1/Test/src/PCOType.hh @@ -0,0 +1,48 @@ +// This Test Port skeleton header file was generated by the +// TTCN-3 Compiler of the TTCN-3 Test Executor version CRL 113 200/4 R2A +// for Arpad Lovassy (earplov@esekilxxen1841) on Tue Jul 22 16:49:55 2014 + +// Copyright Ericsson Telecom AB 2000-2016 + +// You may modify this file. Add your attributes and prototypes of your +// member functions here. + +#ifndef PCOType_HH +#define PCOType_HH + +#include "MyExample.hh" + +namespace MyExample { + +class PCOType : public PCOType_BASE { +public: + PCOType(const char *par_port_name = NULL); + ~PCOType(); + + void set_parameter(const char *parameter_name, + const char *parameter_value); + + void Event_Handler(const fd_set *read_fds, + const fd_set *write_fds, const fd_set *error_fds, + double time_since_last_call); + +private: + /* void Handle_Fd_Event(int fd, boolean is_readable, + boolean is_writable, boolean is_error); */ + void Handle_Fd_Event_Error(int fd); + void Handle_Fd_Event_Writable(int fd); + void Handle_Fd_Event_Readable(int fd); + /* void Handle_Timeout(double time_since_last_call); */ +protected: + void user_map(const char *system_port); + void user_unmap(const char *system_port); + + void user_start(); + void user_stop(); + + void outgoing_send(const CHARSTRING& send_par); +}; + +} /* end of namespace */ + +#endif diff --git a/regression_test/compileonly/mfgen-tpd/search_paths/dep1/Test1/DepTpd1.tpd b/regression_test/compileonly/mfgen-tpd/search_paths/dep1/Test1/DepTpd1.tpd new file mode 100644 index 0000000000000000000000000000000000000000..12b46977d23f6337911969f121feb7a704f3fafd --- /dev/null +++ b/regression_test/compileonly/mfgen-tpd/search_paths/dep1/Test1/DepTpd1.tpd @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (c) 2000-2016 Ericsson Telecom AB + + All rights reserved. This program and the accompanying materials + are made available under the terms of the Eclipse Public License v1.0 + which accompanies this distribution, and is available at + http://www.eclipse.org/legal/epl-v10.html + --> +<TITAN_Project_File_Information version="1.0"> + <ProjectName>DepTpd1</ProjectName> + <Folders> + <FolderResource projectRelativePath="src" relativeURI="../Test/src"/> + </Folders> + <Files> + <FileResource projectRelativePath="src/MyExample.cfg" relativeURI="../Test/src/MyExample.cfg"/> + <FileResource projectRelativePath="src/MyExample.ttcn" relativeURI="../Test/src/MyExample.ttcn"/> + <FileResource projectRelativePath="src/PCOType.cc" relativeURI="../Test/src/PCOType.cc"/> + <FileResource projectRelativePath="src/PCOType.hh" relativeURI="../Test/src/PCOType.hh"/> + </Files> + <ActiveConfiguration>Default</ActiveConfiguration> + <Configurations> + <Configuration name="Default"> + <ProjectProperties> + <MakefileSettings> + <singleMode>true</singleMode> + <targetExecutable>bin\DepTpd1.exe</targetExecutable> + <useGoldLinker>false</useGoldLinker> + <freeTextLinkerOptions></freeTextLinkerOptions> + </MakefileSettings> + <LocalBuildSettings> + <workingDirectory>bin</workingDirectory> + </LocalBuildSettings> + </ProjectProperties> + <FileProperties> + <FileResource> + <FilePath>src/MyExample.cfg</FilePath> + <FileProperties> + <ExcludeFromBuild>true</ExcludeFromBuild> + </FileProperties> + </FileResource> + </FileProperties> + </Configuration> + </Configurations> +</TITAN_Project_File_Information> diff --git a/regression_test/compileonly/mfgen-tpd/search_paths/dep2/Test/src/MyExample2.ttcn b/regression_test/compileonly/mfgen-tpd/search_paths/dep2/Test/src/MyExample2.ttcn new file mode 100644 index 0000000000000000000000000000000000000000..e362aae504ecccbb2adf38b23dfcd8a28639c7f3 --- /dev/null +++ b/regression_test/compileonly/mfgen-tpd/search_paths/dep2/Test/src/MyExample2.ttcn @@ -0,0 +1,11 @@ +/****************************************************************************** + * Copyright (c) 2000-2016 Ericsson Telecom AB + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + ******************************************************************************/ +module MyExample2 +{ + +} diff --git a/regression_test/compileonly/mfgen-tpd/search_paths/dep2/Test2/DepTpd2.tpd b/regression_test/compileonly/mfgen-tpd/search_paths/dep2/Test2/DepTpd2.tpd new file mode 100644 index 0000000000000000000000000000000000000000..0f2802fb1b1b4b85e119b6b2d68075c3deede232 --- /dev/null +++ b/regression_test/compileonly/mfgen-tpd/search_paths/dep2/Test2/DepTpd2.tpd @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (c) 2000-2016 Ericsson Telecom AB + + All rights reserved. This program and the accompanying materials + are made available under the terms of the Eclipse Public License v1.0 + which accompanies this distribution, and is available at + http://www.eclipse.org/legal/epl-v10.html + --> +<TITAN_Project_File_Information version="1.0"> + <ProjectName>DepTpd2</ProjectName> + <ReferencedProjects> + <ReferencedProject name="DepTpd2_1" projectLocationURI="bad/dir/DepTpd2_1.tpd" /> + </ReferencedProjects> + <Folders> + <FolderResource projectRelativePath="src" relativeURI="../Test/src"/> + </Folders> + <Files> + <FileResource projectRelativePath="src/MyExample2.ttcn" relativeURI="../Test/src/MyExample2.ttcn"/> + </Files> + <ActiveConfiguration>Default</ActiveConfiguration> + <Configurations> + <Configuration name="Default"> + <ProjectProperties> + <MakefileSettings> + <singleMode>true</singleMode> + <targetExecutable>bin\Test.exe</targetExecutable> + <useGoldLinker>false</useGoldLinker> + <freeTextLinkerOptions></freeTextLinkerOptions> + </MakefileSettings> + <LocalBuildSettings> + <workingDirectory>bin</workingDirectory> + </LocalBuildSettings> + </ProjectProperties> + <FileProperties> + <FileResource> + <FilePath>src/MyExample.cfg</FilePath> + <FileProperties> + <ExcludeFromBuild>true</ExcludeFromBuild> + </FileProperties> + </FileResource> + </FileProperties> + </Configuration> + </Configurations> +</TITAN_Project_File_Information> diff --git a/regression_test/compileonly/mfgen-tpd/search_paths/dep2/dep2_1/Test/src/MyExample2_1.ttcn b/regression_test/compileonly/mfgen-tpd/search_paths/dep2/dep2_1/Test/src/MyExample2_1.ttcn new file mode 100644 index 0000000000000000000000000000000000000000..f54430c9200564745abef79be813c6c12edc0c96 --- /dev/null +++ b/regression_test/compileonly/mfgen-tpd/search_paths/dep2/dep2_1/Test/src/MyExample2_1.ttcn @@ -0,0 +1,11 @@ +/****************************************************************************** + * Copyright (c) 2000-2016 Ericsson Telecom AB + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + ******************************************************************************/ +module MyExample2_1 +{ + +} diff --git a/regression_test/compileonly/mfgen-tpd/search_paths/dep2/dep2_1/Test2_1/DepTpd2_1.tpd b/regression_test/compileonly/mfgen-tpd/search_paths/dep2/dep2_1/Test2_1/DepTpd2_1.tpd new file mode 100644 index 0000000000000000000000000000000000000000..fa00cd2632d77e7099fb190b1f0da2a73b623b67 --- /dev/null +++ b/regression_test/compileonly/mfgen-tpd/search_paths/dep2/dep2_1/Test2_1/DepTpd2_1.tpd @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (c) 2000-2016 Ericsson Telecom AB + + All rights reserved. This program and the accompanying materials + are made available under the terms of the Eclipse Public License v1.0 + which accompanies this distribution, and is available at + http://www.eclipse.org/legal/epl-v10.html + --> +<TITAN_Project_File_Information version="1.0"> + <ProjectName>DepTpd2_1</ProjectName> + <Folders> + <FolderResource projectRelativePath="src" relativeURI="../Test/src"/> + </Folders> + <Files> + <FileResource projectRelativePath="src/MyExample2_1.ttcn" relativeURI="../Test/src/MyExample2_1.ttcn"/> + </Files> + <ActiveConfiguration>Default</ActiveConfiguration> + <Configurations> + <Configuration name="Default"> + <ProjectProperties> + <MakefileSettings> + <singleMode>true</singleMode> + <targetExecutable>bin\Test.exe</targetExecutable> + <useGoldLinker>false</useGoldLinker> + <freeTextLinkerOptions></freeTextLinkerOptions> + </MakefileSettings> + <LocalBuildSettings> + <workingDirectory>bin</workingDirectory> + </LocalBuildSettings> + </ProjectProperties> + <FileProperties> + <FileResource> + <FilePath>src/MyExample.cfg</FilePath> + <FileProperties> + <ExcludeFromBuild>true</ExcludeFromBuild> + </FileProperties> + </FileResource> + </FileProperties> + </Configuration> + </Configurations> +</TITAN_Project_File_Information> diff --git a/regression_test/compileonly/mfgen-tpd/search_paths/dep3/Test/src/MyExample3.ttcn b/regression_test/compileonly/mfgen-tpd/search_paths/dep3/Test/src/MyExample3.ttcn new file mode 100644 index 0000000000000000000000000000000000000000..1d647a50a73deb84d3723c22b4bfef86d59c45ac --- /dev/null +++ b/regression_test/compileonly/mfgen-tpd/search_paths/dep3/Test/src/MyExample3.ttcn @@ -0,0 +1,11 @@ +/****************************************************************************** + * Copyright (c) 2000-2016 Ericsson Telecom AB + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + ******************************************************************************/ +module MyExample3 +{ + +} diff --git a/regression_test/compileonly/mfgen-tpd/search_paths/dep3/Test3/DepTpd3.tpd b/regression_test/compileonly/mfgen-tpd/search_paths/dep3/Test3/DepTpd3.tpd new file mode 100644 index 0000000000000000000000000000000000000000..222b8e54f6c342d45c31a68e78762068af599a33 --- /dev/null +++ b/regression_test/compileonly/mfgen-tpd/search_paths/dep3/Test3/DepTpd3.tpd @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (c) 2000-2016 Ericsson Telecom AB + + All rights reserved. This program and the accompanying materials + are made available under the terms of the Eclipse Public License v1.0 + which accompanies this distribution, and is available at + http://www.eclipse.org/legal/epl-v10.html + --> +<TITAN_Project_File_Information version="1.0"> + <ProjectName>DepTpd3</ProjectName> + <Folders> + <FolderResource projectRelativePath="src" relativeURI="../Test/src"/> + </Folders> + <Files> + <FileResource projectRelativePath="src/MyExample3.ttcn" relativeURI="../Test/src/MyExample3.ttcn"/> + </Files> + <ActiveConfiguration>Default</ActiveConfiguration> + <Configurations> + <Configuration name="Default"> + <ProjectProperties> + <MakefileSettings> + <singleMode>true</singleMode> + <targetExecutable>bin\Test.exe</targetExecutable> + <useGoldLinker>false</useGoldLinker> + <freeTextLinkerOptions></freeTextLinkerOptions> + </MakefileSettings> + <LocalBuildSettings> + <workingDirectory>bin</workingDirectory> + </LocalBuildSettings> + </ProjectProperties> + <FileProperties> + <FileResource> + <FilePath>src/MyExample.cfg</FilePath> + <FileProperties> + <ExcludeFromBuild>true</ExcludeFromBuild> + </FileProperties> + </FileResource> + </FileProperties> + </Configuration> + </Configurations> +</TITAN_Project_File_Information> diff --git a/regression_test/compileonly/mfgen-tpd/search_paths/main/Main.tpd b/regression_test/compileonly/mfgen-tpd/search_paths/main/Main.tpd new file mode 100644 index 0000000000000000000000000000000000000000..bca675febfb9d1a3cf8235c839b07399a289363a --- /dev/null +++ b/regression_test/compileonly/mfgen-tpd/search_paths/main/Main.tpd @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (c) 2000-2016 Ericsson Telecom AB + + All rights reserved. This program and the accompanying materials + are made available under the terms of the Eclipse Public License v1.0 + which accompanies this distribution, and is available at + http://www.eclipse.org/legal/epl-v10.html + --> +<TITAN_Project_File_Information version="1.0"> + <ProjectName>Main</ProjectName> + <ReferencedProjects> + <ReferencedProject name="DepTpd1" projectLocationURI="../dep1/Test1/DepTpd1.tpd" /> + <ReferencedProject name="Second" tpdName="DepTpd2.tpd" projectLocationURI="../bad/path/Test.tpd" /> + <ReferencedProject name="DepTpd3" projectLocationURI="../bad/path/Test.tpd" /> + </ReferencedProjects> + <Folders> + <FolderResource projectRelativePath="src" relativeURI="src"/> + </Folders> + <Files> + <FileResource projectRelativePath="src/MyMain.ttcn" relativeURI="src/MyMain.ttcn"/> + </Files> + <ActiveConfiguration>Default</ActiveConfiguration> + <Configurations> + <Configuration name="Default"> + <ProjectProperties> + <MakefileSettings> + <singleMode>true</singleMode> + <targetExecutable>bin\TpdEnvVarTestMain.exe</targetExecutable> + <useGoldLinker>false</useGoldLinker> + <freeTextLinkerOptions></freeTextLinkerOptions> + </MakefileSettings> + <LocalBuildSettings> + <workingDirectory>bin</workingDirectory> + </LocalBuildSettings> + </ProjectProperties> + </Configuration> + </Configurations> +</TITAN_Project_File_Information> diff --git a/regression_test/compileonly/mfgen-tpd/search_paths/main/src/MyMain.ttcn b/regression_test/compileonly/mfgen-tpd/search_paths/main/src/MyMain.ttcn new file mode 100644 index 0000000000000000000000000000000000000000..f6aa78fc365e8c05780b446420a0b1ca494ee87f --- /dev/null +++ b/regression_test/compileonly/mfgen-tpd/search_paths/main/src/MyMain.ttcn @@ -0,0 +1,13 @@ +/****************************************************************************** + * Copyright (c) 2000-2016 Ericsson Telecom AB + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + ******************************************************************************/ +module MyMain { + import from MyExample all; + import from MyExample2 all; + import from MyExample2_1 all; + import from MyExample3 all; +} diff --git a/regression_test/implicitOmit/IOAsn.asn b/regression_test/implicitOmit/IOAsn.asn new file mode 100644 index 0000000000000000000000000000000000000000..14685d45fa3a806fc07f82fd3528d95a68f84797 --- /dev/null +++ b/regression_test/implicitOmit/IOAsn.asn @@ -0,0 +1,26 @@ +--***************************************************************************** +-- Copyright (c) 2000-2015 Ericsson Telecom AB +-- All rights reserved. This program and the accompanying materials +-- are made available under the terms of the Eclipse Public License v1.0 +-- which accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +--***************************************************************************** +IOAsn +DEFINITIONS + +AUTOMATIC TAGS ::= + +BEGIN + +AsnSequence ::= SEQUENCE { + field1 ENUMERATED { enumVal } OPTIONAL, + field2 CHOICE { + alt1 INTEGER, + alt2 INTEGER + } OPTIONAL, + field3 INTEGER OPTIONAL, + field4 INTEGER OPTIONAL +} + + +END diff --git a/regression_test/implicitOmit/Makefile b/regression_test/implicitOmit/Makefile index a892b09fdccf176e83b996622f156c3525383e46..991ba9d510fdac5717913c987ef88d330a99c780 100644 --- a/regression_test/implicitOmit/Makefile +++ b/regression_test/implicitOmit/Makefile @@ -38,7 +38,7 @@ TTCN3_LIB = ttcn3$(RT2_SUFFIX)$(DYNAMIC_SUFFIX) TTCN3_MODULES = io.ttcn # ASN.1 modules of this project: -ASN1_MODULES = +ASN1_MODULES = IOAsn.asn # C++ source & header files generated from the TTCN-3 & ASN.1 modules of # this project: diff --git a/regression_test/implicitOmit/io.ttcn b/regression_test/implicitOmit/io.ttcn index f326c6d1187d09e91b984975621baf429c9de030..1e20b6add50ec1d50c02db0495edbaa00eb453d2 100644 --- a/regression_test/implicitOmit/io.ttcn +++ b/regression_test/implicitOmit/io.ttcn @@ -6,6 +6,9 @@ * http://www.eclipse.org/legal/epl-v10.html ******************************************************************************/ module io { + +import from IOAsn all; + type component O {} @@ -542,6 +545,16 @@ testcase tc_io_notused() runs on O else { setverdict(fail, c_notused_value); } } +// Implicit omit on an ASN.1 record, with only empty brackets (which is considered as value list notation) +template AsnSequence t_asn_rec_empty := { } with { optional "implicit omit" }; +template AsnSequence t_asn_rec_empty_exp := { omit, omit, omit, omit }; + +testcase tc_io_asn_record_empty() runs on O +{ + if (log2str(t_asn_rec_empty) == log2str(t_asn_rec_empty_exp)) { setverdict(pass); } + else { setverdict(fail, t_asn_rec_empty); } +} + control { execute(tc12()); execute(tc1ab()); @@ -584,6 +597,7 @@ execute(tc_HQ30261()) execute(tc_io_embedded()); execute(tc_io_notused()); +execute(tc_io_asn_record_empty()); } with { optional "implicit omit" diff --git a/regression_test/json/AttributeTestcases.ttcn b/regression_test/json/AttributeTestcases.ttcn index 2c529e67f71132fda27e6e44405892c98f9220af..c371411ddc544cecf67632552a0c5ee410ea9733 100755 --- a/regression_test/json/AttributeTestcases.ttcn +++ b/regression_test/json/AttributeTestcases.ttcn @@ -58,6 +58,14 @@ testcase tc_name_as() runs on MTC { f_bool2verdict( match(f_dec_profile(f_enc_profile(p)), p) ); } +// testing attribute "name as ..." when the aliases are keywords of the JSON variant syntax +testcase tc_name_as_with_keywords() runs on MTC { + var KeywordFields p := { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; + var octetstring os := char2oct("{\"omit\":1,\"as\":2,\"null\":3,\"name\":4,\"value\":5,\"default\":6,\"extend\":7,\"metainfo\":8,\"for\":9,\"unbound\":10,\"JSON\":11}"); + f_check_encoding(encoded := f_enc_kw_fld(p), expected := os); + f_bool2verdict( match(f_dec_kw_fld(os), p) ); +} + //tests in case of selecting attributes: //if omit fields appear in the encoded //if all not omitted field value appear in the correct form @@ -302,11 +310,49 @@ testcase tc_attribute_metainfo_for_unbound_negtest() runs on MTC { setverdict(pass); } +// Decoding test for the 'metainfo for unbound' attribute, where all fields of an embedded record are +// set to unbound by meta info. The decoded embedded record should be unbound. +testcase tc_attribute_metainfo_for_unbound_empty_rec() runs on MTC { + var charstring dec_str := "{\"mynum\":99,\"mystr\":\"aa\", \"myRec\": {\"num\":null,\"metainfo num\":\"unbound\",\"str\":null,\"metainfo str\":\"unbound\" } }"; + var MetainfoOuterRecord dec_val := f_dec_meta_outer_rec(char2oct(dec_str)); + if (isbound(dec_val.myRec)) { + setverdict(fail, "Field myrec should be unbound after decoding, instead of ", dec_val.myRec); + } + var MetainfoOuterRecord dec_val_exp := { mynum := 99, mystr := "aa", myRec := - }; + if (log2str(dec_val) != log2str(dec_val_exp)) { + setverdict(fail, "Invalid value after decoding. Expected: ", dec_val_exp, ", got: ", dec_val); + } + setverdict(pass); +} + +// Encoding array types with unbound elements with meta info (attribute 'metainfo for unbound') +// A JSON object with one key-value pair (containing the meta info) specifies that an element is unbound. +testcase tc_attribute_metainfo_for_unbound_arrays() runs on MTC { + // test 1: pre-generated array type (record of integer) + var MetainfoRecOf recof := { 1, 2, -, 4 }; + var octetstring os := char2oct("[1,2,{\"metainfo []\":\"unbound\"},4]"); + f_check_encoding(encoded := f_enc_meta_recof(recof), expected := os); + f_bool2verdict( log2str(f_dec_meta_recof(os)) == log2str(recof) ); + + // test 2: array of a structured type (set of MetainfoRecord) + var MetainfoSetOf setof := { { num := 3, str := "abc" }, -, { num := 6 } }; + os := char2oct("[{\"num\":3,\"str\":\"abc\"},{\"metainfo []\":\"unbound\"},{\"num\":6,\"str\":null,\"metainfo str\":\"unbound\"}]"); + f_check_encoding(encoded := f_enc_meta_setof(setof), expected := os); + f_bool2verdict( log2str(f_dec_meta_setof(os)) == log2str(setof) ); + + // test 3: TTCN-3 array (float [3]) + var MetainfoArray arr := { 3.0, 6.0, - }; + os := char2oct("[3.000000,6.000000,{\"metainfo []\":\"unbound\"}]"); + f_check_encoding(encoded := f_enc_meta_arr(arr), expected := os); + f_bool2verdict( log2str(f_dec_meta_arr(os)) == log2str(arr) ); +} + control { execute(tc_NoAttributeOnUpperLevel()) execute(tc_name_as_omit_as_null()); execute(tc_name_as()); + execute(tc_name_as_with_keywords()); execute(tc_attribute_compactprint1()); execute(tc_attribute_compactprint2()); execute(tc_attribute_compactprintp()); @@ -319,5 +365,7 @@ control { execute(tc_attribute_optional_as_value()); execute(tc_attribute_metainfo_for_unbound()); execute(tc_attribute_metainfo_for_unbound_negtest()); + execute(tc_attribute_metainfo_for_unbound_empty_rec()); + execute(tc_attribute_metainfo_for_unbound_arrays()); } } diff --git a/regression_test/json/Functions.ttcn b/regression_test/json/Functions.ttcn index 912df569b0dbb5c9d78c70c18dea2d1fe5c22619..5993c6714ee1f3cb397019aad8a5215b28d3cce9 100755 --- a/regression_test/json/Functions.ttcn +++ b/regression_test/json/Functions.ttcn @@ -98,6 +98,9 @@ external function f_enc_profile0(in Profile0 u) return octetstring external function f_enc_cba(in CBA u) return octetstring with { extension "prototype(convert)"; extension "encode(JSON)"; } +external function f_enc_kw_fld(in KeywordFields u) return octetstring + with { extension "prototype(convert)"; extension "encode(JSON)"; } + external function f_enc_stuff(in Stuff x) return octetstring with { extension "prototype(convert) encode(JSON)" } @@ -115,6 +118,18 @@ external function f_enc_meta_rec(in MetainfoRecord x) return octetstring external function f_enc_meta_set(in MetainfoSet x) return octetstring with { extension "prototype(convert) encode(JSON)" } + +external function f_enc_meta_outer_rec(in MetainfoOuterRecord x) return octetstring + with { extension "prototype(convert) encode(JSON)" } + +external function f_enc_meta_recof(in MetainfoRecOf x) return octetstring + with { extension "prototype(convert) encode(JSON)" } + +external function f_enc_meta_setof(in MetainfoSetOf x) return octetstring + with { extension "prototype(convert) encode(JSON)" } + +external function f_enc_meta_arr(in MetainfoArray x) return octetstring + with { extension "prototype(convert) encode(JSON)" } // for ASN.1 types external function f_enc_seqofint(in SeqOfInt x) return octetstring @@ -213,6 +228,9 @@ external function f_dec_profile0(in octetstring u) return Profile0 external function f_dec_cba(in octetstring u) return CBA with { extension "prototype(convert)"; extension "decode(JSON)"; } +external function f_dec_kw_fld(in octetstring u) return KeywordFields + with { extension "prototype(convert)"; extension "decode(JSON)"; } + external function f_dec_stuff(in octetstring x) return Stuff with { extension "prototype(convert) decode(JSON)" } @@ -233,6 +251,18 @@ external function f_dec_meta_rec(in octetstring x) return MetainfoRecord external function f_dec_meta_set(in octetstring x) return MetainfoSet with { extension "prototype(convert) decode(JSON)" } + +external function f_dec_meta_outer_rec(in octetstring x) return MetainfoOuterRecord + with { extension "prototype(convert) decode(JSON)" } + +external function f_dec_meta_recof(in octetstring x) return MetainfoRecOf + with { extension "prototype(convert) decode(JSON)" } + +external function f_dec_meta_setof(in octetstring x) return MetainfoSetOf + with { extension "prototype(convert) decode(JSON)" } + +external function f_dec_meta_arr(in octetstring x) return MetainfoArray + with { extension "prototype(convert) decode(JSON)" } // for ASN.1 types external function f_dec_seqofint(in octetstring x) return SeqOfInt diff --git a/regression_test/json/Types.ttcn b/regression_test/json/Types.ttcn index b3ed9a21ac34b70c1cfc4f9df96fcc9d2be2966e..c75b83cda3c1b2cb2392c2bd05feb8783816d25d 100755 --- a/regression_test/json/Types.ttcn +++ b/regression_test/json/Types.ttcn @@ -106,6 +106,33 @@ type set Product { variant(price) "JSON:omit as null" } +type record KeywordFields { + integer a1, + integer a2, + integer a3, + integer a4, + integer a5, + integer a6, + integer a7, + integer a8, + integer a9, + integer a10, + integer a11 +} +with { + variant(a1) "JSON: name as omit"; + variant(a2) "JSON: name as as"; + variant(a3) "JSON: name as null"; + variant(a4) "JSON: name as name"; + variant(a5) "JSON: name as value"; + variant(a6) "JSON: name as default"; + variant(a7) "JSON: name as extend"; + variant(a8) "JSON: name as metainfo"; + variant(a9) "JSON: name as for"; + variant(a10) "JSON: name as unbound"; + variant(a11) "JSON: name as JSON"; +} + type union Thing { integer ival, float fval, @@ -203,6 +230,29 @@ with { variant (num) " JSON : name as int "; } +type record MetainfoInnerRecord { + integer num, + charstring str +} +with { + variant "JSON: metainfo for unbound"; +} + +type record MetainfoOuterRecord { + integer mynum, + charstring mystr, + MetainfoInnerRecord myRec +} + +type record of integer MetainfoRecOf +with { variant "JSON: metainfo for unbound"; } + +type set of MetainfoRecord MetainfoSetOf +with { variant "JSON: metainfo for unbound"; } + +type float MetainfoArray[3] +with { variant "JSON: metainfo for unbound"; } + } with { encode "JSON"; } diff --git a/regression_test/negativeTest/UsefulTtcn3Types.ttcn b/regression_test/negativeTest/UsefulTtcn3Types.ttcn index bac9ef5017b44b25cce102d390d94fc632c07a63..2f45065b901fc2e8ff44097cd155dd1f9976779e 100644 --- a/regression_test/negativeTest/UsefulTtcn3Types.ttcn +++ b/regression_test/negativeTest/UsefulTtcn3Types.ttcn @@ -1,10 +1,23 @@ -/****************************************************************************** - * Copyright (c) 2000-2015 Ericsson Telecom AB - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - ******************************************************************************/ +/******************************************************************************* +* Copyright (c) 2000-2016 Ericsson Telecom AB +* +* XSD to TTCN-3 Translator version: CRL 113 200/5 R4C +* +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +*******************************************************************************/ +// +// File: UsefulTtcn3Types.ttcn +// Description: +// References: +// Rev: +// Prodnr: +// Updated: +// Contact: http://ttcn.ericsson.se +// +//////////////////////////////////////////////////////////////////////////////// module UsefulTtcn3Types { diff --git a/regression_test/negativeTest/XSD.ttcn b/regression_test/negativeTest/XSD.ttcn index fe79336e97a3633e0cf9930af187e4b0ac8a1522..972cf66863d442827ab05418cdaf09682ac8d0cb 100644 --- a/regression_test/negativeTest/XSD.ttcn +++ b/regression_test/negativeTest/XSD.ttcn @@ -1,10 +1,23 @@ -/****************************************************************************** - * Copyright (c) 2000-2015 Ericsson Telecom AB - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - ******************************************************************************/ +/******************************************************************************* +* Copyright (c) 2000-2016 Ericsson Telecom AB +* +* XSD to TTCN-3 Translator version: CRL 113 200/5 R4C +* +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +*******************************************************************************/ +// +// File: XSD.ttcn +// Description: +// References: +// Rev: +// Prodnr: +// Updated: +// Contact: http://ttcn.ericsson.se +// +//////////////////////////////////////////////////////////////////////////////// module XSD { import from UsefulTtcn3Types all; diff --git a/regression_test/predefFunction/regex_OK.ttcn b/regression_test/predefFunction/regex_OK.ttcn index da2131fa5a08cfda7384b6f37fb01b5b20d7729e..61e4ab0997b3c5e2b0ff47f8547d70e378f8952d 100644 --- a/regression_test/predefFunction/regex_OK.ttcn +++ b/regression_test/predefFunction/regex_OK.ttcn @@ -65,8 +65,8 @@ reg[34] := regexp("333\rhhh " ,"*\r(*) " ,0) reg[35] := regexp("333\"hhh " ,"*\"(???)(?)*" ,0) reg[36] := regexp("333\"hhh " ,"*3?(?*??)[ ,1]" ,0) reg[37] := regexp("333\"hhh " ,"*3?(???)[1, ,2]" ,0) //In variable assignment// //In operation `regexp\(\)'// //In character string pattern// //Charstring pattern: Duplicate character `.' in the character set// -reg[38] := regexp("333\"hhh " ,"*33?(???)[^a,1]" ,0) -reg[39] := regexp("333\"hhh " ,"333\"(???)*" ,0) +reg[38] := regexp @nocase ("333\"hhh " ,"*33?(???)[^a,1]" ,0) +reg[39] := regexp @nocase ("333\"hhh " ,"333\"(???)*" ,0) for (var integer j:=0; j<=39; j:=j+1) { diff --git a/regression_test/recordOper/TrecordOper.ttcn b/regression_test/recordOper/TrecordOper.ttcn index 8e35633ce727b893ec142526d2cb1afe7d01cd12..5ece0f9550442ced906ffbfe78727646de2990f7 100644 --- a/regression_test/recordOper/TrecordOper.ttcn +++ b/regression_test/recordOper/TrecordOper.ttcn @@ -1532,32 +1532,6 @@ testcase tc_record_partiallyInit13() runs on recordOper_mycomp { if(ispresent(vl_r.roi[0])){setverdict(fail)}else {setverdict(pass)}; if(ispresent(vl_r.roi[90])){setverdict(fail)}else {setverdict(pass)}; } - -// Must be able to make a difference between an unbound record and a bound record with unbound elements (TR: HT25776) -type record TheRec { - integer num, - charstring str -} with { - encode "JSON" -} - -external function f_dec(in octetstring x) return TheRec - with { extension "prototype(convert) decode(JSON) errorbehavior(ALL:WARNING)" } - -testcase tc_record_unbound_diff() runs on recordOper_mycomp -{ - // Unbound record - var TheRec v1; - log(v1); - if (not isbound(v1)) { setverdict(pass); } - else { setverdict(fail, "expected unbound record, got: ", v1); } - - // Create a bound, but empty record with the JSON decoder (decoding errors will only display warnings) - v1 := f_dec(char2oct("{}")); - log(v1); - if (isbound(v1)) { setverdict(pass); } - else { setverdict(fail, "record is unbound, expected bound record with unbound fields"); } -} control { const recordOper_trecord cl_temp1:={ x1:=omit, x2:=3.4 }; // can constants be declared in the control part @@ -1629,6 +1603,5 @@ control { execute(tc_record_omit2()); execute(tc_record_omit_HQ51693()); execute(tc_recordOf_omit()); - execute(tc_record_unbound_diff()); } } diff --git a/regression_test/templateCharstr/TtemplateCharstr.ttcn b/regression_test/templateCharstr/TtemplateCharstr.ttcn index b91d83867353d00501d25914342da2d01a446303..e4be883e06d12662b6f2f36b2b9b638e210f2638 100644 --- a/regression_test/templateCharstr/TtemplateCharstr.ttcn +++ b/regression_test/templateCharstr/TtemplateCharstr.ttcn @@ -87,6 +87,10 @@ template templateCharstr_rec templateCharstr_tRepeatFull := { x1:= pattern "6#(3,)", // at least 3 x2:= pattern "6#(,3)", // at most 3 x3:= pattern "6#(3,3)" }; // precisely 3 +template templateCharstr_rec templateCharstr_tPattern := { + x1 := pattern "abc?xyz", + x2 := pattern @nocase "abc?xyz", + x3 := pattern @nocase "abc*xyz" }; testcase templateCharstrSpec() runs on templateCharstr_mycomp { var templateCharstr_rec x1,x2; //specific value @@ -468,6 +472,29 @@ if (not(match(x4,templateCharstr_tRepeatFull))) {setverdict(pass);} else {setverdict(fail);} } +testcase templateCharstrPattern() runs on templateCharstr_mycomp { + var templateCharstr_rec x0, x1, x2, x3, x4; // pattern + x0 := { x1 := "abc,xyz", x2 := "abc1xyz", x3 := "abcxyz" }; + x1 := { x1 := "abcpxyz", x2 := "abcPxyz", x3 := "abc123abcJKL.? \txyz" }; + x2 := { x1 := "abcxyz", x2 := "abcPxyz", x3 := "abc123xyz" }; // fail first + x3 := { x1 := "abcpxyz", x2 := "abc123xyz", x3 := "abc123xyz" }; // fail second + x4 := { x1 := "abcpxyz", x2 := "abcPxyz", x3 := "abc123xy z" }; // fail third + + // match + if (match(x0, templateCharstr_tPattern)) { setverdict(pass); } + else { setverdict(fail); } + if (match(x1, templateCharstr_tPattern)) { setverdict(pass); } + else { setverdict(fail); } + + // not match + if (not match(x2, templateCharstr_tPattern)) { setverdict(pass); } + else { setverdict(fail); } + if (not match(x3, templateCharstr_tPattern)) { setverdict(pass); } + else { setverdict(fail); } + if (not match(x4, templateCharstr_tPattern)) { setverdict(pass); } + else { setverdict(fail); } +} + testcase TR920() runs on templateCharstr_mycomp { var template charstring temp := pattern "[0-9]|[0-9][0-9]"; const charstring x := "10a"; @@ -694,6 +721,7 @@ control { execute(templateCharstrEmptyPattern()); execute(templateCharstrRepeat()); execute(templateCharstrRepeatFull()); + execute(templateCharstrPattern()); execute(TR920()); execute(templateCharstrPatternCat()); execute(CatBasic()) diff --git a/regression_test/templateOmit/LegacyTests/LegacyTestcases.ttcn b/regression_test/templateOmit/LegacyTests/LegacyTestcases.ttcn index 86657172678cfb34da40472a1b77d5622e09482a..e028108d96cc2b1a5951f5d7053c6f2e7e394143 100644 --- a/regression_test/templateOmit/LegacyTests/LegacyTestcases.ttcn +++ b/regression_test/templateOmit/LegacyTests/LegacyTestcases.ttcn @@ -106,6 +106,14 @@ testcase tc_ispresent_legacy() runs on CT if (ispresent(t_enum_comp_list)) { setverdict(fail, t_enum_comp_list, " should not be present"); } + + var template Everything vt_present := { 1, "a", { 1.0, '10AB'O }, { '110'B, '101'B }, { b := true }, Second }; + if (not ispresent(vt_present)) { + setverdict(fail, vt_present, " should be present"); + } + if (not ispresent(valueof(vt_present))) { + setverdict(fail, "value of ", vt_present, " should be present"); + } setverdict(pass); } diff --git a/regression_test/templateRecof/TtemplateRecof.ttcn b/regression_test/templateRecof/TtemplateRecof.ttcn index ef9d65b1bb7f17c8630bc37c06a981b1635a53ac..2ef04d3009b8ad4d75bf488f13499d33d25b0e9e 100644 --- a/regression_test/templateRecof/TtemplateRecof.ttcn +++ b/regression_test/templateRecof/TtemplateRecof.ttcn @@ -624,6 +624,17 @@ testcase tc_isbound4ROI4() runs on mycomp { f(t_il4,5); } +template integer tpard(template integer i) := i; + +testcase tc_HU56425() runs on mycomp { + template integer t_i := tpard(3); + template templateRecof_myrecof t_list := { tpard(t_i) }; + // HU56425 refers to a code generation error (which caused a C++ compilation error), but let's check the resulting template anyway + template templateRecof_myrecof t_list_exp := { 3 }; + if (log2str(t_list) == log2str(t_list_exp)) { setverdict(pass); } + else { setverdict(fail); } +} + control { execute(templateRecofSpec()); diff --git a/regression_test/unionOper/TunionOper.ttcn b/regression_test/unionOper/TunionOper.ttcn index ac552deb83f513d161f94e403803c1766784a87b..eb52058c3e33fb5ee111bfc171100f29f6eee634 100644 --- a/regression_test/unionOper/TunionOper.ttcn +++ b/regression_test/unionOper/TunionOper.ttcn @@ -1003,6 +1003,98 @@ testcase tc_sideeffect2() runs on unionOper_mycomp { if(vl_newsize == vl_oldsize) {setverdict(pass)}else {setverdict(fail)} //log(vl_u.i); } + +type set InnerSet { + integer num, + charstring str +} + +type record InnerRec { + integer num, + charstring str +} + +type union InnerUni { + InnerSet s, + InnerRec r +} + +type record Outer { + InnerUni uni1, + InnerUni uni2, + record of InnerUni unis +} + +modulepar Outer mp; + +// Test case for artf703093 : A union with an unbound alternative should itself be unbound +// All unions in the module parameter and the variable declared in the test case should +// be unbound (instead of being bound with an unbound alternative). +// Copying the record containing the unions should be possible, too, without errors. +testcase tc_union_with_unbound_alternative() runs on unionOper_mycomp { + if (isbound(mp.uni1)) { + setverdict(fail, "mp.uni1 is bound: ", mp.uni1); + } + if (isbound(mp.uni2)) { + setverdict(fail, "mp.uni2 is bound: ", mp.uni2); + } + if (isbound(mp.unis[0])) { + setverdict(fail, "mp.unis[0] is bound: ", mp.unis[0]); + } + if (isbound(mp.unis[1])) { + setverdict(fail, "mp.unis[1] is bound: ", mp.unis[1]); + } + + var Outer x := { + uni1 := { r := { num := -, str := - } }, + uni2 := { s := { num := -, str := - } }, + unis := { + { r := { num := -, str := - } }, + { s := { num := -, str := - } } + } + }; + if (isbound(x.uni1)) { + setverdict(fail, "x.uni1 is bound: ", x.uni1); + } + if (isbound(x.uni2)) { + setverdict(fail, "x.uni2 is bound: ", x.uni2); + } + if (isbound(x.unis[0])) { + setverdict(fail, "x.unis[0] is bound: ", x.unis[0]); + } + if (isbound(x.unis[1])) { + setverdict(fail, "x.unis[1] is bound: ", x.unis[1]); + } + + var Outer copy := x; + if (isbound(copy.uni1)) { + setverdict(fail, "copied x.uni1 is bound: ", copy.uni1); + } + if (isbound(copy.uni2)) { + setverdict(fail, "copied x.uni2 is bound: ", copy.uni2); + } + if (isbound(copy.unis[0])) { + setverdict(fail, "copied x.unis[0] is bound: ", copy.unis[0]); + } + if (isbound(copy.unis[1])) { + setverdict(fail, "copied x.unis[1] is bound: ", copy.unis[1]); + } + + copy := mp; + if (isbound(copy.uni1)) { + setverdict(fail, "copied mp.uni1 is bound: ", copy.uni1); + } + if (isbound(copy.uni2)) { + setverdict(fail, "copied mp.uni2 is bound: ", copy.uni2); + } + if (isbound(copy.unis[0])) { + setverdict(fail, "copied mp.unis[0] is bound: ", copy.unis[0]); + } + if (isbound(copy.unis[1])) { + setverdict(fail, "copied mp.unis[1] is bound: ", copy.unis[1]); + } + setverdict(pass); +} control { const typedefunionComp_myunion cl_1:= { x1:={ x1:=1, x2:=1.2 }}; // constant in control part @@ -1062,5 +1154,6 @@ control { execute(tc_union_modify_ispresent()); execute(tc_sideeffect1_ispresent()); execute(tc_sideeffect2_ispresent()); + execute(tc_union_with_unbound_alternative()); } } diff --git a/regression_test/unionOper/config.cfg b/regression_test/unionOper/config.cfg index 8642eee12b89a8a32ff4e172b88dc49ccdcb1150..2a491e116d1fb2db5b50a07b44512ac3190265d2 100644 --- a/regression_test/unionOper/config.cfg +++ b/regression_test/unionOper/config.cfg @@ -6,6 +6,15 @@ # http://www.eclipse.org/legal/epl-v10.html ############################################################################### [MODULE_PARAMETERS] +mp := { + uni1 := { r := { } }, + uni2 := { s := { } }, + unis := { + { r := { } }, + { s := { } } + } +}; + [LOGGING] Logfile := "unionOper.log" FileMask := LOG_ALL diff --git a/usrguide/referenceguide.doc b/usrguide/referenceguide.doc index d780c326a9c56919c5c3d74f2a10445c235dc95e..42b3db6cb419c868904b2dc8b99dd1b64d91128c 100644 Binary files a/usrguide/referenceguide.doc and b/usrguide/referenceguide.doc differ diff --git a/usrguide/userguide.doc b/usrguide/userguide.doc index c329ef15705fe47031787ead346734086eda850c..8d16e8b72c5a81902de5f2c9d75fddf2d28832c4 100644 Binary files a/usrguide/userguide.doc and b/usrguide/userguide.doc differ diff --git a/xsdconvert/GeneralFunctions.cc b/xsdconvert/GeneralFunctions.cc index f4817a658eaf927aac2b757004bf2991426beabc..c1dd36f992adb93cc37c852b67f7fcbd6277e799 100644 --- a/xsdconvert/GeneralFunctions.cc +++ b/xsdconvert/GeneralFunctions.cc @@ -8,6 +8,7 @@ #include "GeneralFunctions.hh" #include "SimpleType.hh" #include "TTCN3Module.hh" +#include "ImportStatement.hh" #include <cctype> // for using "toupper" function #include <cstring> @@ -15,7 +16,18 @@ #include <cmath> #include <regex.h> +#include "../common/version_internal.h" + +#include <ctime> + +#if defined(WIN32) && !defined(MINGW) +#include <cygwin/version.h> +#include <sys/cygwin.h> +#include <limits.h> +#endif + extern bool w_flag_used; +extern bool t_flag_used; // XSDName2TTCN3Name function: // Parameters: @@ -656,7 +668,7 @@ RootType * lookup(const List<TTCN3Module*> mods, RootType *lookup1(const TTCN3Module *module, const Mstring& name, const Mstring& nsuri, const RootType *reference, wanted w) { if (nsuri != module->getTargetNamespace()) return NULL; - + for (List<RootType*>::iterator type = module->getDefinedTypes().begin(); type; type = type->Next) { switch (type->Data->getConstruct()) { case c_simpleType: @@ -685,7 +697,16 @@ RootType *lookup1(const TTCN3Module *module, break; } } - + + //Check for an include with NoTargetNamespace to look for the type + //XSD to TTCN ETSI standard 5.1.2 + for(List<RootType*>::iterator it = module->getDefinedTypes().begin(); it; it = it->Next) { + if (it->Data != NULL && it->Data->getConstruct() == c_include && + ((ImportStatement*)(it->Data))->getSourceModule() != NULL && + ((ImportStatement*)(it->Data))->getSourceModule()->getTargetNamespace() == Mstring("NoTargetNamespace")) { + return lookup1(((ImportStatement*)(it->Data))->getSourceModule(), name, Mstring("NoTargetNamespace"), reference, w); + } + } return NULL; } @@ -707,3 +728,56 @@ int multi(const TTCN3Module *module, ReferenceData const& outside_reference, } return multiplicity; } + +void generate_TTCN3_header(FILE * file, const char * modulename, const bool timestamp /* = true */) { + time_t time_current = time(NULL); + fprintf(file, + "/*******************************************************************************\n" + ); + if (t_flag_used) { + fprintf(file, + "* Copyright Ericsson Telecom AB\n" + "*\n" + "* XSD to TTCN-3 Translator\n" + "*\n" + ); + } else { + fprintf(file, + "* Copyright (c) 2000-%-4d Ericsson Telecom AB\n" + "*\n" + "* XSD to TTCN-3 Translator version: %-40s\n" + "*\n", + 1900 + (localtime(&time_current))->tm_year, + PRODUCT_NUMBER + ); + } + fprintf(file, + "* All rights reserved. This program and the accompanying materials\n" + "* are made available under the terms of the Eclipse Public License v1.0\n" + "* which accompanies this distribution, and is available at\n" + "* http://www.eclipse.org/legal/epl-v10.html\n" + "*******************************************************************************/\n" + "//\n" + "// File: %s.ttcn\n" + "// Description:\n" + "// References:\n" + "// Rev:\n" + "// Prodnr:\n", + modulename + ); + if (t_flag_used || !timestamp) { + fprintf(file, + "// Updated:\n" + ); + } else { + fprintf(file, + "// Updated: %s", + ctime(&time_current) + ); + } + fprintf(file, + "// Contact: http://ttcn.ericsson.se\n" + "//\n" + "////////////////////////////////////////////////////////////////////////////////\n" + ); +} \ No newline at end of file diff --git a/xsdconvert/GeneralFunctions.hh b/xsdconvert/GeneralFunctions.hh index ac98df6556d232cbf36d2f64e39a1417fa5e8477..e8914598778cd9d92885deed5fa2ace48b836fbe 100644 --- a/xsdconvert/GeneralFunctions.hh +++ b/xsdconvert/GeneralFunctions.hh @@ -67,6 +67,8 @@ RootType *lookup1(const TTCN3Module *module, int multi(const TTCN3Module *module, ReferenceData const& outside_reference, const RootType *obj); +void generate_TTCN3_header(FILE * file, const char* modulename, const bool timestamp = true); + inline unsigned long long llmin(unsigned long long l, unsigned long long r) { return l < r ? l : r; } diff --git a/xsdconvert/ImportStatement.hh b/xsdconvert/ImportStatement.hh index 829631892263c36544b455aac78ef36ffd227730..03990a573fa0a6c43d6bc42719e289139c0433ec 100644 --- a/xsdconvert/ImportStatement.hh +++ b/xsdconvert/ImportStatement.hh @@ -48,6 +48,8 @@ public: void validityChecking() { } void printToFile(FILE * file); + + const TTCN3Module* getSourceModule() { return source_module; } void dump(unsigned int depth) const; }; diff --git a/xsdconvert/TTCN3Module.cc b/xsdconvert/TTCN3Module.cc index 896e36f5153b42801424a84bb2a4097fa69ac62c..8f84e10cba1367f960295a61d531a649ba3b7bec 100644 --- a/xsdconvert/TTCN3Module.cc +++ b/xsdconvert/TTCN3Module.cc @@ -15,8 +15,6 @@ #include "../common/version_internal.h" -#include <ctime> - #if defined(WIN32) && !defined(MINGW) #include <cygwin/version.h> #include <sys/cygwin.h> @@ -24,7 +22,6 @@ #endif extern bool e_flag_used; -extern bool t_flag_used; extern bool z_flag_used; TTCN3Module::TTCN3Module(const char * a_filename, XMLParser * a_parser) @@ -206,59 +203,6 @@ void TTCN3Module::replaceLastMainType(RootType * t) { actualXsdConstruct = t->getConstruct(); } -void TTCN3Module::generate_TTCN3_header(FILE * file) { - time_t time_current = time(NULL); - fprintf(file, - "/*******************************************************************************\n" - ); - if (t_flag_used) { - fprintf(file, - "* Copyright Ericsson Telecom AB\n" - "*\n" - "* XSD to TTCN-3 Translator\n" - "*\n" - ); - } else { - fprintf(file, - "* Copyright (c) 2000-%-4d Ericsson Telecom AB\n" - "*\n" - "* XSD to TTCN-3 Translator version: %-40s\n" - "*\n", - 1900 + (localtime(&time_current))->tm_year, - PRODUCT_NUMBER - ); - } - fprintf(file, - "* All rights reserved. This program and the accompanying materials\n" - "* are made available under the terms of the Eclipse Public License v1.0\n" - "* which accompanies this distribution, and is available at\n" - "* http://www.eclipse.org/legal/epl-v10.html\n" - "*******************************************************************************/\n" - "//\n" - "// File: %s.ttcn\n" - "// Description:\n" - "// References:\n" - "// Rev:\n" - "// Prodnr:\n", - modulename.c_str() - ); - if (t_flag_used) { - fprintf(file, - "// Updated:\n" - ); - } else { - fprintf(file, - "// Updated: %s", - ctime(&time_current) - ); - } - fprintf(file, - "// Contact: http://ttcn.ericsson.se\n" - "//\n" - "////////////////////////////////////////////////////////////////////////////////\n" - ); -} - void TTCN3Module::generate_TTCN3_fileinfo(FILE * file) { fprintf(file, "//\t- %s\n" diff --git a/xsdconvert/TTCN3Module.hh b/xsdconvert/TTCN3Module.hh index 96887c99e5a4398bb79dd77b52a574e446055131..3b33d2c61e725ab8a71ac07a282c14788d1a4f2c 100644 --- a/xsdconvert/TTCN3Module.hh +++ b/xsdconvert/TTCN3Module.hh @@ -101,7 +101,6 @@ public: FormValue a_attributeFormDefault, BlockValue a_blockDefault); - void generate_TTCN3_header(FILE * file); void generate_TTCN3_fileinfo(FILE * file); void generate_TTCN3_modulestart(FILE * file); void generate_TTCN3_included_types(FILE * file); diff --git a/xsdconvert/TTCN3ModuleInventory.cc b/xsdconvert/TTCN3ModuleInventory.cc index 53b031d98a672435efaa33555b6abc896ab03837..7948496083a0bc199a29b191865b2008a201070d 100644 --- a/xsdconvert/TTCN3ModuleInventory.cc +++ b/xsdconvert/TTCN3ModuleInventory.cc @@ -231,7 +231,7 @@ void TTCN3ModuleInventory::moduleGeneration() { setvbuf(file, NULL, _IONBF, 0); #endif - module->Data->generate_TTCN3_header(file); + generate_TTCN3_header(file, module->Data->getModulename().c_str()); fprintf(file, "//\tGenerated from file(s):\n"); diff --git a/xsdconvert/converter.cc b/xsdconvert/converter.cc index f41827d00b49e548e1030b59423d00996fc99008..f2dbc288b55d646c5d67b8a1a83c8afae7ad3786 100644 --- a/xsdconvert/converter.cc +++ b/xsdconvert/converter.cc @@ -269,21 +269,23 @@ static bool checkFailure() { } static bool generatePredefinedModules() { - struct stat stFileInfo; - // Only generate the missing predefined modules. - if (stat("UsefulTtcn3Types.ttcn", &stFileInfo) != 0) { + //struct stat stFileInfo; + // Only generate the missing predefined modules. + // Generate, because the copyright is now generated into the modules. + //if (stat("UsefulTtcn3Types.ttcn", &stFileInfo) != 0) { extern const char *moduleUsefulTtcn3Types; FILE *fileUsefulTtcn3Types = fopen("UsefulTtcn3Types.ttcn", "w"); if (fileUsefulTtcn3Types == NULL) { fprintf(stderr, "ERROR:\nCannot create file UsefulTtcn3Types.ttcn!\n"); return false; } + generate_TTCN3_header(fileUsefulTtcn3Types, "UsefulTtcn3Types", false); fprintf(fileUsefulTtcn3Types, "%s", moduleUsefulTtcn3Types); if (!q_flag_used) { fprintf(stderr, "Notify: File \'UsefulTtcn3Types.ttcn\' was generated.\n"); } fclose(fileUsefulTtcn3Types); - } + //} //XSD.ttcn changed //if (stat("XSD.ttcn", &stFileInfo) != 0) { @@ -293,6 +295,7 @@ static bool generatePredefinedModules() { fprintf(stderr, "ERROR:\nCannot create file XSD.ttcn!\n"); return false; } + generate_TTCN3_header(fileXsd, "XSD", false); fprintf(fileXsd, "%s", moduleXSD); if (!q_flag_used) { fprintf(stderr, "Notify: File \'XSD.ttcn\' was generated.\n");