diff --git a/Makefile b/Makefile index 357f933afbebc7b0a84c253050bd1bd22770e806..bc81ca306bac3bd4ddcea476b229e65b484bbcaf 100644 --- a/Makefile +++ b/Makefile @@ -37,7 +37,7 @@ include $(TOP)/Makefile.cfg ALLDIRS := common compiler2 repgen xsdconvert ifndef MINGW - ALLDIRS += core core2 mctr2 loggerplugins + ALLDIRS += mctr2 core core2 loggerplugins endif # JNI not supported on Cygwin or Mingw diff --git a/README.cygwin b/README.cygwin index d41316f904a749e8917cd37bc7fad07cebc5a18b..74e5dcc680b2f65d5b7849cbe8cb7e4496c832b6 100644 --- a/README.cygwin +++ b/README.cygwin @@ -15,19 +15,19 @@ Cygwin setup Start the Cygwin setup utility (see below), it will refresh your installed Cygwin packages to the newest versions. - If Cygwin is not installed yet: - + (A) Download and execute the latest cygwin installer utility, please use the 64-bit version installer: https://cygwin.com/setup-x86_64.exe - + (B) Select Install from Internet (recommended to save local disk space) (C) Choose Cygwin installation root directory (C:\cygwin is recommended) Select All Users, or Just Me. - + (D) Select "Local Package Directory" (typically the same directory, where the setup....exe Cygwin installer utility is stored). - + (E) Use Internet Explorer Proxy Settings (recommended). (F) Select a download mirror site. @@ -41,35 +41,35 @@ Cygwin setup Note: Cygwin installer will automatically select the packages the manually selected ones are depending on; do NOT deselect any automatically selected package! - a) Test execution ONLY (command line or from Eclipse Executor): - Base: <all packages> (Default setting of the installer) - Net: openssl - Tcl: expect - b) Test case development: in addition to the above select the - following packages: - Devel: binutils - Devel: gcc-g++ - Devel: make - Libs: libxml2-devel - Net: openssl-devel (automatically installs Net:openssl - as well, if selected) + a) Test execution ONLY (command line or from Eclipse Executor): + Base: <all packages> (Default setting of the installer) + Net: openssl + Tcl: expect + b) Test case development: in addition to the above select the + following packages: + Devel: binutils + Devel: gcc-g++ + Devel: make + Libs: libxml2-devel + Net: openssl-devel (automatically installs Net:openssl + as well, if selected) c) To compile your own Titan Cygwin binary: in addition to the above, select the following packages: - Devel: bison - Devel: ctags - Devel: cygwin32-expat - Devel: diffstat - Devel: flex - Devel: gcc-core - Editors: <any editor of your preference> (optional) - Libs: libncurses-devel - Libs: libreadline-devel - - If, after selecting the required packages and clicking on the - "Next" button, a "Resolving Dependcies" window lists further - required packages, ensure that the "Select required packages - (RECOMMENDED)" checkbox is checked and click the "Next" button. - + Devel: bison + Devel: ctags + Devel: cygwin32-expat + Devel: diffstat + Devel: flex + Devel: gcc-core + Editors: <any editor of your preference> (optional) + Libs: libncurses-devel + Libs: libreadline-devel + + If, after selecting the required packages and clicking on the + "Next" button, a "Resolving Dependcies" window lists further + required packages, ensure that the "Select required packages + (RECOMMENDED)" checkbox is checked and click the "Next" button. + (H) Select the Create icon on Desktop checkbox (I) (Optional) @@ -93,34 +93,39 @@ Cygwin setup WARNING: The path of your "unix" home directory shall not contain any space! - (J) Using the bynary Titan package: download the Titan package for from + (I1)If you are working with Titan plugins for Eclipse or any Windows based program + using cygwin commands, insert the Windows equivalent path of cygwin folders "/bin" or/and "/usr/bin" + into the Windows environment variable "Path". For example if the cygwin root is "C:\cygwin64" then + Path should contain "C:\cygwin64\bin;C:\cygwin64\usr\bin". + + (J) Using the binary Titan package: download the Titan package for from GitHub. Unpack the Titan package into a folder of your choice. Note: It is not a requirement, but is a kind of best practice to place Titan into a subfolder within your "unix" home directory. Edit the <your cygwin installation directory>/home/<yourUserId>/.bashrc - file. Add these lines to it: - export PATH=${TTCN3_DIR}/bin:${PATH} - export LD_LIBRARY_PATH=${TTCN3_DIR}/lib:${LD_LIBRARY_PATH} + file. Add these lines to it: + export PATH=${TTCN3_DIR}/bin:${PATH} + export LD_LIBRARY_PATH=${TTCN3_DIR}/lib:${LD_LIBRARY_PATH} (K) Compile Titan with Cygwin: - Get the latest source code from GitHub. - Download and install JDK from Oracle's download site: - http://www.oracle.com/technetwork/java/javase/downloads/index.html - Edit the <your cygwin installation directory>/home/<yourUserId>/.bashrc - as above. - Create titan/Makefile.personal with the following content: - TTCN3_DIR := /home/<user id>/git/titan/Install + Get the latest source code from GitHub. + Download and install JDK from Oracle's download site: + http://www.oracle.com/technetwork/java/javase/downloads/index.html + Edit the <your cygwin installation directory>/home/<yourUserId>/.bashrc + as above. + Create titan/Makefile.personal with the following content: + TTCN3_DIR := /home/<user id>/git/titan/Install JDKDIR := /home/<user id>/jdk JNI := no GUI := no GEN_PDF := no DEBUG := no - Compile Titan: - cd titan - make -j - make install - The compiled files will be placed into the titan/Install directory. - + Compile Titan: + cd titan + make -j + make install + The compiled files will be placed into the titan/Install directory. + (L) If you want to use graphical tools (like nedit for example), then you need to install the Cygwin/X component too. The install procedure can be found at the homepage: http://x.cygwin.com/docs/ug/cygwin-x-ug.html diff --git a/README.linux b/README.linux index 11c5d2958f1314e18d123c891924cd748018fe7b..e851c5d98bfd779753ee1ec36303933980318d83 100644 --- a/README.linux +++ b/README.linux @@ -30,20 +30,23 @@ git clone https://github.com/eclipse/titan.core titan.core 3. Configure the build cd titan.core -check that MakefileFOSS.cfg is present and has the following content: + +For open source users: check that MakefileFOSS.cfg is present and has the following content: cat MakefileFOSS.cfg # Configurations for the Free Open Source Software version LICENSING := no USAGE_STATS := no +If you want to use your build within teh Ericsson domain: delete MakefileFOSS.cfg +This will enable licensing. Several build options are possible; for details on options please read through the Makefile.cfg. Options can be overridden by the content of a file named Makefile.personal which can be used to adapt to local installation directories, change config options etc. Below, a small number of typical scenarios are presented. -a) JNI disabled +a) JNI disabled, gcc compiler (default) The JNI interface is used by the Eclipse Titan Executor or by the Java Executor API. If you don't need them , Titan can be compiled without JNI. @@ -58,15 +61,27 @@ XMLDIR := /usr JNI := no GEN_PDF := no +b) JNI disabled, clang compiler ver. 3.8 + +Create ~/titan.core/Makefile.personal to override settings in Makefile.cfg with the following content: +(replace paths with values relevant to your installation). +TTCN3_DIR := /home/<user id>/titan.core/Install +OPENSSL_DIR := /usr +#JDKDIR := /usr/lib/jvm/java-7-openjdk-amd64 +XMLDIR := /usr +JNI := no +GEN_PDF := no +CXX := clang++-3.8 +CC := clang-3.8 -b) JNI enabled +c) JNI enabled, gcc compiler (default) install JDK into /home/<user id>/jdk Create ~/titan.core/Makefile.personal to override settings in Makefile.cfg with the following content: -(replace paths with values relevant to your installation) +(replace paths with values relevant to your installation). TTCN3_DIR := /home/<user id>/titan.core/Install OPENSSL_DIR := /usr @@ -133,6 +148,3 @@ These tests might run for half an hour (regr.tests) to two hours (func.tests) 8. Optionally, copy Titan into its final directory. From here on, you can continue with the Titan installation guide, see /Install/docs, to set/change environment variables etc. -nagylenard -elnrnag -elnrnag2 diff --git a/README.md b/README.md index a406babf4553ace8ac0e2bd27858ea2e0e2c9e84..558c5d661797adb78b698e1c5ff46d51cf9fbf3a 100644 --- a/README.md +++ b/README.md @@ -30,26 +30,7 @@ https://www.eclipse.org/downloads/download.php?file=/titan/TITAN_User_P.pdf ##Binaries and SHA512 checksums for a number of Linux platforms can be downloaded from: -* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.4.pl0-linux32-gcc4.3-sled11.1.tgz -* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.4.pl0-linux32-gcc4.3-sled11.1.tgz.sha512 -* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.4.pl0-linux64-gcc4.8.3-sled12.0.tgz -* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.4.pl0-linux64-gcc4.8.3-sled12.0.tgz.sha512 -* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.4.pl0-linux64-gcc4.1.2-rhel5.tgz -* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.4.pl0-linux64-gcc4.1.2-rhel5.tgz.sha512 -* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.4.pl0-linux64-gcc4.3-SLED11.1.tgz -* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.4.pl0-linux64-gcc4.3-SLED11.1.tgz.sha512 -* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.4.pl0-linux64-gcc4.3-sled11.0.tgz -* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.4.pl0-linux64-gcc4.3-sled11.0.tgz.sha512 -* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.4.pl0-linux64-gcc4.3-sles11.1.tgz -* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.4.pl0-linux64-gcc4.3-sles11.1.tgz.sha512 -* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.4.pl0-linux64-gcc4.4.5-rhel6.tgz -* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.4.pl0-linux64-gcc4.4.5-rhel6.tgz.sha512 -* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.4.pl0-linux64-gcc4.8.2-rhel7.tgz -* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.4.pl0-linux64-gcc4.8.2-rhel7.tgz.sha512 -* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.4.pl0-linux64-gcc4.6-ubuntu12.04.tgz -* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.4.pl0-linux64-gcc4.6-ubuntu12.04.tgz.sha512 -* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.4.pl0-linux64-gcc4.8-ubuntu14.04.tgz -* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.4.pl0-linux64-gcc4.8-ubuntu14.04.tgz.sha512 +* https://projects.eclipse.org/projects/tools.titan/downloads # Related products: @@ -62,8 +43,7 @@ Source code: Compressed update site and SHA512 checksum: -* https://www.eclipse.org/downloads/download.php?file=/titan/TITAN_on_Eclipse_5.4.0.CRL_113_200_5_R4A_20151113-1513.zip -* https://www.eclipse.org/downloads/download.php?file=/titan/TITAN_on_Eclipse_5.4.0.CRL_113_200_5_R4A_20151113-1513.zip.sha512 +* https://projects.eclipse.org/projects/tools.titan/downloads ## Test Ports: diff --git a/common/version_internal.h b/common/version_internal.h index 14316f23707b02b57f76fa8df8c0ab5bdd66fd39..9b9a0bd6ad8c313f7e363271ed17d734af0e4542 100644 --- a/common/version_internal.h +++ b/common/version_internal.h @@ -12,6 +12,7 @@ * Lovassy, Arpad * Raduly, Csaba * Szabados, Kristof + * Szabo, Bence Janos * Szabo, Janos Zoltan – initial implementation * ******************************************************************************/ @@ -123,17 +124,29 @@ /* Version of the C/C++ compiler */ #if defined(__GNUC__) - /* the code is compiled with GCC */ -# ifdef __GNUC_PATCHLEVEL__ - /* the patch number is known (version 3.0 or later) */ -# define GEN_COMP_VER2(major, minor, patchlevel) "GCC " #major "." #minor "." #patchlevel -# define GEN_COMP_VER(major, minor, patchlevel) GEN_COMP_VER2(major, minor, patchlevel) -# define C_COMPILER_VERSION GEN_COMP_VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) +# ifdef __clang__ +# ifdef __clang_patchlevel__ +# define GEN_COMP_VER2(major, minor, patchlevel) "clang " #major "." #minor "." #patchlevel +# define GEN_COMP_VER(major, minor, patchlevel) GEN_COMP_VER2(major, minor, patchlevel) +# define C_COMPILER_VERSION GEN_COMP_VER(__clang_major__, __clang_minor__, __clang_patchlevel__) +# else +# define GEN_COMP_VER2(major, minor) "clang " #major "." #minor ".?" +# define GEN_COMP_VER(major, minor) GEN_COMP_VER2(major, minor) +# define C_COMPILER_VERSION GEN_COMP_VER(__clang_major__, __clang_minor__) +# endif # else - /* the patch number is unknown (version 2.x.?) */ -# define GEN_COMP_VER2(major, minor) "GCC " #major "." #minor ".?" -# define GEN_COMP_VER(major, minor) GEN_COMP_VER2(major, minor) -# define C_COMPILER_VERSION GEN_COMP_VER(__GNUC__, __GNUC_MINOR__) + /* the code is compiled with GCC */ +# ifdef __GNUC_PATCHLEVEL__ + /* the patch number is known (version 3.0 or later) */ +# define GEN_COMP_VER2(major, minor, patchlevel) "GCC " #major "." #minor "." #patchlevel +# define GEN_COMP_VER(major, minor, patchlevel) GEN_COMP_VER2(major, minor, patchlevel) +# define C_COMPILER_VERSION GEN_COMP_VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) +# else + /* the patch number is unknown (version 2.x.?) */ +# define GEN_COMP_VER2(major, minor) "GCC " #major "." #minor ".?" +# define GEN_COMP_VER(major, minor) GEN_COMP_VER2(major, minor) +# define C_COMPILER_VERSION GEN_COMP_VER(__GNUC__, __GNUC_MINOR__) +# endif # endif #elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) /* the code is compiled with Sun Workshop C/C++ compiler */ diff --git a/compiler2/DebuggerStuff.cc b/compiler2/DebuggerStuff.cc index c34bd6ebc89b9196123ba9a10995231cd96498f9..f379c09730fc43b848ed30aa1e7b386f79778567 100644 --- a/compiler2/DebuggerStuff.cc +++ b/compiler2/DebuggerStuff.cc @@ -110,11 +110,12 @@ string array_dimensions_to_string(Ttcn::ArrayDimensions* p_dims) return ret_val; } -void calculate_type_name_and_print_function_from_type(Type* p_type, - Type* p_type_last, - Module* p_module, - string& p_type_name, - string& p_print_function) +void calculate_type_name_and_debug_functions_from_type(Type* p_type, + Type* p_type_last, + Module* p_module, + string& p_type_name, + string& p_print_function, + string& p_set_function) { if (p_type_last->get_typetype() == Type::T_COMPONENT) { p_type_name = "component"; @@ -142,13 +143,17 @@ void calculate_type_name_and_print_function_from_type(Type* p_type, p_type_name = p_type_last->get_dispname(); } const Module* var_type_mod = p_type_last->get_my_scope()->get_scope_mod(); + string module_prefix; if (var_type_mod != p_module) { - p_print_function = var_type_mod->get_modid().get_name() + "::"; + module_prefix = var_type_mod->get_modid().get_name() + "::"; } - else { - p_print_function.clear(); + p_print_function = module_prefix + "print_var_" + + var_type_mod->get_modid().get_ttcnname(); + if (p_type_last->get_typetype() != Type::T_SIGNATURE && + p_type_last->get_typetype() != Type::T_PORT) { + p_set_function = module_prefix + "set_var_" + + var_type_mod->get_modid().get_ttcnname(); } - p_print_function += "print_var_" + var_type_mod->get_modid().get_ttcnname(); } else { // built-in type, get the TTCN-3 version of the type if possible @@ -182,23 +187,34 @@ char* generate_code_debugger_add_var(char* str, Common::Assignment* var_ass, } bool is_lazy_param = false; + bool is_constant = false; switch (var_ass->get_asstype()) { case Common::Assignment::A_PAR_VAL: case Common::Assignment::A_PAR_VAL_IN: - case Common::Assignment::A_PAR_TEMPL_IN: + case Common::Assignment::A_PAR_TEMPL_IN: { if (var_ass->get_lazy_eval()) { // lazy parameters have their own printing function is_lazy_param = true; } - break; + Ttcn::FormalPar* fpar = dynamic_cast<Ttcn::FormalPar*>(var_ass); + is_constant = fpar == NULL || !fpar->get_used_as_lvalue(); + break; } + case Common::Assignment::A_CONST: + case Common::Assignment::A_EXT_CONST: + case Common::Assignment::A_MODULEPAR: + case Common::Assignment::A_MODULEPAR_TEMP: + case Common::Assignment::A_TEMPLATE: + is_constant = scope_name != NULL; default: break; } - // recreate the TTCN-3 version of the type name and determine the type's printing function - string type_name, print_function; + // recreate the TTCN-3 version of the type name and determine the type's + // printing and overwriting functions + string type_name, print_function, set_function; print_function = is_lazy_param ? "TTCN3_Debugger::print_lazy_param<" : "TTCN3_Debugger::print_base_var"; + set_function = "TTCN3_Debugger::set_base_var"; if (var_ass->get_asstype() == Common::Assignment::A_TIMER || var_ass->get_asstype() == Common::Assignment::A_PAR_TIMER) { type_name = "timer"; @@ -242,8 +258,9 @@ char* generate_code_debugger_add_var(char* str, Common::Assignment* var_ass, dims_str += t->get_dimension()->get_stringRepr(); t = t->get_ofType()->get_type_refd_last(); } - string dummy; - calculate_type_name_and_print_function_from_type(t, t, current_mod, type_name, dummy); + string dummy1, dummy2; + calculate_type_name_and_debug_functions_from_type(t, t, current_mod, + type_name, dummy1, dummy2); type_name += dims_str; if (!is_lazy_param) { switch (var_ass->get_asstype()) { @@ -257,20 +274,27 @@ char* generate_code_debugger_add_var(char* str, Common::Assignment* var_ass, print_function = string("TTCN3_Debugger::print_template_array<") + function_params_for_array_type(var_type, current_mod, true) + string(">"); + set_function = string("TTCN3_Debugger::set_template_array<") + + function_params_for_array_type(var_type, current_mod, true) + + string(">"); break; default: // value array print_function = string("TTCN3_Debugger::print_value_array<") + function_params_for_array_type(var_type, current_mod, false) + string(">"); + set_function = string("TTCN3_Debugger::set_value_array<") + + function_params_for_array_type(var_type, current_mod, false) + + string(">"); break; } } } else { string dummy; - calculate_type_name_and_print_function_from_type(var_ass->get_Type(), - var_type, current_mod, type_name, is_lazy_param ? dummy : print_function); + calculate_type_name_and_debug_functions_from_type(var_ass->get_Type(), + var_type, current_mod, type_name, is_lazy_param ? dummy : print_function, + set_function); } } @@ -295,7 +319,7 @@ char* generate_code_debugger_add_var(char* str, Common::Assignment* var_ass, print_function += ">"; } - return mputprintf(str, "%s%s_scope%sadd_variable(&%s, \"%s\", \"%s\", %s);\n", + return mputprintf(str, "%s%s_scope%sadd_variable(&%s, \"%s\", \"%s\", %s%s%s);\n", scope_name != NULL ? " " : "", // add indenting for global variables scope_name != NULL ? scope_name : "debug", // the prefix of the debugger scope: // ("global" for global variables, "debug" for local variables, @@ -307,7 +331,9 @@ char* generate_code_debugger_add_var(char* str, Common::Assignment* var_ass, // so the lazy parameter evaluation code is not generated) var_ass->get_id().get_ttcnname().c_str(), // variable name in TTCN-3 type_name.c_str(), // variable type in TTCN-3, with a suffix if it's a template - print_function.c_str()); // variable printing function + print_function.c_str(), // variable printing function + is_constant ? "" : ", ", is_constant ? "" : set_function.c_str()); + // variable overwriting function (not generated for constants) } char* generate_code_debugger_function_init(char* str, Common::Assignment* func_ass) diff --git a/compiler2/Value.cc b/compiler2/Value.cc index af36e4ef7d0c8fc179a41af45b293ec11d2583f4..e6cf738b27d5264e879c4869842a69aa9c9f5f7b 100644 --- a/compiler2/Value.cc +++ b/compiler2/Value.cc @@ -11521,11 +11521,9 @@ error: break; case OPTYPE_DECODE: { Ttcn::ActualParList *parlist = u.expr.r1->get_parlist(); - Common::Assignment *ass = u.expr.r1->get_refd_assignment(); if (parlist) str = parlist->rearrange_init_code(str, usage_mod); parlist = u.expr.r2->get_parlist(); - ass = u.expr.r2->get_refd_assignment(); if (parlist) str = parlist->rearrange_init_code(str, usage_mod); break; } case OPTYPE_HOSTID: diff --git a/compiler2/asn1/AST_asn1.cc b/compiler2/asn1/AST_asn1.cc index cd87a28f38d2866c34e67334e9ab120aee811a77..4503ef0dcc9a84f926b09cae669888c6f45df1bf 100644 --- a/compiler2/asn1/AST_asn1.cc +++ b/compiler2/asn1/AST_asn1.cc @@ -578,7 +578,8 @@ namespace Asn { void Module::generate_debugger_functions(output_struct *output) { - char* str = NULL; + char* print_str = NULL; + char* overwrite_str = NULL; for (size_t i = 0; i < asss->get_nof_asss(); ++i) { Asn::Assignment* asn_ass = dynamic_cast<Asn::Assignment*>(asss->get_ass_byIndex(i)); if (asn_ass->get_ass_pard() != NULL) { @@ -594,36 +595,58 @@ namespace Asn { // only structured types and enums are needed // for instances of parameterized types, the last reference, which is // not itself an instance of a parameterized type, holds the type's display name - str = mputprintf(str, + print_str = mputprintf(print_str, " %sif (!strcmp(p_var.type_name, \"%s\")) {\n" - " ((const %s*)p_var.value)->log();\n" + " ((const %s*)ptr)->log();\n" " }\n" " else if (!strcmp(p_var.type_name, \"%s template\")) {\n" - " ((const %s_template*)p_var.value)->log();\n" + " ((const %s_template*)ptr)->log();\n" " }\n" - , (str != NULL) ? "else " : "" + , (print_str != NULL) ? "else " : "" + , t->get_dispname().c_str(), t->get_genname_value(this).c_str() + , t->get_dispname().c_str(), t->get_genname_value(this).c_str()); + overwrite_str = mputprintf(overwrite_str, + " %sif (!strcmp(p_var.type_name, \"%s\")) {\n" + " ((%s*)p_var.value)->set_param(p_new_value);\n" + " }\n" + " else if (!strcmp(p_var.type_name, \"%s template\")) {\n" + " ((%s_template*)p_var.value)->set_param(p_new_value);\n" + " }\n" + , (overwrite_str != NULL) ? "else " : "" , t->get_dispname().c_str(), t->get_genname_value(this).c_str() , t->get_dispname().c_str(), t->get_genname_value(this).c_str()); } } } - if (str != NULL) { + if (print_str != NULL) { // don't generate an empty printing function output->header.class_defs = mputprintf(output->header.class_defs, - "/* Debugger printing function for types declared in this module */\n\n" - "extern CHARSTRING print_var_%s(const TTCN3_Debugger::variable_t& p_var);\n", - get_modid().get_ttcnname().c_str()); + "/* Debugger printing and overwriting functions for types declared in this module */\n\n" + "extern CHARSTRING print_var_%s(const TTCN3_Debugger::variable_t& p_var);\n" + "extern boolean set_var_%s(TTCN3_Debugger::variable_t& p_var, Module_Param& p_new_value);\n", + get_modid().get_ttcnname().c_str(), get_modid().get_ttcnname().c_str()); output->source.global_vars = mputprintf(output->source.global_vars, "\n/* Debugger printing function for types declared in this module */\n" "CHARSTRING print_var_%s(const TTCN3_Debugger::variable_t& p_var)\n" "{\n" + " const void* ptr = p_var.set_function != NULL ? p_var.value : p_var.cvalue;\n" " TTCN_Logger::begin_event_log2str();\n" "%s" " else {\n" " TTCN_Logger::log_event_str(\"<unrecognized value or template>\");\n" " }\n" " return TTCN_Logger::end_event_log2str();\n" - "}\n", get_modid().get_ttcnname().c_str(), str); + "}\n\n" + "/* Debugger overwriting function for types declared in this module */\n" + "boolean set_var_%s(TTCN3_Debugger::variable_t& p_var, Module_Param& p_new_value)\n" + "{\n" + "%s" + " else {\n" + " return FALSE;\n" + " }\n" + " return TRUE;\n" + "}\n", get_modid().get_ttcnname().c_str(), print_str, + get_modid().get_ttcnname().c_str(), overwrite_str); } } diff --git a/compiler2/compiler.1 b/compiler2/compiler.1 index d64cc88fbcbea83bc59f522c82734370aa489637..8c0e3467b9d1e86810be556aea974ddad06171a6 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 "[\| " \-abcdEfgijlLMpqrRsStuwxXyY " \|]" +.RB "[\| " \-abcdEfgijlLMnpqrRsStuwxXyY " \|]" .RB "[\| " \-V .IR " verb_level" " \|]" .RB "[\| " \-K @@ -167,6 +167,9 @@ operation and the .B present template restriction accordingly. .TP +.B \-n +Activates the debugger and generates extra code for storing debug information. +.TP .BI \-o " dir" The output files (including Test Port skeletons) will be placed into the directory specified by diff --git a/compiler2/main.cc b/compiler2/main.cc index 5e6cfd5bc3d2e8c2fa4eae7970a320f619a12edf..f01d98e2e466dc4dbce5c8bd91ab3db43c30645a 100644 --- a/compiler2/main.cc +++ b/compiler2/main.cc @@ -384,7 +384,7 @@ static boolean is_valid_asn1_filename(const char* file_name) static void usage() { fprintf(stderr, "\n" - "usage: %s [-abcdEfgijlLOpqrRsStuwxXyY] [-K file] [-z file] [-V verb_level]\n" + "usage: %s [-abcdEfgijlLMnOpqrRsStuwxXyY] [-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" @@ -405,6 +405,7 @@ static void usage() " -l: include source line info in C++ code\n" " -L: add source line info for logging\n" " -M: allow 'omit' in template value lists (legacy behavior)\n" + " -n: activate debugger (generates extra code for debugging)\n" " -o dir: output files will be placed into dir\n" " -p: parse only (no semantic check or code generation)\n" " -P pduname: define top-level pdu\n" @@ -791,7 +792,7 @@ int main(int argc, char *argv[]) break; } } - + /* Checking incompatible options */ if (vflag) { if (Aflag || Lflag || Pflag || Tflag || Vflag || Yflag || diff --git a/compiler2/makefile.c b/compiler2/makefile.c index d77f45226ff9027531ba951fb3ff764c16c046ff..0c5639d28e03710aa389e1b8b80485fd6d2e3111 100644 --- a/compiler2/makefile.c +++ b/compiler2/makefile.c @@ -262,6 +262,7 @@ struct makefile_struct { boolean outparamboundness; boolean omit_in_value_list; boolean warnings_for_bad_variants; + boolean activate_debugger; boolean disable_predef_ext_folder; struct string_list* solspeclibraries; /* not owned */ struct string_list* sol8speclibraries; /* not owned */ @@ -327,6 +328,7 @@ static void init_makefile_struct(struct makefile_struct *makefile) makefile->outparamboundness = FALSE; makefile->omit_in_value_list = FALSE; makefile->warnings_for_bad_variants = FALSE; + makefile->activate_debugger = FALSE; makefile->solspeclibraries = NULL; makefile->sol8speclibraries = NULL; makefile->linuxspeclibraries = NULL; @@ -2054,6 +2056,7 @@ static void print_makefile(struct makefile_struct *makefile) (makefile->outparamboundness ? " -Y" : ""), (makefile->omit_in_value_list ? " -M" : ""), (makefile->warnings_for_bad_variants ? " -E" : ""), + (makefile->activate_debugger ? " -n" : ""), (makefile->tcov_file_name ? makefile->tcov_file_name : ""), (makefile->profiled_file_list ? " -z $(PROFILED_FILE_LIST)" : ""), /* end of COMPILER FLAGS */ @@ -2939,7 +2942,7 @@ static void print_makefile(struct makefile_struct *makefile) "# Platform specific additional libraries:\n" "#\n", fp); - fputs("SOLARIS_LIBS = -lsocket -lnsl -lxml2", fp); + fputs("SOLARIS_LIBS = -lsocket -lnsl -lxml2 -lcurses", fp); #ifdef USAGE_STATS fputs(" -lresolv", fp); #endif @@ -2954,7 +2957,7 @@ static void print_makefile(struct makefile_struct *makefile) } fputs("\n", fp); - fputs("SOLARIS8_LIBS = -lsocket -lnsl -lxml2", fp); + fputs("SOLARIS8_LIBS = -lsocket -lnsl -lxml2 -lcurses", fp); #ifdef USAGE_STATS fputs(" -lresolv", fp); #endif @@ -2969,7 +2972,7 @@ static void print_makefile(struct makefile_struct *makefile) } fputs("\n", fp); - fputs("LINUX_LIBS = -lxml2", fp); + fputs("LINUX_LIBS = -lxml2 -lncurses", fp); #ifdef USAGE_STATS fputs(" -lpthread -lrt", fp); #endif @@ -2984,7 +2987,7 @@ static void print_makefile(struct makefile_struct *makefile) } fputs("\n", fp); - fputs("FREEBSD_LIBS = -lxml2", fp); + fputs("FREEBSD_LIBS = -lxml2 -lncurses", fp); if (makefile->freebsdspeclibraries) { struct string_list* act_elem = makefile->freebsdspeclibraries; while (act_elem) { @@ -2996,7 +2999,7 @@ static void print_makefile(struct makefile_struct *makefile) } fputs("\n", fp); - fputs("WIN32_LIBS = -lxml2", fp); + fputs("WIN32_LIBS = -lxml2 -lncurses", fp); if (makefile->win32speclibraries) { struct string_list* act_elem = makefile->win32speclibraries; while (act_elem) { @@ -3816,7 +3819,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, boolean warnings_for_bad_variants, boolean disable_predef_ext_folder, struct string_list* solspeclibraries, + boolean outparamboundness, boolean omit_in_value_list, boolean warnings_for_bad_variants, boolean activate_debugger, + 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, @@ -3868,6 +3872,7 @@ static void generate_makefile(size_t n_arguments, char *arguments[], makefile.outparamboundness = outparamboundness; makefile.omit_in_value_list = omit_in_value_list; makefile.warnings_for_bad_variants = warnings_for_bad_variants; + makefile.activate_debugger = activate_debugger; makefile.disable_predef_ext_folder = disable_predef_ext_folder; makefile.solspeclibraries = solspeclibraries; makefile.sol8speclibraries = sol8speclibraries; @@ -4003,7 +4008,7 @@ static void generate_makefile(size_t n_arguments, char *arguments[], static void usage(void) { fprintf(stderr, "\n" - "usage: %s [-abc" C_flag "dDEfFglLmMprRstTVwWXZ] [-K file] [-z file ] [-P dir]" + "usage: %s [-abc" C_flag "dDEfFglLmMnprRstTVwWXZ] [-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" @@ -4026,6 +4031,7 @@ static void usage(void) " -L: create makefile with library archive as the default target\n" " -m: always use makedepend for dependencies\n" " -M: allow 'omit' in template value lists (legacy behavior)\n" + " -n: activate debugger (generates extra code for debugging)\n" " -o dir|file: write the Makefile to the given directory or file\n" " -O file: add the given file to the Makefile as other file\n" " -p: generate Makefile with TTCN-3 preprocessing\n" @@ -4093,7 +4099,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, - diflag = FALSE, zflag = FALSE, Eflag = FALSE; + diflag = FALSE, zflag = FALSE, Eflag = FALSE, nflag = FALSE; boolean error_flag = FALSE; char *output_file = NULL; char *ets_name = NULL; @@ -4150,7 +4156,7 @@ int main(int argc, char *argv[]) } for ( ; ; ) { - int c = getopt(argc, argv, "O:ab:c" C_flag "dDe:EfFgI:K:o:lLmMpP:rRst:TU:vVwWXYz:ZH"); + int c = getopt(argc, argv, "O:ab:c" C_flag "dDe:EfFgI:K:o:lLmMnpP:rRst:TU:vVwWXYz:ZH"); if (c == -1) break; switch (c) { case 'O': @@ -4225,6 +4231,9 @@ int main(int argc, char *argv[]) case 'M': SET_FLAG(M); break; + case 'n': + SET_FLAG(n); + break; case 'p': SET_FLAG(p); break; @@ -4301,7 +4310,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 || Eflag || n_other_files > 0 || n_search_paths > 0) + || Zflag || Hflag || Mflag || zflag || Eflag || nflag || n_other_files > 0 || n_search_paths > 0) error_flag = TRUE; } @@ -4487,7 +4496,7 @@ 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, &Eflag, &diflag, solspeclibraries, sol8speclibraries, linuxspeclibraries, freebsdspeclibraries, win32speclibraries, &ttcn3prep, + &asflag, &swflag, &Yflag, &Mflag, &Eflag, &nflag, &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, search_paths, n_search_paths); @@ -4526,7 +4535,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, Eflag, diflag, solspeclibraries, + drflag, dtflag, dxflag, djflag, fxflag, doflag, gfflag, lnflag, isflag, asflag, swflag, Yflag, Mflag, Eflag, nflag, diflag, solspeclibraries, sol8speclibraries, linuxspeclibraries, freebsdspeclibraries, win32speclibraries, ttcn3prep, linkerlibraries, additionalObjects, linkerlibsearchpath, generatorCommandOutput, target_placement_list); } diff --git a/compiler2/record_of.c b/compiler2/record_of.c index 2308ba76e85b8e9f891493db837e52480d5af5f3..806014a8d851a5a2672266926f86adb70b1fc46b 100644 --- a/compiler2/record_of.c +++ b/compiler2/record_of.c @@ -636,6 +636,10 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output) " Module_Param* const curr = mp->get_elem(i);\n" " if (curr->get_type()!=Module_Param::MP_NotUsed) {\n" " (*this)[i].set_param(*curr);\n" + " if (!(*this)[i].is_bound()) {\n" + " delete val_ptr->value_elements[i];\n" + " val_ptr->value_elements[i] = NULL;\n" + " }\n" " }\n" " }\n" " break;\n" @@ -643,6 +647,10 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output) " for (size_t i=0; i<mp->get_size(); ++i) {\n" " Module_Param* const curr = mp->get_elem(i);\n" " (*this)[curr->get_id()->get_index()].set_param(*curr);\n" + " if (!(*this)[curr->get_id()->get_index()].is_bound()) {\n" + " delete val_ptr->value_elements[curr->get_id()->get_index()];\n" + " val_ptr->value_elements[curr->get_id()->get_index()] = NULL;\n" + " }\n" " }\n" " break;\n" " default:\n" diff --git a/compiler2/ttcn3/AST_ttcn3.cc b/compiler2/ttcn3/AST_ttcn3.cc index 85568e2b974cae248384114f4fa2a41d63ffb1a7..6859e36cc11c7b90c97f61bc1d2e7e2f15091a43 100644 --- a/compiler2/ttcn3/AST_ttcn3.cc +++ b/compiler2/ttcn3/AST_ttcn3.cc @@ -2912,7 +2912,8 @@ namespace Ttcn { void Module::generate_debugger_functions(output_struct *output) { - char* str = NULL; + char* print_str = NULL; + char* overwrite_str = NULL; for (size_t i = 0; i < asss->get_nof_asss(); ++i) { Def_Type* def = dynamic_cast<Def_Type*>(asss->get_ass_byIndex(i)); if (def != NULL) { @@ -2920,41 +2921,74 @@ namespace Ttcn { if (!t->is_ref() && t->get_typetype() != Type::T_COMPONENT) { // don't generate code for subtypes if (t->get_typetype() != Type::T_SIGNATURE) { - str = mputprintf(str, + print_str = mputprintf(print_str, " %sif (!strcmp(p_var.type_name, \"%s\")) {\n" - " ((const %s*)p_var.value)->log();\n" + " ((const %s*)ptr)->log();\n" " }\n" - , (str != NULL) ? "else " : "" + , (print_str != NULL) ? "else " : "" , t->get_dispname().c_str(), t->get_genname_value(this).c_str()); + if (t->get_typetype() != Type::T_PORT) { + overwrite_str = mputprintf(overwrite_str, + " %sif (!strcmp(p_var.type_name, \"%s\")) {\n" + " ((%s*)p_var.value)->set_param(p_new_value);\n" + " }\n" + , (overwrite_str != NULL) ? "else " : "" + , t->get_dispname().c_str(), t->get_genname_value(this).c_str()); + } } if (t->get_typetype() != Type::T_PORT) { - str = mputprintf(str, + print_str = mputprintf(print_str, " %sif (!strcmp(p_var.type_name, \"%s template\")) {\n" - " ((const %s_template*)p_var.value)->log();\n" + " ((const %s_template*)ptr)->log();\n" " }\n" - , (str != NULL) ? "else " : "" + , (print_str != NULL) ? "else " : "" , t->get_dispname().c_str(), t->get_genname_value(this).c_str()); + if (t->get_typetype() != Type::T_SIGNATURE) { + overwrite_str = mputprintf(overwrite_str, + " %sif (!strcmp(p_var.type_name, \"%s template\")) {\n" + " ((%s_template*)p_var.value)->set_param(p_new_value);\n" + " }\n" + , (overwrite_str != NULL) ? "else " : "" + , t->get_dispname().c_str(), t->get_genname_value(this).c_str()); + } } } } } - if (str != NULL) { + if (print_str != NULL) { // don't generate an empty printing function output->header.class_defs = mputprintf(output->header.class_defs, - "/* Debugger printing function for types declared in this module */\n\n" + "/* Debugger printing and overwriting functions for types declared in this module */\n\n" "extern CHARSTRING print_var_%s(const TTCN3_Debugger::variable_t& p_var);\n", get_modid().get_ttcnname().c_str()); output->source.global_vars = mputprintf(output->source.global_vars, "\n/* Debugger printing function for types declared in this module */\n" "CHARSTRING print_var_%s(const TTCN3_Debugger::variable_t& p_var)\n" "{\n" + " const void* ptr = p_var.set_function != NULL ? p_var.value : p_var.cvalue;\n" " TTCN_Logger::begin_event_log2str();\n" "%s" " else {\n" " TTCN_Logger::log_event_str(\"<unrecognized value or template>\");\n" " }\n" " return TTCN_Logger::end_event_log2str();\n" - "}\n", get_modid().get_ttcnname().c_str(), str); + "}\n", get_modid().get_ttcnname().c_str(), print_str); + } + if (overwrite_str != NULL) { + // don't generate an empty overwriting function + output->header.class_defs = mputprintf(output->header.class_defs, + "extern boolean set_var_%s(TTCN3_Debugger::variable_t& p_var, Module_Param& p_new_value);\n", + get_modid().get_ttcnname().c_str()); + output->source.global_vars = mputprintf(output->source.global_vars, + "\n/* Debugger overwriting function for types declared in this module */\n" + "boolean set_var_%s(TTCN3_Debugger::variable_t& p_var, Module_Param& p_new_value)\n" + "{\n" + "%s" + " else {\n" + " return FALSE;\n" + " }\n" + " return TRUE;\n" + "}\n", get_modid().get_ttcnname().c_str(), overwrite_str); } } @@ -7542,6 +7576,9 @@ namespace Ttcn { "timer_value);\n"); body = create_location_object(body, "TESTCASE", dispname_str); body = fp_list->generate_shadow_objects(body); + if (debugger_active) { + body = generate_code_debugger_function_init(body, this); + } body = mputprintf(body, "try {\n" "TTCN_Runtime::begin_testcase(\"%s\", \"%s\", ", my_scope->get_scope_mod()->get_modid().get_dispname().c_str(), @@ -7553,9 +7590,6 @@ namespace Ttcn { body = system_type->get_CompBody()->generate_code_comptype_name(body); else body = runs_on_body->generate_code_comptype_name(body); body = mputstr(body, ", has_timer, timer_value);\n"); - if (debugger_active) { - body = generate_code_debugger_function_init(body, this); - } body = block->generate_code(body); body = mputprintf(body, "} catch (const TC_Error& tc_error) {\n" diff --git a/compiler2/ttcn3_makefilegen.1 b/compiler2/ttcn3_makefilegen.1 index fb1c164f9c2124eb1840c69e922ef2453619bca2..a99b01d834fc80900bba0a939bb437ef0ca1af17 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 "[\| " \-acdEfglMpRsw " \|]" +.RB "[\| " \-acdEfglMnpRsw " \|]" .RB "[\| " \-e .IR " ETS_name" " \|]" .RB "[\| " \-o @@ -126,6 +126,9 @@ operation and the .B present template restriction accordingly. .TP +.B \-n +Activates the debugger and generates extra code for storing debug information. +.TP .B \-p Generate Makefile with .I TTCN-3 preprocessing. diff --git a/compiler2/xpather.cc b/compiler2/xpather.cc index 59e14e97e5dd1b9562d147b3e3c5a52fa8ae4d1e..2c6cf1e3273b3bce835b5c9f1c4595d73d8281f8 100644 --- a/compiler2/xpather.cc +++ b/compiler2/xpather.cc @@ -633,7 +633,8 @@ static tpd_result process_tpd_internal(const char *p_tpd_name, char* tpdName, co 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, boolean *p_Eflag, boolean* p_diflag, 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_nflag, + 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, @@ -652,7 +653,8 @@ 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, boolean* p_Eflag, boolean* p_diflag, 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_nflag, + 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, @@ -675,7 +677,7 @@ 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, p_Eflag, p_diflag, solspeclibs, sol8speclibs, + p_asflag, p_swflag, p_Yflag, p_Mflag, p_Eflag, p_nflag, p_diflag, solspeclibs, sol8speclibs, linuxspeclibs, freebsdspeclibs, win32speclibs, ttcn3prep, linkerlibs, additionalObjects, linkerlibsearchp, Vflag, Dflag, p_Zflag, p_Hflag, generatorCommandOutput, target_placement_list, prefix_workdir, @@ -724,7 +726,8 @@ static tpd_result process_tpd_internal(const char *p_tpd_name, char *tpdName, co 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, boolean* p_Eflag, boolean* p_diflag, 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_nflag, + 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, @@ -1245,6 +1248,7 @@ static tpd_result process_tpd_internal(const char *p_tpd_name, char *tpdName, co xsdbool2boolean(xpathCtx, actcfg, "forceOldFuncOutParHandling", p_Yflag); xsdbool2boolean(xpathCtx, actcfg, "omitInValueList", p_Mflag); xsdbool2boolean(xpathCtx, actcfg, "warningsForBadVariants", p_Eflag); + xsdbool2boolean(xpathCtx, actcfg, "activateDebugger", p_nflag); xsdbool2boolean(xpathCtx, actcfg, "disablePredefinedExternalFolder", p_diflag); projDesc = projGenHelper.getTargetOfProject(*p_project_name); @@ -2085,7 +2089,8 @@ static tpd_result process_tpd_internal(const char *p_tpd_name, char *tpdName, co 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_Eflag = 0, my_diflag = *p_diflag; + my_swflag = 0, my_Yflag = 0, my_Mflag = *p_Mflag, my_Eflag = 0, my_nflag = *p_nflag, + my_diflag = *p_diflag; char *my_ets = NULL; char *my_proj_name = NULL; @@ -2107,7 +2112,7 @@ static tpd_result process_tpd_internal(const char *p_tpd_name, char *tpdName, co 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_Eflag, &my_diflag, + &my_gfflag, &my_lnflag, &my_isflag, &my_asflag, &my_swflag, &my_Yflag, &my_Mflag, &my_Eflag, &my_nflag, &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, diff --git a/compiler2/xpather.h b/compiler2/xpather.h index 8cfd183de4bd217e26b6fe9402ef48cb3d943527..de3f9c91a5e47d6015955781a7abeb2b59376baa 100644 --- a/compiler2/xpather.h +++ b/compiler2/xpather.h @@ -197,6 +197,7 @@ boolean buildObjects(const char* projName, boolean add_referenced); * @param outparamboundness outParamBoundness -Y * @param omit_in_value_list omitInValueList -M * @param warnings_for_bad_variants warningsForBadVariants -E + * @param activate_debugger activateDebugger -n * @param disable_predef_exp_folder disablePredefinedExternalFolder * @param solspeclibs SolarisSpecificLibraries * @param sol8speclibs Solaris8SpecificLibraries @@ -238,7 +239,8 @@ 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, boolean *warnings_for_bad_variants, boolean *disable_predef_exp_folder, struct string_list* solspeclibs, struct string_list* sol8speclibs, + boolean *outparamboundness, boolean *omit_in_value_list, boolean *warnings_for_bad_variants, boolean *activate_debugger, + 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, diff --git a/conformance_test/negative_tests/21_configuration_operations.script b/conformance_test/negative_tests/21_configuration_operations.script index f213b10efc045473ac7f3e76399dd0a4801d5cb3..1ce87e4515a03cbf29a66d60b0b665a83e189b2b 100644 --- a/conformance_test/negative_tests/21_configuration_operations.script +++ b/conformance_test/negative_tests/21_configuration_operations.script @@ -1235,7 +1235,7 @@ module NegSem_210302_Start_test_component_001 { <END_MODULE> <RESULT COUNT 1> -Dynamic test case error: PTC with component reference 3 is not alive anymore. Start operation cannot be performed on it. +Dynamic test case error: <END_RESULT> <END_TC> diff --git a/conformance_test/positive_tests/09_test_configurations/0901_communication_ports/Sem_0901_Communication_ports_009.ttcn b/conformance_test/positive_tests/09_test_configurations/0901_communication_ports/Sem_0901_Communication_ports_009.ttcn index d010e35fda31c4c5bf9ab385d928ebf82cb8f3ba..54003110365cd195868f6ee73a3b0cf6b54d83f4 100755 --- a/conformance_test/positive_tests/09_test_configurations/0901_communication_ports/Sem_0901_Communication_ports_009.ttcn +++ b/conformance_test/positive_tests/09_test_configurations/0901_communication_ports/Sem_0901_Communication_ports_009.ttcn @@ -28,6 +28,8 @@ module Sem_0901_Communication_ports_009 { function checkConnected() runs on GeneralComp { + log("check"); + if(p.checkstate("Connected")) { setverdict(pass,"Connected"); } else { @@ -49,6 +51,7 @@ module Sem_0901_Communication_ports_009 { v_ptcB.start(checkConnected()); v_ptcC.start(checkConnected()); + all component.done; } control{ diff --git a/conformance_test/positive_tests/09_test_configurations/0902_test_system_interface/Sem_0902_001_loopbackPort.cc b/conformance_test/positive_tests/09_test_configurations/0902_test_system_interface/Sem_0902_001_loopbackPort.cc new file mode 100644 index 0000000000000000000000000000000000000000..7aaa9fa840c2df487ca54c3485e287f45a905419 --- /dev/null +++ b/conformance_test/positive_tests/09_test_configurations/0902_test_system_interface/Sem_0902_001_loopbackPort.cc @@ -0,0 +1,77 @@ +// This Test Port skeleton source file was generated by the +// TTCN-3 Compiler of the TTCN-3 Test Executor version CRL 113 200/5 R4D +// for eadrkir (eadrkir@eadrkir-VirtualBox) on Mon Apr 18 14:18:01 2016 + +// Copyright (c) 2000-2015 Ericsson Telecom AB + +// You may modify this file. Complete the body of empty functions and +// add your member functions here. + +#include "Sem_0902_001_loopbackPort.hh" + +namespace Sem__0902__Communication__ports__001 { + +Sem__0902__001__loopbackPort::Sem__0902__001__loopbackPort(const char *par_port_name) + : Sem__0902__001__loopbackPort_BASE(par_port_name) +{ + +} + +Sem__0902__001__loopbackPort::~Sem__0902__001__loopbackPort() +{ + +} + +void Sem__0902__001__loopbackPort::set_parameter(const char * /*parameter_name*/, + const char * /*parameter_value*/) +{ + +} + +/*void Sem__0902__001__loopbackPort::Handle_Fd_Event(int fd, boolean is_readable, + boolean is_writable, boolean is_error) {}*/ + +void Sem__0902__001__loopbackPort::Handle_Fd_Event_Error(int /*fd*/) +{ + +} + +void Sem__0902__001__loopbackPort::Handle_Fd_Event_Writable(int /*fd*/) +{ + +} + +void Sem__0902__001__loopbackPort::Handle_Fd_Event_Readable(int /*fd*/) +{ + +} + +/*void Sem__0902__001__loopbackPort::Handle_Timeout(double time_since_last_call) {}*/ + +void Sem__0902__001__loopbackPort::user_map(const char * /*system_port*/) +{ + +} + +void Sem__0902__001__loopbackPort::user_unmap(const char * /*system_port*/) +{ + +} + +void Sem__0902__001__loopbackPort::user_start() +{ + +} + +void Sem__0902__001__loopbackPort::user_stop() +{ + +} + +void Sem__0902__001__loopbackPort::outgoing_send(const INTEGER& send_par) +{ + incoming_message(send_par); +} + +} /* end of namespace */ + diff --git a/conformance_test/positive_tests/09_test_configurations/0902_test_system_interface/Sem_0902_001_loopbackPort.hh b/conformance_test/positive_tests/09_test_configurations/0902_test_system_interface/Sem_0902_001_loopbackPort.hh new file mode 100644 index 0000000000000000000000000000000000000000..757ca69d4362f2821e54b049c53c98529bd5f5e3 --- /dev/null +++ b/conformance_test/positive_tests/09_test_configurations/0902_test_system_interface/Sem_0902_001_loopbackPort.hh @@ -0,0 +1,44 @@ +// This Test Port skeleton header file was generated by the +// TTCN-3 Compiler of the TTCN-3 Test Executor version CRL 113 200/5 R4D +// for eadrkir (eadrkir@eadrkir-VirtualBox) on Mon Apr 18 14:18:01 2016 + +// Copyright (c) 2000-2015 Ericsson Telecom AB + +// You may modify this file. Add your attributes and prototypes of your +// member functions here. + +#ifndef Sem_0902_001_loopbackPort_HH +#define Sem_0902_001_loopbackPort_HH + +#include "Sem_0902_Communication_ports_001.hh" + +namespace Sem__0902__Communication__ports__001 { + +class Sem__0902__001__loopbackPort : public Sem__0902__001__loopbackPort_BASE { +public: + Sem__0902__001__loopbackPort(const char *par_port_name = NULL); + ~Sem__0902__001__loopbackPort(); + + void set_parameter(const char *parameter_name, + const char *parameter_value); + +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 INTEGER& send_par); +}; + +} /* end of namespace */ + +#endif diff --git a/conformance_test/positive_tests/09_test_configurations/0902_test_system_interface/Sem_0902_002_loopbackPort.cc b/conformance_test/positive_tests/09_test_configurations/0902_test_system_interface/Sem_0902_002_loopbackPort.cc new file mode 100644 index 0000000000000000000000000000000000000000..290f1482867f7cf0ff1a1371605796a3feaf7677 --- /dev/null +++ b/conformance_test/positive_tests/09_test_configurations/0902_test_system_interface/Sem_0902_002_loopbackPort.cc @@ -0,0 +1,77 @@ +// This Test Port skeleton source file was generated by the +// TTCN-3 Compiler of the TTCN-3 Test Executor version CRL 113 200/5 R4D +// for eadrkir (eadrkir@eadrkir-VirtualBox) on Mon Apr 18 14:18:01 2016 + +// Copyright (c) 2000-2015 Ericsson Telecom AB + +// You may modify this file. Complete the body of empty functions and +// add your member functions here. + +#include "Sem_0902_002_loopbackPort.hh" + +namespace Sem__0902__Communication__ports__002 { + +Sem__0902__002__loopbackPort::Sem__0902__002__loopbackPort(const char *par_port_name) + : Sem__0902__002__loopbackPort_BASE(par_port_name) +{ + +} + +Sem__0902__002__loopbackPort::~Sem__0902__002__loopbackPort() +{ + +} + +void Sem__0902__002__loopbackPort::set_parameter(const char * /*parameter_name*/, + const char * /*parameter_value*/) +{ + +} + +/*void Sem__0902__002__loopbackPort::Handle_Fd_Event(int fd, boolean is_readable, + boolean is_writable, boolean is_error) {}*/ + +void Sem__0902__002__loopbackPort::Handle_Fd_Event_Error(int /*fd*/) +{ + +} + +void Sem__0902__002__loopbackPort::Handle_Fd_Event_Writable(int /*fd*/) +{ + +} + +void Sem__0902__002__loopbackPort::Handle_Fd_Event_Readable(int /*fd*/) +{ + +} + +/*void Sem__0902__002__loopbackPort::Handle_Timeout(double time_since_last_call) {}*/ + +void Sem__0902__002__loopbackPort::user_map(const char * /*system_port*/) +{ + +} + +void Sem__0902__002__loopbackPort::user_unmap(const char * /*system_port*/) +{ + +} + +void Sem__0902__002__loopbackPort::user_start() +{ + +} + +void Sem__0902__002__loopbackPort::user_stop() +{ + +} + +void Sem__0902__002__loopbackPort::outgoing_send(const INTEGER& send_par) +{ + incoming_message(send_par); +} + +} /* end of namespace */ + diff --git a/conformance_test/positive_tests/09_test_configurations/0902_test_system_interface/Sem_0902_002_loopbackPort.hh b/conformance_test/positive_tests/09_test_configurations/0902_test_system_interface/Sem_0902_002_loopbackPort.hh new file mode 100644 index 0000000000000000000000000000000000000000..ecbcf98a0f4836efd141defb602c09cdc9f94601 --- /dev/null +++ b/conformance_test/positive_tests/09_test_configurations/0902_test_system_interface/Sem_0902_002_loopbackPort.hh @@ -0,0 +1,44 @@ +// This Test Port skeleton header file was generated by the +// TTCN-3 Compiler of the TTCN-3 Test Executor version CRL 113 200/5 R4D +// for eadrkir (eadrkir@eadrkir-VirtualBox) on Mon Apr 18 14:18:01 2016 + +// Copyright (c) 2000-2015 Ericsson Telecom AB + +// You may modify this file. Add your attributes and prototypes of your +// member functions here. + +#ifndef Sem_0902_002_loopbackPort_HH +#define Sem_0902_002_loopbackPort_HH + +#include "Sem_0902_Communication_ports_002.hh" + +namespace Sem__0902__Communication__ports__002 { + +class Sem__0902__002__loopbackPort : public Sem__0902__002__loopbackPort_BASE { +public: + Sem__0902__002__loopbackPort(const char *par_port_name = NULL); + ~Sem__0902__002__loopbackPort(); + + void set_parameter(const char *parameter_name, + const char *parameter_value); + +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 INTEGER& send_par); +}; + +} /* end of namespace */ + +#endif diff --git a/conformance_test/positive_tests/09_test_configurations/0902_test_system_interface/Sem_0902_Communication_ports_001.ttcn b/conformance_test/positive_tests/09_test_configurations/0902_test_system_interface/Sem_0902_Communication_ports_001.ttcn index e3598d68d7910c17a80576f2709374af782196f5..9eb3c4f61412c59cf18d654a03098fd020ffcc66 100644 --- a/conformance_test/positive_tests/09_test_configurations/0902_test_system_interface/Sem_0902_Communication_ports_001.ttcn +++ b/conformance_test/positive_tests/09_test_configurations/0902_test_system_interface/Sem_0902_Communication_ports_001.ttcn @@ -16,18 +16,18 @@ // Mycompport A is mapped with a system interface module Sem_0902_Communication_ports_001{ - type port loopbackPort message { + type port Sem_0902_001_loopbackPort message { inout integer } type component GeneralComp { - port loopbackPort MycomportA + port Sem_0902_001_loopbackPort MycomportA } type component MyTestSystemInterface { - port loopbackPort messagePort + port Sem_0902_001_loopbackPort messagePort } // MyTestSystemInterface is the test system interface diff --git a/conformance_test/positive_tests/09_test_configurations/0902_test_system_interface/Sem_0902_Communication_ports_002.ttcn b/conformance_test/positive_tests/09_test_configurations/0902_test_system_interface/Sem_0902_Communication_ports_002.ttcn index 5d030bc742ae98c7f83c02ef632e402a85d28d54..e4567eb6eb0bddadec17acb2588f822c9314089b 100644 --- a/conformance_test/positive_tests/09_test_configurations/0902_test_system_interface/Sem_0902_Communication_ports_002.ttcn +++ b/conformance_test/positive_tests/09_test_configurations/0902_test_system_interface/Sem_0902_Communication_ports_002.ttcn @@ -16,7 +16,7 @@ //Two ports are mapped to two system interface module Sem_0902_Communication_ports_002{ - type port loopbackPort1 message { + type port Sem_0902_002_loopbackPort message { inout integer } @@ -24,12 +24,12 @@ module Sem_0902_Communication_ports_002{ { var integer v_received1:=0; var integer v_received2:=0; - port loopbackPort1 myPortA,myPortB + port Sem_0902_002_loopbackPort myPortA,myPortB } type component MyTestSystemInterface { - port loopbackPort1 messagePortA,messagePortB + port Sem_0902_002_loopbackPort messagePortA,messagePortB } // MyTestSystemInterface is the test system interface diff --git a/conformance_test/positive_tests/16_functions_altsteps_testcases/1602_altsteps/160201_invoking_altsteps/Sem_160201_003_loopbackPort.cc b/conformance_test/positive_tests/16_functions_altsteps_testcases/1602_altsteps/160201_invoking_altsteps/Sem_160201_003_loopbackPort.cc new file mode 100644 index 0000000000000000000000000000000000000000..cfd7236d25401fffbf7608a09582de2efc19b67c --- /dev/null +++ b/conformance_test/positive_tests/16_functions_altsteps_testcases/1602_altsteps/160201_invoking_altsteps/Sem_160201_003_loopbackPort.cc @@ -0,0 +1,77 @@ +// This Test Port skeleton source file was generated by the +// TTCN-3 Compiler of the TTCN-3 Test Executor version CRL 113 200/5 R4D +// for eadrkir (eadrkir@eadrkir-VirtualBox) on Mon Apr 18 14:18:01 2016 + +// Copyright (c) 2000-2015 Ericsson Telecom AB + +// You may modify this file. Complete the body of empty functions and +// add your member functions here. + +#include "Sem_160201_003_loopbackPort.hh" + +namespace Sem__160201__invoking__altsteps__003 { + +Sem__160201__003__loopbackPort::Sem__160201__003__loopbackPort(const char *par_port_name) + : Sem__160201__003__loopbackPort_BASE(par_port_name) +{ + +} + +Sem__160201__003__loopbackPort::~Sem__160201__003__loopbackPort() +{ + +} + +void Sem__160201__003__loopbackPort::set_parameter(const char * /*parameter_name*/, + const char * /*parameter_value*/) +{ + +} + +/*void Sem__160201__003__loopbackPort::Handle_Fd_Event(int fd, boolean is_readable, + boolean is_writable, boolean is_error) {}*/ + +void Sem__160201__003__loopbackPort::Handle_Fd_Event_Error(int /*fd*/) +{ + +} + +void Sem__160201__003__loopbackPort::Handle_Fd_Event_Writable(int /*fd*/) +{ + +} + +void Sem__160201__003__loopbackPort::Handle_Fd_Event_Readable(int /*fd*/) +{ + +} + +/*void Sem__160201__003__loopbackPort::Handle_Timeout(double time_since_last_call) {}*/ + +void Sem__160201__003__loopbackPort::user_map(const char * /*system_port*/) +{ + +} + +void Sem__160201__003__loopbackPort::user_unmap(const char * /*system_port*/) +{ + +} + +void Sem__160201__003__loopbackPort::user_start() +{ + +} + +void Sem__160201__003__loopbackPort::user_stop() +{ + +} + +void Sem__160201__003__loopbackPort::outgoing_send(const INTEGER& send_par) +{ + incoming_message(send_par); +} + +} /* end of namespace */ + diff --git a/conformance_test/positive_tests/16_functions_altsteps_testcases/1602_altsteps/160201_invoking_altsteps/Sem_160201_003_loopbackPort.hh b/conformance_test/positive_tests/16_functions_altsteps_testcases/1602_altsteps/160201_invoking_altsteps/Sem_160201_003_loopbackPort.hh new file mode 100644 index 0000000000000000000000000000000000000000..d059879059842f149cf6eaa2e9b85621cd3c5255 --- /dev/null +++ b/conformance_test/positive_tests/16_functions_altsteps_testcases/1602_altsteps/160201_invoking_altsteps/Sem_160201_003_loopbackPort.hh @@ -0,0 +1,44 @@ +// This Test Port skeleton header file was generated by the +// TTCN-3 Compiler of the TTCN-3 Test Executor version CRL 113 200/5 R4D +// for eadrkir (eadrkir@eadrkir-VirtualBox) on Mon Apr 18 14:18:01 2016 + +// Copyright (c) 2000-2015 Ericsson Telecom AB + +// You may modify this file. Add your attributes and prototypes of your +// member functions here. + +#ifndef Sem_160201_003_loopbackPort_HH +#define Sem_160201_003_loopbackPort_HH + +#include "Sem_160201_invoking_altsteps_003.hh" + +namespace Sem__160201__invoking__altsteps__003 { + +class Sem__160201__003__loopbackPort : public Sem__160201__003__loopbackPort_BASE { +public: + Sem__160201__003__loopbackPort(const char *par_port_name = NULL); + ~Sem__160201__003__loopbackPort(); + + void set_parameter(const char *parameter_name, + const char *parameter_value); + +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 INTEGER& send_par); +}; + +} /* end of namespace */ + +#endif diff --git a/conformance_test/positive_tests/16_functions_altsteps_testcases/1602_altsteps/160201_invoking_altsteps/Sem_160201_004_loopbackPort.cc b/conformance_test/positive_tests/16_functions_altsteps_testcases/1602_altsteps/160201_invoking_altsteps/Sem_160201_004_loopbackPort.cc new file mode 100644 index 0000000000000000000000000000000000000000..017eb07cedf62cb42a091be23e0fe0ff27ccae3e --- /dev/null +++ b/conformance_test/positive_tests/16_functions_altsteps_testcases/1602_altsteps/160201_invoking_altsteps/Sem_160201_004_loopbackPort.cc @@ -0,0 +1,77 @@ +// This Test Port skeleton source file was generated by the +// TTCN-3 Compiler of the TTCN-3 Test Executor version CRL 113 200/5 R4D +// for eadrkir (eadrkir@eadrkir-VirtualBox) on Mon Apr 18 14:18:01 2016 + +// Copyright (c) 2000-2015 Ericsson Telecom AB + +// You may modify this file. Complete the body of empty functions and +// add your member functions here. + +#include "Sem_160201_004_loopbackPort.hh" + +namespace Sem__160201__invoking__altsteps__004 { + +Sem__160201__004__loopbackPort::Sem__160201__004__loopbackPort(const char *par_port_name) + : Sem__160201__004__loopbackPort_BASE(par_port_name) +{ + +} + +Sem__160201__004__loopbackPort::~Sem__160201__004__loopbackPort() +{ + +} + +void Sem__160201__004__loopbackPort::set_parameter(const char * /*parameter_name*/, + const char * /*parameter_value*/) +{ + +} + +/*void Sem__160201__004__loopbackPort::Handle_Fd_Event(int fd, boolean is_readable, + boolean is_writable, boolean is_error) {}*/ + +void Sem__160201__004__loopbackPort::Handle_Fd_Event_Error(int /*fd*/) +{ + +} + +void Sem__160201__004__loopbackPort::Handle_Fd_Event_Writable(int /*fd*/) +{ + +} + +void Sem__160201__004__loopbackPort::Handle_Fd_Event_Readable(int /*fd*/) +{ + +} + +/*void Sem__160201__004__loopbackPort::Handle_Timeout(double time_since_last_call) {}*/ + +void Sem__160201__004__loopbackPort::user_map(const char * /*system_port*/) +{ + +} + +void Sem__160201__004__loopbackPort::user_unmap(const char * /*system_port*/) +{ + +} + +void Sem__160201__004__loopbackPort::user_start() +{ + +} + +void Sem__160201__004__loopbackPort::user_stop() +{ + +} + +void Sem__160201__004__loopbackPort::outgoing_send(const INTEGER& send_par) +{ + incoming_message(send_par); +} + +} /* end of namespace */ + diff --git a/conformance_test/positive_tests/16_functions_altsteps_testcases/1602_altsteps/160201_invoking_altsteps/Sem_160201_004_loopbackPort.hh b/conformance_test/positive_tests/16_functions_altsteps_testcases/1602_altsteps/160201_invoking_altsteps/Sem_160201_004_loopbackPort.hh new file mode 100644 index 0000000000000000000000000000000000000000..8e42f75345ca0e61d4ae55a23c3a67bd86657a5c --- /dev/null +++ b/conformance_test/positive_tests/16_functions_altsteps_testcases/1602_altsteps/160201_invoking_altsteps/Sem_160201_004_loopbackPort.hh @@ -0,0 +1,44 @@ +// This Test Port skeleton header file was generated by the +// TTCN-3 Compiler of the TTCN-3 Test Executor version CRL 113 200/5 R4D +// for eadrkir (eadrkir@eadrkir-VirtualBox) on Mon Apr 18 14:18:01 2016 + +// Copyright (c) 2000-2015 Ericsson Telecom AB + +// You may modify this file. Add your attributes and prototypes of your +// member functions here. + +#ifndef Sem_160201_004_loopbackPort_HH +#define Sem_160201_004_loopbackPort_HH + +#include "Sem_160201_invoking_altsteps_004.hh" + +namespace Sem__160201__invoking__altsteps__004 { + +class Sem__160201__004__loopbackPort : public Sem__160201__004__loopbackPort_BASE { +public: + Sem__160201__004__loopbackPort(const char *par_port_name = NULL); + ~Sem__160201__004__loopbackPort(); + + void set_parameter(const char *parameter_name, + const char *parameter_value); + +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 INTEGER& send_par); +}; + +} /* end of namespace */ + +#endif diff --git a/conformance_test/positive_tests/16_functions_altsteps_testcases/1602_altsteps/160201_invoking_altsteps/Sem_160201_invoking_altsteps_003.ttcn b/conformance_test/positive_tests/16_functions_altsteps_testcases/1602_altsteps/160201_invoking_altsteps/Sem_160201_invoking_altsteps_003.ttcn index 903f2aa97899e3b9ce1792adcbdfa7525eea9417..9b8309ba24d776fbeec2e2df1d8b9a8cc28c23cf 100644 --- a/conformance_test/positive_tests/16_functions_altsteps_testcases/1602_altsteps/160201_invoking_altsteps/Sem_160201_invoking_altsteps_003.ttcn +++ b/conformance_test/positive_tests/16_functions_altsteps_testcases/1602_altsteps/160201_invoking_altsteps/Sem_160201_invoking_altsteps_003.ttcn @@ -16,22 +16,18 @@ // Mycompport A is dynamically mapped module Sem_160201_invoking_altsteps_003{ - type port loopbackPort message { + type port Sem_160201_003_loopbackPort message { inout integer - } with {extension "internal"} - - type port IntegerOutputPortType message { - inout integer - } with {extension "internal"} + } type component GeneralComp { - port IntegerOutputPortType MycomportA + port Sem_160201_003_loopbackPort MycomportA } type component MyTestSystemInterface { - port loopbackPort messagePort + port Sem_160201_003_loopbackPort messagePort } altstep AltStep1() runs on GeneralComp { diff --git a/conformance_test/positive_tests/16_functions_altsteps_testcases/1602_altsteps/160201_invoking_altsteps/Sem_160201_invoking_altsteps_004.ttcn b/conformance_test/positive_tests/16_functions_altsteps_testcases/1602_altsteps/160201_invoking_altsteps/Sem_160201_invoking_altsteps_004.ttcn index 3de332c6b88aa1b8ffd1b0c82bc197887612353c..74da367fa66fcde16fac70768e20119be13d6a92 100644 --- a/conformance_test/positive_tests/16_functions_altsteps_testcases/1602_altsteps/160201_invoking_altsteps/Sem_160201_invoking_altsteps_004.ttcn +++ b/conformance_test/positive_tests/16_functions_altsteps_testcases/1602_altsteps/160201_invoking_altsteps/Sem_160201_invoking_altsteps_004.ttcn @@ -16,23 +16,19 @@ // Mycompport A is dynamically mapped module Sem_160201_invoking_altsteps_004{ - type port loopbackPort message { + type port Sem_160201_004_loopbackPort message { inout integer - } with {extension "internal"} - - type port IntegerOutputPortType message { - inout integer - } with {extension "internal"} + } type component GeneralComp { timer tc_timer := 0.1; - port IntegerOutputPortType MycomportA + port Sem_160201_004_loopbackPort MycomportA } type component MyTestSystemInterface { - port loopbackPort messagePort + port Sem_160201_004_loopbackPort messagePort } altstep AltStep1() runs on GeneralComp { diff --git a/conformance_test/positive_tests/20_statement_and_operations_for_alt/2002_the_alt_statement/Sem_2002_012_loopbackPort.cc b/conformance_test/positive_tests/20_statement_and_operations_for_alt/2002_the_alt_statement/Sem_2002_012_loopbackPort.cc new file mode 100644 index 0000000000000000000000000000000000000000..10e24e74ce8f63710bdd092169eb577a415c7416 --- /dev/null +++ b/conformance_test/positive_tests/20_statement_and_operations_for_alt/2002_the_alt_statement/Sem_2002_012_loopbackPort.cc @@ -0,0 +1,77 @@ +// This Test Port skeleton source file was generated by the +// TTCN-3 Compiler of the TTCN-3 Test Executor version CRL 113 200/5 R4D +// for eadrkir (eadrkir@eadrkir-VirtualBox) on Mon Apr 18 14:18:01 2016 + +// Copyright (c) 2000-2015 Ericsson Telecom AB + +// You may modify this file. Complete the body of empty functions and +// add your member functions here. + +#include "Sem_2002_012_loopbackPort.hh" + +namespace Sem__2002__TheAltStatement__012 { + +Sem__2002__012__loopbackPort::Sem__2002__012__loopbackPort(const char *par_port_name) + : Sem__2002__012__loopbackPort_BASE(par_port_name) +{ + +} + +Sem__2002__012__loopbackPort::~Sem__2002__012__loopbackPort() +{ + +} + +void Sem__2002__012__loopbackPort::set_parameter(const char * /*parameter_name*/, + const char * /*parameter_value*/) +{ + +} + +/*void Sem__2002__012__loopbackPort::Handle_Fd_Event(int fd, boolean is_readable, + boolean is_writable, boolean is_error) {}*/ + +void Sem__2002__012__loopbackPort::Handle_Fd_Event_Error(int /*fd*/) +{ + +} + +void Sem__2002__012__loopbackPort::Handle_Fd_Event_Writable(int /*fd*/) +{ + +} + +void Sem__2002__012__loopbackPort::Handle_Fd_Event_Readable(int /*fd*/) +{ + +} + +/*void Sem__2002__012__loopbackPort::Handle_Timeout(double time_since_last_call) {}*/ + +void Sem__2002__012__loopbackPort::user_map(const char * /*system_port*/) +{ + +} + +void Sem__2002__012__loopbackPort::user_unmap(const char * /*system_port*/) +{ + +} + +void Sem__2002__012__loopbackPort::user_start() +{ + +} + +void Sem__2002__012__loopbackPort::user_stop() +{ + +} + +void Sem__2002__012__loopbackPort::outgoing_send(const INTEGER& send_par) +{ + incoming_message(send_par); +} + +} /* end of namespace */ + diff --git a/conformance_test/positive_tests/20_statement_and_operations_for_alt/2002_the_alt_statement/Sem_2002_012_loopbackPort.hh b/conformance_test/positive_tests/20_statement_and_operations_for_alt/2002_the_alt_statement/Sem_2002_012_loopbackPort.hh new file mode 100644 index 0000000000000000000000000000000000000000..3cc61fe23b04fb3209df0dd59fb09d91fee06a72 --- /dev/null +++ b/conformance_test/positive_tests/20_statement_and_operations_for_alt/2002_the_alt_statement/Sem_2002_012_loopbackPort.hh @@ -0,0 +1,44 @@ +// This Test Port skeleton header file was generated by the +// TTCN-3 Compiler of the TTCN-3 Test Executor version CRL 113 200/5 R4D +// for eadrkir (eadrkir@eadrkir-VirtualBox) on Mon Apr 18 14:18:01 2016 + +// Copyright (c) 2000-2015 Ericsson Telecom AB + +// You may modify this file. Add your attributes and prototypes of your +// member functions here. + +#ifndef Sem_2002_012_loopbackPort_HH +#define Sem_2002_012_loopbackPort_HH + +#include "Sem_2002_TheAltStatement_012.hh" + +namespace Sem__2002__TheAltStatement__012 { + +class Sem__2002__012__loopbackPort : public Sem__2002__012__loopbackPort_BASE { +public: + Sem__2002__012__loopbackPort(const char *par_port_name = NULL); + ~Sem__2002__012__loopbackPort(); + + void set_parameter(const char *parameter_name, + const char *parameter_value); + +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 INTEGER& send_par); +}; + +} /* end of namespace */ + +#endif diff --git a/conformance_test/positive_tests/20_statement_and_operations_for_alt/2002_the_alt_statement/Sem_2002_013_loopbackPort.cc b/conformance_test/positive_tests/20_statement_and_operations_for_alt/2002_the_alt_statement/Sem_2002_013_loopbackPort.cc new file mode 100644 index 0000000000000000000000000000000000000000..535649a07c9f442ad424add9fe8507a274400323 --- /dev/null +++ b/conformance_test/positive_tests/20_statement_and_operations_for_alt/2002_the_alt_statement/Sem_2002_013_loopbackPort.cc @@ -0,0 +1,77 @@ +// This Test Port skeleton source file was generated by the +// TTCN-3 Compiler of the TTCN-3 Test Executor version CRL 113 200/5 R4D +// for eadrkir (eadrkir@eadrkir-VirtualBox) on Mon Apr 18 14:18:01 2016 + +// Copyright (c) 2000-2015 Ericsson Telecom AB + +// You may modify this file. Complete the body of empty functions and +// add your member functions here. + +#include "Sem_2002_013_loopbackPort.hh" + +namespace Sem__2002__TheAltStatement__013 { + +Sem__2002__013__loopbackPort::Sem__2002__013__loopbackPort(const char *par_port_name) + : Sem__2002__013__loopbackPort_BASE(par_port_name) +{ + +} + +Sem__2002__013__loopbackPort::~Sem__2002__013__loopbackPort() +{ + +} + +void Sem__2002__013__loopbackPort::set_parameter(const char * /*parameter_name*/, + const char * /*parameter_value*/) +{ + +} + +/*void Sem__2002__013__loopbackPort::Handle_Fd_Event(int fd, boolean is_readable, + boolean is_writable, boolean is_error) {}*/ + +void Sem__2002__013__loopbackPort::Handle_Fd_Event_Error(int /*fd*/) +{ + +} + +void Sem__2002__013__loopbackPort::Handle_Fd_Event_Writable(int /*fd*/) +{ + +} + +void Sem__2002__013__loopbackPort::Handle_Fd_Event_Readable(int /*fd*/) +{ + +} + +/*void Sem__2002__013__loopbackPort::Handle_Timeout(double time_since_last_call) {}*/ + +void Sem__2002__013__loopbackPort::user_map(const char * /*system_port*/) +{ + +} + +void Sem__2002__013__loopbackPort::user_unmap(const char * /*system_port*/) +{ + +} + +void Sem__2002__013__loopbackPort::user_start() +{ + +} + +void Sem__2002__013__loopbackPort::user_stop() +{ + +} + +void Sem__2002__013__loopbackPort::outgoing_send(const INTEGER& send_par) +{ + incoming_message(send_par); +} + +} /* end of namespace */ + diff --git a/conformance_test/positive_tests/20_statement_and_operations_for_alt/2002_the_alt_statement/Sem_2002_013_loopbackPort.hh b/conformance_test/positive_tests/20_statement_and_operations_for_alt/2002_the_alt_statement/Sem_2002_013_loopbackPort.hh new file mode 100644 index 0000000000000000000000000000000000000000..f5406811d0b98580dd374d489057144194d26269 --- /dev/null +++ b/conformance_test/positive_tests/20_statement_and_operations_for_alt/2002_the_alt_statement/Sem_2002_013_loopbackPort.hh @@ -0,0 +1,44 @@ +// This Test Port skeleton header file was generated by the +// TTCN-3 Compiler of the TTCN-3 Test Executor version CRL 113 200/5 R4D +// for eadrkir (eadrkir@eadrkir-VirtualBox) on Mon Apr 18 14:18:01 2016 + +// Copyright (c) 2000-2015 Ericsson Telecom AB + +// You may modify this file. Add your attributes and prototypes of your +// member functions here. + +#ifndef Sem_2002_013_loopbackPort_HH +#define Sem_2002_013_loopbackPort_HH + +#include "Sem_2002_TheAltStatement_013.hh" + +namespace Sem__2002__TheAltStatement__013 { + +class Sem__2002__013__loopbackPort : public Sem__2002__013__loopbackPort_BASE { +public: + Sem__2002__013__loopbackPort(const char *par_port_name = NULL); + ~Sem__2002__013__loopbackPort(); + + void set_parameter(const char *parameter_name, + const char *parameter_value); + +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 INTEGER& send_par); +}; + +} /* end of namespace */ + +#endif diff --git a/conformance_test/positive_tests/20_statement_and_operations_for_alt/2002_the_alt_statement/Sem_2002_TheAltStatement_012.ttcn b/conformance_test/positive_tests/20_statement_and_operations_for_alt/2002_the_alt_statement/Sem_2002_TheAltStatement_012.ttcn index bd657d3458f0ff00f874dfd5431a127bf6bf27fc..8b882b01a8190ce6c0e4aaea10f88c1077250b1c 100644 --- a/conformance_test/positive_tests/20_statement_and_operations_for_alt/2002_the_alt_statement/Sem_2002_TheAltStatement_012.ttcn +++ b/conformance_test/positive_tests/20_statement_and_operations_for_alt/2002_the_alt_statement/Sem_2002_TheAltStatement_012.ttcn @@ -16,22 +16,18 @@ // Mycompport A is dynamically mapped module Sem_2002_TheAltStatement_012{ - type port loopbackPort message { + type port Sem_2002_012_loopbackPort message { inout integer - } with {extension "internal"} - - type port IntegerOutputPortType message { - inout integer - } with {extension "internal"} + } type component GeneralComp { - port IntegerOutputPortType MycomportA + port Sem_2002_012_loopbackPort MycomportA } type component MyTestSystemInterface { - port loopbackPort messagePort + port Sem_2002_012_loopbackPort messagePort } // MyTestSystemInterface is the test system interface diff --git a/conformance_test/positive_tests/20_statement_and_operations_for_alt/2002_the_alt_statement/Sem_2002_TheAltStatement_013.ttcn b/conformance_test/positive_tests/20_statement_and_operations_for_alt/2002_the_alt_statement/Sem_2002_TheAltStatement_013.ttcn index 5c34e2d1804f8c20d705f239f8be6e8c69e014c0..843a25ef4b0a22821edd6074ceb436a435d9b321 100644 --- a/conformance_test/positive_tests/20_statement_and_operations_for_alt/2002_the_alt_statement/Sem_2002_TheAltStatement_013.ttcn +++ b/conformance_test/positive_tests/20_statement_and_operations_for_alt/2002_the_alt_statement/Sem_2002_TheAltStatement_013.ttcn @@ -16,22 +16,18 @@ // Mycompport A is dynamically mapped module Sem_2002_TheAltStatement_013{ - type port loopbackPort message { + type port Sem_2002_013_loopbackPort message { inout integer - } with {extension "internal"} - - type port IntegerOutputPortType message { - inout integer - } with {extension "internal"} + } type component GeneralComp { - port IntegerOutputPortType MycomportA + port Sem_2002_013_loopbackPort MycomportA } type component MyTestSystemInterface { - port loopbackPort messagePort + port Sem_2002_013_loopbackPort messagePort } // MyTestSystemInterface is the test system interface diff --git a/conformance_test/positive_tests/C_predefined_functions/C06_Other_functions/C0602_The_testcasename_function/Sem_C0602_The_hostid_function_001.ttcn b/conformance_test/positive_tests/C_predefined_functions/C06_Other_functions/C0602_The_testcasename_function/Sem_C0602_The_hostid_function_001.ttcn index 7242232fc02f6bd97fa55d2a80527ce67522f8c2..e6ca66772518679140ee1165128f5a0bc2605c20 100755 --- a/conformance_test/positive_tests/C_predefined_functions/C06_Other_functions/C0602_The_testcasename_function/Sem_C0602_The_hostid_function_001.ttcn +++ b/conformance_test/positive_tests/C_predefined_functions/C06_Other_functions/C0602_The_testcasename_function/Sem_C0602_The_hostid_function_001.ttcn @@ -33,14 +33,14 @@ module Sem_C0602_The_hostid_function_001 { var IPaddressV6 v_ipv6hostid; // in case of no ip address is given - if ((lengthof(hostid("IPv4")) == 0) or (lengthof(hostid("IPv6"))==0 )) { + if ((lengthof(hostid("Ipv4")) == 0) or (lengthof(hostid("Ipv6"))==0 )) { setverdict(pass, "No ip address on interface"); } else { - v_ipv4hostid := hostid("IPv4"); // check IPv4 address with subtyping + v_ipv4hostid := hostid("Ipv4"); // check IPv4 address with subtyping setverdict(pass, v_ipv4hostid); - v_ipv6hostid := hostid("IPv6"); // check IPv6 address with subtyping + v_ipv6hostid := hostid("Ipv6"); // check IPv6 address with subtyping setverdict(pass, v_ipv6hostid); } diff --git a/conformance_test/positive_tests/pos_conf_tests.cfg b/conformance_test/positive_tests/pos_conf_tests.cfg index 1e5fa924bc01b249e0a290e008b167a012eb2df8..5351c70b13c32a924a76be3faaaf15ed47805026 100644 --- a/conformance_test/positive_tests/pos_conf_tests.cfg +++ b/conformance_test/positive_tests/pos_conf_tests.cfg @@ -582,6 +582,12 @@ Sem_0901_Communication_ports_002.control Sem_0901_Communication_ports_003.control Sem_0901_Communication_ports_004.control Sem_0901_Communication_ports_005.control +Sem_0901_Communication_ports_006.control +Sem_0901_Communication_ports_007.control +Sem_0901_Communication_ports_008.control +Sem_0901_Communication_ports_009.control +Sem_0901_Communication_ports_010.control +Sem_0901_Communication_ports_011.control Sem_0902_Communication_ports_001.control Sem_0902_Communication_ports_002.control Sem_10_Constants_001.control @@ -768,6 +774,8 @@ Sem_1601_toplevel_002.control Sem_1601_toplevel_003.control Sem_160201_invoking_altsteps_001.control Sem_160201_invoking_altsteps_002.control +Sem_160201_invoking_altsteps_003.control +Sem_160201_invoking_altsteps_004.control Sem_1602_toplevel_001.control Sem_1901_assignments_001.control Sem_1901_assignments_002.control @@ -813,6 +821,8 @@ Sem_2002_TheAltStatement_008.control Sem_2002_TheAltStatement_009.control Sem_2002_TheAltStatement_010.control Sem_2002_TheAltStatement_011.control +Sem_2002_TheAltStatement_012.control +Sem_2002_TheAltStatement_013.control Sem_2002_TheAltStatement_014.control Sem_2003_the_repeat_statement_001.control Sem_2003_the_repeat_statement_003.control @@ -840,7 +850,15 @@ Sem_210101_connect_and_map_operations_001.control Sem_210101_connect_and_map_operations_002.control Sem_210101_connect_and_map_operations_003.control Sem_210101_connect_and_map_operations_004.control +Sem_210101_connect_and_map_operations_005.control +Sem_210101_connect_and_map_operations_006.control +Sem_210101_connect_and_map_operations_007.control +Sem_210101_connect_and_map_operations_008.control +Sem_210102_disconnect_and_unmap_operations_001.control Sem_210102_disconnect_and_unmap_operations_010.control +Sem_210102_disconnect_operation_002.control +Sem_210102_unmap_operation_001.control +Sem_210102_unmap_operation_002.control Sem_210301_CreateOperation_001.control Sem_210301_CreateOperation_002.control Sem_210301_CreateOperation_003.control @@ -1138,6 +1156,7 @@ Sem_B010503_match_n_times_005.control Sem_B010505_pattern_compatibility_001.control Sem_B0105_toplevel_001.control Sem_B0105_toplevel_002.control +Sem_C0602_The_hostid_function_001.control Sem_C0602_The_testcasename_function_001.control Sem_D01_macro_module_001.control Sem_D02_macro_file_001.control diff --git a/conformance_test/positive_tests/pos_conf_tests.tpd b/conformance_test/positive_tests/pos_conf_tests.tpd index 53136924b040030e1dfb5d85f654ff3b164a97f4..d55c2f9cb58e93ff6e3d4c3c3d5ef8b4f994fdd0 100644 --- a/conformance_test/positive_tests/pos_conf_tests.tpd +++ b/conformance_test/positive_tests/pos_conf_tests.tpd @@ -1701,22 +1701,22 @@ <FileResource projectRelativePath="09_test_configurations/0901_communication_ports/Sem_0901_Communication_ports_003.ttcn" relativeURI="09_test_configurations/0901_communication_ports/Sem_0901_Communication_ports_003.ttcn"/> <FileResource projectRelativePath="09_test_configurations/0901_communication_ports/Sem_0901_Communication_ports_004.ttcn" relativeURI="09_test_configurations/0901_communication_ports/Sem_0901_Communication_ports_004.ttcn"/> <FileResource projectRelativePath="09_test_configurations/0901_communication_ports/Sem_0901_Communication_ports_005.ttcn" relativeURI="09_test_configurations/0901_communication_ports/Sem_0901_Communication_ports_005.ttcn"/> -<!-- <FileResource projectRelativePath="09_test_configurations/0901_communication_ports/Sem_0901_Communication_ports_006.ttcn" relativeURI="09_test_configurations/0901_communication_ports/Sem_0901_Communication_ports_006.ttcn"/>--> -<!-- <FileResource projectRelativePath="09_test_configurations/0901_communication_ports/Sem_0901_Communication_ports_007.ttcn" relativeURI="09_test_configurations/0901_communication_ports/Sem_0901_Communication_ports_007.ttcn"/>--> -<!-- <FileResource projectRelativePath="09_test_configurations/0901_communication_ports/Sem_0901_Communication_ports_008.ttcn" relativeURI="09_test_configurations/0901_communication_ports/Sem_0901_Communication_ports_008.ttcn"/>--> -<!-- <FileResource projectRelativePath="09_test_configurations/0901_communication_ports/Sem_0901_Communication_ports_009.ttcn" relativeURI="09_test_configurations/0901_communication_ports/Sem_0901_Communication_ports_009.ttcn"/>--> -<!-- <FileResource projectRelativePath="09_test_configurations/0901_communication_ports/Sem_0901_Communication_ports_010.ttcn" relativeURI="09_test_configurations/0901_communication_ports/Sem_0901_Communication_ports_010.ttcn"/>--> -<!-- <FileResource projectRelativePath="09_test_configurations/0901_communication_ports/Sem_0901_Communication_ports_011.ttcn" relativeURI="09_test_configurations/0901_communication_ports/Sem_0901_Communication_ports_011.ttcn"/>--> + <FileResource projectRelativePath="09_test_configurations/0901_communication_ports/Sem_0901_Communication_ports_006.ttcn" relativeURI="09_test_configurations/0901_communication_ports/Sem_0901_Communication_ports_006.ttcn"/> + <FileResource projectRelativePath="09_test_configurations/0901_communication_ports/Sem_0901_Communication_ports_007.ttcn" relativeURI="09_test_configurations/0901_communication_ports/Sem_0901_Communication_ports_007.ttcn"/> + <FileResource projectRelativePath="09_test_configurations/0901_communication_ports/Sem_0901_Communication_ports_008.ttcn" relativeURI="09_test_configurations/0901_communication_ports/Sem_0901_Communication_ports_008.ttcn"/> + <FileResource projectRelativePath="09_test_configurations/0901_communication_ports/Sem_0901_Communication_ports_009.ttcn" relativeURI="09_test_configurations/0901_communication_ports/Sem_0901_Communication_ports_009.ttcn"/> + <FileResource projectRelativePath="09_test_configurations/0901_communication_ports/Sem_0901_Communication_ports_010.ttcn" relativeURI="09_test_configurations/0901_communication_ports/Sem_0901_Communication_ports_010.ttcn"/> + <FileResource projectRelativePath="09_test_configurations/0901_communication_ports/Sem_0901_Communication_ports_011.ttcn" relativeURI="09_test_configurations/0901_communication_ports/Sem_0901_Communication_ports_011.ttcn"/> <!-- <FileResource projectRelativePath="09_test_configurations/0902_test_system_interface/NegSem_0902_Communication_ports_001.ttcn" relativeURI="09_test_configurations/0902_test_system_interface/NegSem_0902_Communication_ports_001.ttcn"/>--> <!-- <FileResource projectRelativePath="09_test_configurations/0902_test_system_interface/NegSem_0902_Communication_ports_002.ttcn" relativeURI="09_test_configurations/0902_test_system_interface/NegSem_0902_Communication_ports_002.ttcn"/>--> <!-- <FileResource projectRelativePath="09_test_configurations/0902_test_system_interface/NegSem_0902_Communication_ports_003.ttcn" relativeURI="09_test_configurations/0902_test_system_interface/NegSem_0902_Communication_ports_003.ttcn"/>--> <!-- <FileResource projectRelativePath="09_test_configurations/0902_test_system_interface/NegSem_0902_Communication_ports_004.ttcn" relativeURI="09_test_configurations/0902_test_system_interface/NegSem_0902_Communication_ports_004.ttcn"/>--> <FileResource projectRelativePath="09_test_configurations/0902_test_system_interface/Sem_0902_Communication_ports_001.ttcn" relativeURI="09_test_configurations/0902_test_system_interface/Sem_0902_Communication_ports_001.ttcn"/> - <FileResource projectRelativePath="09_test_configurations/0902_test_system_interface/loopbackPort.cc" relativeURI="09_test_configurations/0902_test_system_interface/loopbackPort.cc"/> - <FileResource projectRelativePath="09_test_configurations/0902_test_system_interface/loopbackPort.hh" relativeURI="09_test_configurations/0902_test_system_interface/loopbackPort.hh"/> - <FileResource projectRelativePath="09_test_configurations/0902_test_system_interface/Sem_0902_Communication_ports_002.ttcn" relativeURI="09_test_configurations/0902_test_system_interface/Sem_0902_Communication_ports_002.ttcn"/> -<FileResource projectRelativePath="09_test_configurations/0902_test_system_interface/loopbackPort1.cc" relativeURI="09_test_configurations/0902_test_system_interface/loopbackPort1.cc"/> - <FileResource projectRelativePath="09_test_configurations/0902_test_system_interface/loopbackPort1.hh" relativeURI="09_test_configurations/0902_test_system_interface/loopbackPort1.hh"/> + <FileResource projectRelativePath="09_test_configurations/0902_test_system_interface/Sem_0902_001_loopbackPort.cc" relativeURI="09_test_configurations/0902_test_system_interface/Sem_0902_001_loopbackPort.cc"/> + <FileResource projectRelativePath="09_test_configurations/0902_test_system_interface/Sem_0902_001_loopbackPort.hh" relativeURI="09_test_configurations/0902_test_system_interface/Sem_0902_001_loopbackPort.hh"/> + <FileResource projectRelativePath="09_test_configurations/0902_test_system_interface/Sem_0902_Communication_ports_002.ttcn" relativeURI="09_test_configurations/0902_test_system_interface/Sem_0902_Communication_ports_002.ttcn"/> + <FileResource projectRelativePath="09_test_configurations/0902_test_system_interface/Sem_0902_002_loopbackPort.cc" relativeURI="09_test_configurations/0902_test_system_interface/Sem_0902_002_loopbackPort.cc"/> + <FileResource projectRelativePath="09_test_configurations/0902_test_system_interface/Sem_0902_002_loopbackPort.hh" relativeURI="09_test_configurations/0902_test_system_interface/Sem_0902_002_loopbackPort.hh"/> <FileResource projectRelativePath="09_test_configurations/0902_test_system_interface/Syn_0902_Communication_ports_001.ttcn" relativeURI="09_test_configurations/0902_test_system_interface/Syn_0902_Communication_ports_001.ttcn"/> <!-- <FileResource projectRelativePath="10_constants/NegSem_10_Constants_001.ttcn" relativeURI="10_constants/NegSem_10_Constants_001.ttcn"/>--> <!-- <FileResource projectRelativePath="10_constants/NegSem_10_Constants_002.ttcn" relativeURI="10_constants/NegSem_10_Constants_002.ttcn"/>--> @@ -2198,8 +2198,12 @@ <!-- <FileResource projectRelativePath="16_functions_altsteps_testcases/1602_altsteps/160201_invoking_altsteps/NegSem_160201_invoking_altsteps_001.ttcn" relativeURI="16_functions_altsteps_testcases/1602_altsteps/160201_invoking_altsteps/NegSem_160201_invoking_altsteps_001.ttcn"/>--> <FileResource projectRelativePath="16_functions_altsteps_testcases/1602_altsteps/160201_invoking_altsteps/Sem_160201_invoking_altsteps_001.ttcn" relativeURI="16_functions_altsteps_testcases/1602_altsteps/160201_invoking_altsteps/Sem_160201_invoking_altsteps_001.ttcn"/> <FileResource projectRelativePath="16_functions_altsteps_testcases/1602_altsteps/160201_invoking_altsteps/Sem_160201_invoking_altsteps_002.ttcn" relativeURI="16_functions_altsteps_testcases/1602_altsteps/160201_invoking_altsteps/Sem_160201_invoking_altsteps_002.ttcn"/> -<!-- <FileResource projectRelativePath="16_functions_altsteps_testcases/1602_altsteps/160201_invoking_altsteps/Sem_160201_invoking_altsteps_003.ttcn" relativeURI="16_functions_altsteps_testcases/1602_altsteps/160201_invoking_altsteps/Sem_160201_invoking_altsteps_003.ttcn"/>--> -<!-- <FileResource projectRelativePath="16_functions_altsteps_testcases/1602_altsteps/160201_invoking_altsteps/Sem_160201_invoking_altsteps_004.ttcn" relativeURI="16_functions_altsteps_testcases/1602_altsteps/160201_invoking_altsteps/Sem_160201_invoking_altsteps_004.ttcn"/>--> + <FileResource projectRelativePath="16_functions_altsteps_testcases/1602_altsteps/160201_invoking_altsteps/Sem_160201_invoking_altsteps_003.ttcn" relativeURI="16_functions_altsteps_testcases/1602_altsteps/160201_invoking_altsteps/Sem_160201_invoking_altsteps_003.ttcn"/> + <FileResource projectRelativePath="16_functions_altsteps_testcases/1602_altsteps/160201_invoking_altsteps/Sem_160201_003_loopbackPort.cc" relativeURI="16_functions_altsteps_testcases/1602_altsteps/160201_invoking_altsteps/Sem_160201_003_loopbackPort.cc"/> + <FileResource projectRelativePath="16_functions_altsteps_testcases/1602_altsteps/160201_invoking_altsteps/Sem_160201_003_loopbackPort.hh" relativeURI="16_functions_altsteps_testcases/1602_altsteps/160201_invoking_altsteps/Sem_160201_003_loopbackPort.hh"/> + <FileResource projectRelativePath="16_functions_altsteps_testcases/1602_altsteps/160201_invoking_altsteps/Sem_160201_invoking_altsteps_004.ttcn" relativeURI="16_functions_altsteps_testcases/1602_altsteps/160201_invoking_altsteps/Sem_160201_invoking_altsteps_004.ttcn"/> + <FileResource projectRelativePath="16_functions_altsteps_testcases/1602_altsteps/160201_invoking_altsteps/Sem_160201_004_loopbackPort.cc" relativeURI="16_functions_altsteps_testcases/1602_altsteps/160201_invoking_altsteps/Sem_160201_004_loopbackPort.cc"/> + <FileResource projectRelativePath="16_functions_altsteps_testcases/1602_altsteps/160201_invoking_altsteps/Sem_160201_004_loopbackPort.hh" relativeURI="16_functions_altsteps_testcases/1602_altsteps/160201_invoking_altsteps/Sem_160201_004_loopbackPort.hh"/> <!-- <FileResource projectRelativePath="16_functions_altsteps_testcases/1602_altsteps/1602_toplevel/NegSem_1602_toplevel_001.ttcn" relativeURI="16_functions_altsteps_testcases/1602_altsteps/1602_toplevel/NegSem_1602_toplevel_001.ttcn"/>--> <!-- <FileResource projectRelativePath="16_functions_altsteps_testcases/1602_altsteps/1602_toplevel/xf_NegSem_1602_toplevel_001.cc" relativeURI="16_functions_altsteps_testcases/1602_altsteps/1602_toplevel/xf_NegSem_1602_toplevel_001.cc"/>--> <!-- <FileResource projectRelativePath="16_functions_altsteps_testcases/1602_altsteps/1602_toplevel/NegSem_1602_toplevel_002.ttcn" relativeURI="16_functions_altsteps_testcases/1602_altsteps/1602_toplevel/NegSem_1602_toplevel_002.ttcn"/>--> @@ -2304,8 +2308,12 @@ <FileResource projectRelativePath="20_statement_and_operations_for_alt/2002_the_alt_statement/Sem_2002_TheAltStatement_009.ttcn" relativeURI="20_statement_and_operations_for_alt/2002_the_alt_statement/Sem_2002_TheAltStatement_009.ttcn"/> <FileResource projectRelativePath="20_statement_and_operations_for_alt/2002_the_alt_statement/Sem_2002_TheAltStatement_010.ttcn" relativeURI="20_statement_and_operations_for_alt/2002_the_alt_statement/Sem_2002_TheAltStatement_010.ttcn"/> <FileResource projectRelativePath="20_statement_and_operations_for_alt/2002_the_alt_statement/Sem_2002_TheAltStatement_011.ttcn" relativeURI="20_statement_and_operations_for_alt/2002_the_alt_statement/Sem_2002_TheAltStatement_011.ttcn"/> -<!-- <FileResource projectRelativePath="20_statement_and_operations_for_alt/2002_the_alt_statement/Sem_2002_TheAltStatement_012.ttcn" relativeURI="20_statement_and_operations_for_alt/2002_the_alt_statement/Sem_2002_TheAltStatement_012.ttcn"/>--> -<!-- <FileResource projectRelativePath="20_statement_and_operations_for_alt/2002_the_alt_statement/Sem_2002_TheAltStatement_013.ttcn" relativeURI="20_statement_and_operations_for_alt/2002_the_alt_statement/Sem_2002_TheAltStatement_013.ttcn"/>--> + <FileResource projectRelativePath="20_statement_and_operations_for_alt/2002_the_alt_statement/Sem_2002_TheAltStatement_012.ttcn" relativeURI="20_statement_and_operations_for_alt/2002_the_alt_statement/Sem_2002_TheAltStatement_012.ttcn"/> + <FileResource projectRelativePath="20_statement_and_operations_for_alt/2002_the_alt_statement/Sem_2002_012_loopbackPort.cc" relativeURI="20_statement_and_operations_for_alt/2002_the_alt_statement/Sem_2002_012_loopbackPort.cc"/> + <FileResource projectRelativePath="20_statement_and_operations_for_alt/2002_the_alt_statement/Sem_2002_012_loopbackPort.hh" relativeURI="20_statement_and_operations_for_alt/2002_the_alt_statement/Sem_2002_012_loopbackPort.hh"/> + <FileResource projectRelativePath="20_statement_and_operations_for_alt/2002_the_alt_statement/Sem_2002_TheAltStatement_013.ttcn" relativeURI="20_statement_and_operations_for_alt/2002_the_alt_statement/Sem_2002_TheAltStatement_013.ttcn"/> + <FileResource projectRelativePath="20_statement_and_operations_for_alt/2002_the_alt_statement/Sem_2002_013_loopbackPort.cc" relativeURI="20_statement_and_operations_for_alt/2002_the_alt_statement/Sem_2002_013_loopbackPort.cc"/> + <FileResource projectRelativePath="20_statement_and_operations_for_alt/2002_the_alt_statement/Sem_2002_013_loopbackPort.hh" relativeURI="20_statement_and_operations_for_alt/2002_the_alt_statement/Sem_2002_013_loopbackPort.hh"/> <FileResource projectRelativePath="20_statement_and_operations_for_alt/2002_the_alt_statement/Sem_2002_TheAltStatement_014.ttcn" relativeURI="20_statement_and_operations_for_alt/2002_the_alt_statement/Sem_2002_TheAltStatement_014.ttcn"/> <!-- <FileResource projectRelativePath="20_statement_and_operations_for_alt/2003_the_repeat_statement/NegSem_2003_the_repeat_statement_001.ttcn" relativeURI="20_statement_and_operations_for_alt/2003_the_repeat_statement/NegSem_2003_the_repeat_statement_001.ttcn"/>--> <FileResource projectRelativePath="20_statement_and_operations_for_alt/2003_the_repeat_statement/Sem_2003_the_repeat_statement_001.ttcn" relativeURI="20_statement_and_operations_for_alt/2003_the_repeat_statement/Sem_2003_the_repeat_statement_001.ttcn"/> @@ -2386,10 +2394,10 @@ <FileResource projectRelativePath="21_configuration_operations/2101_connection_operations/210101_connect_and_map_operations/Sem_210101_connect_and_map_operations_002.ttcn" relativeURI="21_configuration_operations/2101_connection_operations/210101_connect_and_map_operations/Sem_210101_connect_and_map_operations_002.ttcn"/> <FileResource projectRelativePath="21_configuration_operations/2101_connection_operations/210101_connect_and_map_operations/Sem_210101_connect_and_map_operations_003.ttcn" relativeURI="21_configuration_operations/2101_connection_operations/210101_connect_and_map_operations/Sem_210101_connect_and_map_operations_003.ttcn"/> <FileResource projectRelativePath="21_configuration_operations/2101_connection_operations/210101_connect_and_map_operations/Sem_210101_connect_and_map_operations_004.ttcn" relativeURI="21_configuration_operations/2101_connection_operations/210101_connect_and_map_operations/Sem_210101_connect_and_map_operations_004.ttcn"/> -<!-- <FileResource projectRelativePath="21_configuration_operations/2101_connection_operations/210101_connect_and_map_operations/Sem_210101_connect_and_map_operations_005.ttcn" relativeURI="21_configuration_operations/2101_connection_operations/210101_connect_and_map_operations/Sem_210101_connect_and_map_operations_005.ttcn"/>--> -<!-- <FileResource projectRelativePath="21_configuration_operations/2101_connection_operations/210101_connect_and_map_operations/Sem_210101_connect_and_map_operations_006.ttcn" relativeURI="21_configuration_operations/2101_connection_operations/210101_connect_and_map_operations/Sem_210101_connect_and_map_operations_006.ttcn"/>--> -<!-- <FileResource projectRelativePath="21_configuration_operations/2101_connection_operations/210101_connect_and_map_operations/Sem_210101_connect_and_map_operations_007.ttcn" relativeURI="21_configuration_operations/2101_connection_operations/210101_connect_and_map_operations/Sem_210101_connect_and_map_operations_007.ttcn"/>--> -<!-- <FileResource projectRelativePath="21_configuration_operations/2101_connection_operations/210101_connect_and_map_operations/Sem_210101_connect_and_map_operations_008.ttcn" relativeURI="21_configuration_operations/2101_connection_operations/210101_connect_and_map_operations/Sem_210101_connect_and_map_operations_008.ttcn"/>--> + <FileResource projectRelativePath="21_configuration_operations/2101_connection_operations/210101_connect_and_map_operations/Sem_210101_connect_and_map_operations_005.ttcn" relativeURI="21_configuration_operations/2101_connection_operations/210101_connect_and_map_operations/Sem_210101_connect_and_map_operations_005.ttcn"/> + <FileResource projectRelativePath="21_configuration_operations/2101_connection_operations/210101_connect_and_map_operations/Sem_210101_connect_and_map_operations_006.ttcn" relativeURI="21_configuration_operations/2101_connection_operations/210101_connect_and_map_operations/Sem_210101_connect_and_map_operations_006.ttcn"/> + <FileResource projectRelativePath="21_configuration_operations/2101_connection_operations/210101_connect_and_map_operations/Sem_210101_connect_and_map_operations_007.ttcn" relativeURI="21_configuration_operations/2101_connection_operations/210101_connect_and_map_operations/Sem_210101_connect_and_map_operations_007.ttcn"/> + <FileResource projectRelativePath="21_configuration_operations/2101_connection_operations/210101_connect_and_map_operations/Sem_210101_connect_and_map_operations_008.ttcn" relativeURI="21_configuration_operations/2101_connection_operations/210101_connect_and_map_operations/Sem_210101_connect_and_map_operations_008.ttcn"/> <!-- <FileResource projectRelativePath="21_configuration_operations/2101_connection_operations/210101_connect_and_map_operations/Sem_210101_connect_and_map_operations_009.ttcn" relativeURI="21_configuration_operations/2101_connection_operations/210101_connect_and_map_operations/Sem_210101_connect_and_map_operations_009.ttcn"/>--> <!-- <FileResource projectRelativePath="21_configuration_operations/2101_connection_operations/210101_connect_and_map_operations/Sem_210101_connect_and_map_operations_010.ttcn" relativeURI="21_configuration_operations/2101_connection_operations/210101_connect_and_map_operations/Sem_210101_connect_and_map_operations_010.ttcn"/>--> <!-- <FileResource projectRelativePath="21_configuration_operations/2101_connection_operations/210102_disconnect_and_unmap_operations/NegSem_210102_disconnect_and_unmap_operations_001.ttcn" relativeURI="21_configuration_operations/2101_connection_operations/210102_disconnect_and_unmap_operations/NegSem_210102_disconnect_and_unmap_operations_001.ttcn"/>--> @@ -2407,7 +2415,7 @@ <!-- <FileResource projectRelativePath="21_configuration_operations/2101_connection_operations/210102_disconnect_and_unmap_operations/NegSem_210102_disconnect_and_unmap_operations_013.ttcn" relativeURI="21_configuration_operations/2101_connection_operations/210102_disconnect_and_unmap_operations/NegSem_210102_disconnect_and_unmap_operations_013.ttcn"/>--> <!-- <FileResource projectRelativePath="21_configuration_operations/2101_connection_operations/210102_disconnect_and_unmap_operations/NegSem_210102_disconnect_and_unmap_operations_014.ttcn" relativeURI="21_configuration_operations/2101_connection_operations/210102_disconnect_and_unmap_operations/NegSem_210102_disconnect_and_unmap_operations_014.ttcn"/>--> <!-- <FileResource projectRelativePath="21_configuration_operations/2101_connection_operations/210102_disconnect_and_unmap_operations/NegSem_210102_disconnect_operation_001.ttcn" relativeURI="21_configuration_operations/2101_connection_operations/210102_disconnect_and_unmap_operations/NegSem_210102_disconnect_operation_001.ttcn"/>--> -<!-- <FileResource projectRelativePath="21_configuration_operations/2101_connection_operations/210102_disconnect_and_unmap_operations/Sem_210102_disconnect_and_unmap_operations_001.ttcn" relativeURI="21_configuration_operations/2101_connection_operations/210102_disconnect_and_unmap_operations/Sem_210102_disconnect_and_unmap_operations_001.ttcn"/>--> + <FileResource projectRelativePath="21_configuration_operations/2101_connection_operations/210102_disconnect_and_unmap_operations/Sem_210102_disconnect_and_unmap_operations_001.ttcn" relativeURI="21_configuration_operations/2101_connection_operations/210102_disconnect_and_unmap_operations/Sem_210102_disconnect_and_unmap_operations_001.ttcn"/> <!-- <FileResource projectRelativePath="21_configuration_operations/2101_connection_operations/210102_disconnect_and_unmap_operations/Sem_210102_disconnect_and_unmap_operations_002.ttcn" relativeURI="21_configuration_operations/2101_connection_operations/210102_disconnect_and_unmap_operations/Sem_210102_disconnect_and_unmap_operations_002.ttcn"/>--> <!-- <FileResource projectRelativePath="21_configuration_operations/2101_connection_operations/210102_disconnect_and_unmap_operations/Sem_210102_disconnect_and_unmap_operations_003.ttcn" relativeURI="21_configuration_operations/2101_connection_operations/210102_disconnect_and_unmap_operations/Sem_210102_disconnect_and_unmap_operations_003.ttcn"/>--> <!-- <FileResource projectRelativePath="21_configuration_operations/2101_connection_operations/210102_disconnect_and_unmap_operations/Sem_210102_disconnect_and_unmap_operations_004.ttcn" relativeURI="21_configuration_operations/2101_connection_operations/210102_disconnect_and_unmap_operations/Sem_210102_disconnect_and_unmap_operations_004.ttcn"/>--> @@ -2421,9 +2429,9 @@ <!-- <FileResource projectRelativePath="21_configuration_operations/2101_connection_operations/210102_disconnect_and_unmap_operations/Sem_210102_disconnect_and_unmap_operations_012.ttcn" relativeURI="21_configuration_operations/2101_connection_operations/210102_disconnect_and_unmap_operations/Sem_210102_disconnect_and_unmap_operations_012.ttcn"/>--> <!-- <FileResource projectRelativePath="21_configuration_operations/2101_connection_operations/210102_disconnect_and_unmap_operations/Sem_210102_disconnect_and_unmap_operations_013.ttcn" relativeURI="21_configuration_operations/2101_connection_operations/210102_disconnect_and_unmap_operations/Sem_210102_disconnect_and_unmap_operations_013.ttcn"/>--> <!-- <FileResource projectRelativePath="21_configuration_operations/2101_connection_operations/210102_disconnect_and_unmap_operations/Sem_210102_disconnect_operation_001.ttcn" relativeURI="21_configuration_operations/2101_connection_operations/210102_disconnect_and_unmap_operations/Sem_210102_disconnect_operation_001.ttcn"/>--> -<!-- <FileResource projectRelativePath="21_configuration_operations/2101_connection_operations/210102_disconnect_and_unmap_operations/Sem_210102_disconnect_operation_002.ttcn" relativeURI="21_configuration_operations/2101_connection_operations/210102_disconnect_and_unmap_operations/Sem_210102_disconnect_operation_002.ttcn"/>--> -<!-- <FileResource projectRelativePath="21_configuration_operations/2101_connection_operations/210102_disconnect_and_unmap_operations/Sem_210102_unmap_operation_001.ttcn" relativeURI="21_configuration_operations/2101_connection_operations/210102_disconnect_and_unmap_operations/Sem_210102_unmap_operation_001.ttcn"/>--> -<!-- <FileResource projectRelativePath="21_configuration_operations/2101_connection_operations/210102_disconnect_and_unmap_operations/Sem_210102_unmap_operation_002.ttcn" relativeURI="21_configuration_operations/2101_connection_operations/210102_disconnect_and_unmap_operations/Sem_210102_unmap_operation_002.ttcn"/>--> + <FileResource projectRelativePath="21_configuration_operations/2101_connection_operations/210102_disconnect_and_unmap_operations/Sem_210102_disconnect_operation_002.ttcn" relativeURI="21_configuration_operations/2101_connection_operations/210102_disconnect_and_unmap_operations/Sem_210102_disconnect_operation_002.ttcn"/> + <FileResource projectRelativePath="21_configuration_operations/2101_connection_operations/210102_disconnect_and_unmap_operations/Sem_210102_unmap_operation_001.ttcn" relativeURI="21_configuration_operations/2101_connection_operations/210102_disconnect_and_unmap_operations/Sem_210102_unmap_operation_001.ttcn"/> + <FileResource projectRelativePath="21_configuration_operations/2101_connection_operations/210102_disconnect_and_unmap_operations/Sem_210102_unmap_operation_002.ttcn" relativeURI="21_configuration_operations/2101_connection_operations/210102_disconnect_and_unmap_operations/Sem_210102_unmap_operation_002.ttcn"/> <!-- <FileResource projectRelativePath="21_configuration_operations/2101_connection_operations/2101_toplevel/NegSem_2101_TopLevel_001.ttcn" relativeURI="21_configuration_operations/2101_connection_operations/2101_toplevel/NegSem_2101_TopLevel_001.ttcn"/>--> <!-- <FileResource projectRelativePath="21_configuration_operations/2101_connection_operations/2101_toplevel/NegSem_2101_TopLevel_002.ttcn" relativeURI="21_configuration_operations/2101_connection_operations/2101_toplevel/NegSem_2101_TopLevel_002.ttcn"/>--> <!-- <FileResource projectRelativePath="21_configuration_operations/2102_test_case_operations/NegSem_2102_testcase_stop_001.ttcn" relativeURI="21_configuration_operations/2102_test_case_operations/NegSem_2102_testcase_stop_001.ttcn"/>--> @@ -3333,7 +3341,7 @@ <!-- <FileResource projectRelativePath="B_matching_incoming_values/B01_template_matching/B0105_matching_character_pattern/B010506_case_sensitive_pattern_matching/Sem_B010506_case_sensitive_pattern_matching_002.ttcn" relativeURI="B_matching_incoming_values/B01_template_matching/B0105_matching_character_pattern/B010506_case_sensitive_pattern_matching/Sem_B010506_case_sensitive_pattern_matching_002.ttcn"/>--> <FileResource projectRelativePath="B_matching_incoming_values/B01_template_matching/B0105_matching_character_pattern/B0105_toplevel/Sem_B0105_toplevel_001.ttcn" relativeURI="B_matching_incoming_values/B01_template_matching/B0105_matching_character_pattern/B0105_toplevel/Sem_B0105_toplevel_001.ttcn"/> <FileResource projectRelativePath="B_matching_incoming_values/B01_template_matching/B0105_matching_character_pattern/B0105_toplevel/Sem_B0105_toplevel_002.ttcn" relativeURI="B_matching_incoming_values/B01_template_matching/B0105_matching_character_pattern/B0105_toplevel/Sem_B0105_toplevel_002.ttcn"/> -<!-- <FileResource projectRelativePath="C_predefined_functions/C06_Other_functions/C0602_The_testcasename_function/Sem_C0602_The_hostid_function_001.ttcn" relativeURI="C_predefined_functions/C06_Other_functions/C0602_The_testcasename_function/Sem_C0602_The_hostid_function_001.ttcn"/>--> + <FileResource projectRelativePath="C_predefined_functions/C06_Other_functions/C0602_The_testcasename_function/Sem_C0602_The_hostid_function_001.ttcn" relativeURI="C_predefined_functions/C06_Other_functions/C0602_The_testcasename_function/Sem_C0602_The_hostid_function_001.ttcn"/> <FileResource projectRelativePath="C_predefined_functions/C06_Other_functions/C0602_The_testcasename_function/Sem_C0602_The_testcasename_function_001.ttcn" relativeURI="C_predefined_functions/C06_Other_functions/C0602_The_testcasename_function/Sem_C0602_The_testcasename_function_001.ttcn"/> <FileResource projectRelativePath="D_preprocessing_macros/D01_macro_module/Sem_D01_macro_module_001.ttcn" relativeURI="D_preprocessing_macros/D01_macro_module/Sem_D01_macro_module_001.ttcn"/> <FileResource projectRelativePath="D_preprocessing_macros/D02_macro_file/Sem_D02_macro_file_001.ttcn" relativeURI="D_preprocessing_macros/D02_macro_file/Sem_D02_macro_file_001.ttcn"/> diff --git a/core/Communication.cc b/core/Communication.cc index db8fb8d35a8da6d9c9636e965a65467647354226..44352b934da5fda883bff31a369032e3957f7b3d 100644 --- a/core/Communication.cc +++ b/core/Communication.cc @@ -8,6 +8,7 @@ * Contributors: * Baji, Laszlo * Balasko, Jeno + * Baranyi, Botond * Beres, Szabolcs * Delic, Adam * Feher, Csaba @@ -1158,11 +1159,13 @@ void TTCN_Communication::send_debug_return_value(int return_type, const char* me Text_Buf text_buf; text_buf.push_int(MSG_DEBUG_RETURN_VALUE); text_buf.push_int(return_type); - timeval tv; - gettimeofday(&tv, NULL); - text_buf.push_int(tv.tv_sec); - text_buf.push_int(tv.tv_usec); - text_buf.push_string(message); + if (message != NULL) { + timeval tv; + gettimeofday(&tv, NULL); + text_buf.push_int(tv.tv_sec); + text_buf.push_int(tv.tv_usec); + text_buf.push_string(message); + } send_message(text_buf); } @@ -1173,6 +1176,21 @@ void TTCN_Communication::send_debug_halt_req() send_message(text_buf); } +void TTCN_Communication::send_debug_continue_req() +{ + Text_Buf text_buf; + text_buf.push_int(MSG_DEBUG_CONTINUE_REQ); + send_message(text_buf); +} + +void TTCN_Communication::send_debug_batch(const char* batch_file) +{ + Text_Buf text_buf; + text_buf.push_int(MSG_DEBUG_BATCH); + text_buf.push_string(batch_file); + send_message(text_buf); +} + boolean TTCN_Communication::send_log(time_t timestamp_sec, long timestamp_usec, unsigned int event_severity, size_t message_text_len, const char *message_text) diff --git a/core/Communication.hh b/core/Communication.hh index 1147128f8e09dc8b72b83e09e9d08e34ab26b0c4..3cf058ebff0e035ffca12d0c5b92b0c201246cbc 100644 --- a/core/Communication.hh +++ b/core/Communication.hh @@ -8,6 +8,7 @@ * Contributors: * Baji, Laszlo * Balasko, Jeno + * Baranyi, Botond * Beres, Szabolcs * Feher, Csaba * Forstner, Matyas @@ -149,6 +150,8 @@ public: static void send_debug_return_value(int return_type, const char* message); static void send_debug_halt_req(); + static void send_debug_continue_req(); + static void send_debug_batch(const char* batch_file); /** @brief Send a log message to the MC. diff --git a/core/DebugCommands.hh b/core/DebugCommands.hh index e5d569c559b840ca9bf18d5fd382c8dbd4d4f146..a2ed895dede3199370f9549814e16638a7da260b 100644 --- a/core/DebugCommands.hh +++ b/core/DebugCommands.hh @@ -17,46 +17,49 @@ /** list of commands coming from the user interface to the debugger (parameters listed in comments) */ // settings -#define D_SWITCH 1 // 1, "on" or "off" -#define D_ADD_BREAKPOINT 2 // 2, module name and line number -#define D_REMOVE_BREAKPOINT 3 // 2, module name and line number -#define D_SET_ERROR_BEHAVIOR 4 // 1, "yes" or "no" -#define D_SET_FAIL_BEHAVIOR 5 // 1, "yes" or "no" -#define D_SET_OUTPUT 6 // 1-2, "console", or "file" or "both" + file name +#define D_SWITCH 1 // 1, "on" or "off" +#define D_SET_BREAKPOINT 2 // 2-3, module name and line number + optional batch file name +#define D_REMOVE_BREAKPOINT 3 // 1-2, 'all', or module name + 'all' or line number +#define D_SET_AUTOMATIC_BREAKPOINT 4 // 2-3, "error" or "fail", + "off", or "on" + optional batch file name +#define D_SET_OUTPUT 5 // 1-2, "console", or "file" or "both", + file name +#define D_SET_GLOBAL_BATCH_FILE 6 // 1-2, "off", or "on" + batch file name // printing and overwriting data -#define D_SET_COMPONENT 7 // 1, "mtc" or component reference -#define D_PRINT_CALL_STACK 8 // 0 -#define D_SET_STACK_LEVEL 9 // 1, stack level -#define D_LIST_VARIABLES 10 // 1-2, "local", "global", "comp" or "all", + optional filter (pattern) -#define D_PRINT_VARIABLE 11 // 1+, list of variable names -#define D_OVERWRITE_VARIABLE 12 // 2, variable name, new value (in module parameter syntax) -#define D_PRINT_SNAPSHOTS 13 // 0 -#define D_SET_SNAPSHOT_BEHAVIOR 14 // TBD +#define D_SET_COMPONENT 7 // 1, "mtc" or component reference +#define D_PRINT_CALL_STACK 8 // 0 +#define D_SET_STACK_LEVEL 9 // 1, stack level +#define D_LIST_VARIABLES 10 // 1-2, "local", "global", "comp" or "all", + optional filter (pattern) +#define D_PRINT_VARIABLE 11 // 1+, list of variable names +#define D_OVERWRITE_VARIABLE 12 // 2, variable name, new value (in module parameter syntax) +#define D_PRINT_SNAPSHOTS 13 // 0 +#define D_SET_SNAPSHOT_BEHAVIOR 14 // TBD // stepping -#define D_STEP_OVER 15 // 0 -#define D_STEP_INTO 16 // 0 -#define D_STEP_OUT 17 // 0 -#define D_RUN_TO_CURSOR 18 // 2, module name and line number +#define D_STEP_OVER 15 // 0 +#define D_STEP_INTO 16 // 0 +#define D_STEP_OUT 17 // 0 +#define D_RUN_TO_CURSOR 18 // 2, module name and line number // the halted state -#define D_HALT 19 // 0 -#define D_CONTINUE 20 // 0 -#define D_EXIT 21 // 1, "test" or "all" -// batch files -#define D_BATCH 22 // 1, batch file name -#define D_SET_HALTING_BATCH_FILE 23 // 1-2, "no", or "yes" + batch file name +#define D_HALT 19 // 0 +#define D_CONTINUE 20 // 0 +#define D_EXIT 21 // 1, "test" or "all" // initialization -#define D_SETUP 24 // 5+, arguments for D_SWITCH, D_SET_OUTPUT, D_ERROR_BEHAVIOR, D_FAIL_BEHAVIOR + any number of D_ADD_BREAKPOINT arguments +#define D_SETUP 22 // 9+: + // 1 argument for D_SWITCH, + // 2 arguments for D_SET_OUTPUT, + // 2 arguments (2nd and 3rd) for D_SET_AUTOMATIC_BREAKPOINT, where the first argument is "error", + // 2 arguments (2nd and 3rd) for D_SET_AUTOMATIC_BREAKPOINT, where the first argument is "fail", + // 2 arguments for D_SET_GLOBAL_BATCH_FILE, + // + arguments for any number of D_SET_BREAKPOINT commands (optional) -#define D_ERROR 0 // any +#define D_ERROR 0 // any /** names of commands in the user interface */ #define D_SWITCH_TEXT "debug" -#define D_ADD_BREAKPOINT_TEXT "daddbp" +#define D_SET_BREAKPOINT_TEXT "dsetbp" #define D_REMOVE_BREAKPOINT_TEXT "drembp" -#define D_SET_ERROR_BEHAVIOR_TEXT "derrcfg" -#define D_SET_FAIL_BEHAVIOR_TEXT "dfailcfg" +#define D_SET_AUTOMATIC_BREAKPOINT_TEXT "dautobp" #define D_SET_OUTPUT_TEXT "doutput" +#define D_SET_GLOBAL_BATCH_FILE_TEXT "dglobbatch" #define D_SET_COMPONENT_TEXT "dcomp" #define D_PRINT_CALL_STACK_TEXT "dprintstack" #define D_SET_STACK_LEVEL_TEXT "dstacklevel" @@ -72,8 +75,6 @@ #define D_HALT_TEXT "dhalt" #define D_CONTINUE_TEXT "dcont" #define D_EXIT_TEXT "dexit" -#define D_BATCH_TEXT "dbatch" -#define D_SET_HALTING_BATCH_FILE_TEXT "dbatchcfg" /** debugger return value types */ diff --git a/core/Debugger.cc b/core/Debugger.cc index a5331cab477ff40bf6f13f508a70a23dc718a19e..5d5642508fbef1dd0c98f54c9d7156d2b788a703 100644 --- a/core/Debugger.cc +++ b/core/Debugger.cc @@ -15,6 +15,8 @@ #include "DebugCommands.hh" #include "Communication.hh" #include "../common/pattern.hh" +#include "Param_Types.hh" +#include "DebuggerUI.hh" #include <unistd.h> #include <pwd.h> @@ -45,82 +47,214 @@ void TTCN3_Debugger::switch_state(const char* p_state_str) } } else { - print(DRET_NOTIFICATION, "Argument 1 is invalid. Expected 'yes' or 'no'."); + print(DRET_NOTIFICATION, "Argument 1 is invalid. Expected 'on' or 'off'."); } } -void TTCN3_Debugger::add_breakpoint(const char* p_module, int p_line /*const char* batch_file*/) +void TTCN3_Debugger::set_breakpoint(const char* p_module, int p_line, + const char* batch_file) { - if (find_breakpoint(p_module, p_line) == breakpoints.size()) { + size_t pos = find_breakpoint(p_module, p_line); + if (pos == breakpoints.size()) { breakpoint_t bp; bp.module = mcopystr(p_module); bp.line = p_line; + bp.batch_file = batch_file != NULL ? mcopystr(batch_file) : NULL; breakpoints.push_back(bp); - print(DRET_SETTING_CHANGE, "Breakpoint added in module '%s' at line %d.", - p_module, p_line); + print(DRET_SETTING_CHANGE, "Breakpoint added in module '%s' at line %d%s%s%s.", + p_module, p_line, + batch_file != NULL ? " with batch file '" : " with no batch file", + batch_file != NULL ? batch_file : "", batch_file != NULL ? "'" : ""); } else { - print(DRET_NOTIFICATION, "Breakpoint already set in module '%s' at line %d.", - p_module, p_line); + if (breakpoints[pos].batch_file != NULL) { + if (batch_file != NULL) { + if (!strcmp(batch_file, breakpoints[pos].batch_file)) { + print(DRET_NOTIFICATION, "Breakpoint already set in module '%s' at " + "line %d with batch file '%s'.", + p_module, p_line, batch_file); + } + else { + print(DRET_SETTING_CHANGE, "Batch file was changed from '%s' to '%s' for " + "breakpoint in module '%s' at line %d.", breakpoints[pos].batch_file, + batch_file, p_module, p_line); + } + } + else { + print(DRET_SETTING_CHANGE, "Batch file '%s' removed from breakpoint in " + "module '%s' at line %d.", breakpoints[pos].batch_file, p_module, p_line); + } + Free(breakpoints[pos].batch_file); + } + else { + if (batch_file != NULL) { + print(DRET_SETTING_CHANGE, "Batch file '%s' added to breakpoint in module " + "'%s' at line %d.", batch_file, p_module, p_line); + } + else { + print(DRET_NOTIFICATION, "Breakpoint already set in module '%s' at line " + "%d with no batch file.", p_module, p_line); + } + } + breakpoints[pos].batch_file = batch_file != NULL ? mcopystr(batch_file) : NULL; } } -void TTCN3_Debugger::remove_breakpoint(const char* p_module, int p_line) +void TTCN3_Debugger::remove_breakpoint(const char* p_module, const char* p_line) { - size_t pos = find_breakpoint(p_module, p_line); - if (pos != breakpoints.size()) { - Free(breakpoints[pos].module); - breakpoints.erase_at(pos); - print(DRET_SETTING_CHANGE, "Breakpoint removed in module '%s' from line %d.", - p_module, p_line); + bool all_breakpoints = !strcmp(p_module, "all"); + if (p_line != NULL) { + if (!strcmp(p_line, "all")) { + bool found = false; + for (size_t i = breakpoints.size(); i > 0; --i) { + if (!strcmp(breakpoints[i - 1].module, p_module)) { + found = true; + Free(breakpoints[i - 1].module); + Free(breakpoints[i - 1].batch_file); + breakpoints.erase_at(i - 1); + } + } + if (found) { + print(DRET_SETTING_CHANGE, "Removed all breakpoints in module '%s'.", p_module); + } + else { + print(DRET_NOTIFICATION, "No breakpoints found in module '%s'.", p_module); + } + return; + } + else { + if (all_breakpoints) { + print(DRET_NOTIFICATION, "Unexpected 2nd argument, when the first " + "argument is 'all'."); + return; + } + size_t len = strlen(p_line); + for (size_t i = 0; i < len; ++i) { + if (p_line[i] < '0' || p_line[i] > '9') { + print(DRET_NOTIFICATION, "Argument 2 is invalid. Expected 'all' or " + "integer value (line number)."); + return; + } + } + long line = strtol(p_line, NULL, 10); + size_t pos = find_breakpoint(p_module, line); + if (pos != breakpoints.size()) { + Free(breakpoints[pos].module); + Free(breakpoints[pos].batch_file); + breakpoints.erase_at(pos); + print(DRET_SETTING_CHANGE, "Breakpoint removed in module '%s' from line %d.", + p_module, line); + } + else { + print(DRET_NOTIFICATION, "No breakpoint found in module '%s' at line %d.", + p_module, line); + } + return; + } + } + else if (!all_breakpoints) { + print(DRET_NOTIFICATION, "2 arguments expected, when the first argument is " + "not 'all'."); + return; + } + // delete all breakpoints if we got this far + if (breakpoints.empty()) { + print(DRET_NOTIFICATION, "No breakpoints found."); } else { - print(DRET_NOTIFICATION, "No breakpoint found in module '%s' at line %d.", - p_module, p_line); + for (size_t i = 0; i < breakpoints.size(); ++i) { + Free(breakpoints[i].module); + Free(breakpoints[i].batch_file); + } + breakpoints.clear(); + print(DRET_SETTING_CHANGE, "Removed all breakpoints."); } } -void TTCN3_Debugger::set_special_breakpoint(special_breakpoint_t p_type, const char* p_state_str) +void TTCN3_Debugger::set_automatic_breakpoint(const char* p_event_str, + const char* p_state_str, + const char* p_batch_file) { bool new_state; - if (!strcmp(p_state_str, "yes")) { + if (!strcmp(p_state_str, "on")) { new_state = true; } - else if(!strcmp(p_state_str, "no")) { + else if(!strcmp(p_state_str, "off")) { new_state = false; } - // else if "batch" else { - print(DRET_NOTIFICATION, "Argument 1 is invalid. Expected 'yes' or 'no'."); + print(DRET_NOTIFICATION, "Argument 2 is invalid. Expected 'on' or 'off'."); return; } const char* sbp_type_str; bool state_changed; - switch (p_type) { - case SBP_FAIL_VERDICT: - state_changed = (fail_behavior != new_state); - fail_behavior = new_state; - sbp_type_str = "Fail"; - break; - case SBP_ERROR_VERDICT: - state_changed = (error_behavior != new_state); - error_behavior = new_state; - sbp_type_str = "Error"; - break; - default: - // should never happen + char** old_batch_file_ptr; + if (!strcmp(p_event_str, "fail")) { + state_changed = (fail_behavior.trigger != new_state); + fail_behavior.trigger = new_state; + old_batch_file_ptr = &fail_behavior.batch_file; + sbp_type_str = "fail verdict"; + } + else if (!strcmp(p_event_str, "error")) { + state_changed = (error_behavior.trigger != new_state); + error_behavior.trigger = new_state; + old_batch_file_ptr = &error_behavior.batch_file; + sbp_type_str = "error verdict"; + } + else { + print(DRET_NOTIFICATION, "Argument 1 is invalid. Expected 'error' or 'fail'."); return; } - print(DRET_SETTING_CHANGE, "%s verdict behavior %sset to %s.", sbp_type_str, - state_changed ? "" : "was already ", - new_state ? "halt test execution" : "do nothing"); + if (state_changed) { + print(DRET_SETTING_CHANGE, "Automatic breakpoint at %s switched %s%s%s%s.", + sbp_type_str, new_state ? "on" : "off", + new_state ? (p_batch_file != NULL ? " with batch file '" : " with no batch file") : "", + (p_batch_file != NULL && new_state) ? p_batch_file : "", + (p_batch_file != NULL && new_state) ? "'" : ""); + } + else { + if (new_state) { + if (*old_batch_file_ptr != NULL) { + if (p_batch_file != NULL) { + if (!strcmp(p_batch_file, *old_batch_file_ptr)) { + print(DRET_NOTIFICATION, "Automatic breakpoint at %s was already " + "switched on with batch file '%s'.", sbp_type_str, p_batch_file); + } + else { + print(DRET_SETTING_CHANGE, "Batch file was changed from '%s' to '%s' " + "for automatic breakpoint at %s.", *old_batch_file_ptr, p_batch_file, + sbp_type_str); + } + } + else { + print(DRET_SETTING_CHANGE, "Batch file '%s' removed from automatic " + "breakpoint at %s.", *old_batch_file_ptr, sbp_type_str); + } + } + else { + if (p_batch_file != NULL) { + print(DRET_SETTING_CHANGE, "Batch file '%s' added to automatic breakpoint " + "at %s.", p_batch_file, sbp_type_str); + } + else { + print(DRET_NOTIFICATION, "Automatic breakpoint at %s was already " + "switched on with no batch file.", sbp_type_str); + } + } + } + else { + print(DRET_NOTIFICATION, "Automatic breakpoint at %s was already switched off."); + } + } + Free(*old_batch_file_ptr); + *old_batch_file_ptr = p_batch_file != NULL ? mcopystr(p_batch_file) : NULL; } void TTCN3_Debugger::print_call_stack() { for (size_t i = call_stack.size(); i != 0; --i) { add_to_result("%d.\t", (int)call_stack.size() - (int)i + 1); - call_stack[i - 1]->print_function(); + call_stack[i - 1].function->print_function(); if (i != 1) { add_to_result("\n"); } @@ -138,15 +272,69 @@ void TTCN3_Debugger::set_stack_level(int new_level) } else { stack_level = (int)call_stack.size() - new_level; - call_stack[stack_level]->print_function(); + call_stack[stack_level].function->print_function(); print(DRET_NOTIFICATION, "Stack level set to:\n%d.\t%s", new_level, command_result); + Free(command_result); + command_result = NULL; + } +} + +#define STACK_LEVEL (stack_level >= 0) ? (size_t)stack_level : (call_stack.size() - 1) + +void TTCN3_Debugger::print_variable(const char* p_var_name) +{ + const variable_t* var = call_stack[STACK_LEVEL].function->find_variable(p_var_name); + if (var != NULL) { + add_to_result("[%s] %s := %s", var->type_name, var->name, + (const char*)var->print_function(*var)); + } + else { + add_to_result("Variable '%s' not found.", p_var_name); } } -void TTCN3_Debugger::print_variable(const TTCN3_Debugger::variable_t* p_var) +void TTCN3_Debugger::overwrite_variable(const char* p_var_name, + int p_value_element_count, + char** p_value_elements) { - add_to_result("[%s] %s := %s", p_var->type_name, p_var->name, - (const char*)p_var->print_function(*p_var)); + variable_t* var = call_stack[STACK_LEVEL].function->find_variable(p_var_name); + if (var != NULL) { + if (var->set_function == NULL) { + print(DRET_NOTIFICATION, "Constant variables cannot be overwritten."); + } + else { + char* new_value_str = NULL; + for (int i = 0; i < p_value_element_count; ++i) { + if (i != 0) { + new_value_str = mputc(new_value_str, ' '); + } + new_value_str = mputstr(new_value_str, p_value_elements[i]); + } + Module_Param* parsed_mp = process_config_debugger_value(new_value_str); + // an error message has already been displayed if parsed_mp is NULL + if (parsed_mp != NULL) { + try { + Debugger_Value_Parsing debug_value_parsing; + boolean handled = var->set_function(*var, *parsed_mp); + if (!handled) { + print(DRET_NOTIFICATION, "Variables of type '%s' cannot be overwritten.", + var->type_name); + } + else { + add_to_result("[%s] %s := %s", var->type_name, var->name, + (const char*)var->print_function(*var)); + } + } + catch (const TC_Error&) { + // do nothing, an error message has already been displayed in this case + } + delete parsed_mp; + } + } + } + else { + print(DRET_NOTIFICATION, "Variable '%s' not found.", p_var_name); + } } void TTCN3_Debugger::set_output(const char* p_output_type, const char* p_file_name) @@ -182,18 +370,18 @@ void TTCN3_Debugger::set_output(const char* p_output_type, const char* p_file_na same_file = true; } else if (!TTCN_Runtime::is_hc()) { - // don't open any files on HCs, just store settings for future PTCs + // don't open any files on HCs, just store settings for future PTCs final_file_name = finalize_file_name(p_file_name); - new_fp = fopen(final_file_name, "w"); + new_fp = fopen(final_file_name, TTCN_Runtime::is_mtc() ? "w" : "a"); if (new_fp == NULL) { print(DRET_NOTIFICATION, "Failed to open file '%s' for writing.", final_file_name); + Free(final_file_name); return; } } } // print the change notification to the old output - char* file_str = file ? mprintf("file '%s'", TTCN_Runtime::is_hc() ? p_file_name - : final_file_name) : NULL; + char* file_str = file ? mprintf("file '%s'", final_file_name) : NULL; Free(final_file_name); print(DRET_SETTING_CHANGE, "Debugger set to print its output to %s%s%s.", console ? "the console" : "", (console && file) ? " and to " : "", @@ -214,13 +402,124 @@ void TTCN3_Debugger::set_output(const char* p_output_type, const char* p_file_na } } -void TTCN3_Debugger::halt() +void TTCN3_Debugger::set_global_batch_file(const char* p_state_str, + const char* p_file_name) +{ + bool delete_old = false; + bool copy_new = false; + if (!strcmp(p_state_str, "on")) { + if (p_file_name != NULL) { + if (global_batch_file != NULL) { + if (!strcmp(p_file_name, global_batch_file)) { + print(DRET_NOTIFICATION, "Global batch file was already switched on " + "and set to '%s'.", p_file_name); + } + else { + print(DRET_SETTING_CHANGE, "Global batch file changed from '%s' to '%s'.", + global_batch_file, p_file_name); + delete_old = true; + copy_new = true; + } + } + else { + print(DRET_SETTING_CHANGE, "Global batch file switched on and set to '%s'.", + p_file_name); + copy_new = true; + } + } + else { + print(DRET_NOTIFICATION, "Missing batch file name argument."); + } + } + else if (!strcmp(p_state_str, "off")) { + if (global_batch_file != NULL) { + print(DRET_SETTING_CHANGE, "Global batch file switched off."); + delete_old = true; + } + else { + print(DRET_NOTIFICATION, "Global batch file was already switched off."); + } + } + else { + print(DRET_NOTIFICATION, "Argument 1 is invalid. Expected 'on' or 'off'."); + } + if (delete_old) { + Free(global_batch_file); + global_batch_file = NULL; + } + if (copy_new) { + global_batch_file = mcopystr(p_file_name); + } +} + +void TTCN3_Debugger::step(stepping_t p_stepping_type) +{ + if (!halted) { + print(DRET_NOTIFICATION, "Stepping commands can only be used when test " + "execution is halted."); + return; + } + stepping_type = p_stepping_type; + stepping_stack_size = call_stack.size(); + if (!TTCN_Runtime::is_single()) { + TTCN_Communication::send_debug_continue_req(); + } + resume(); +} + +void TTCN3_Debugger::run_to_cursor(const char* p_module, int p_line) +{ + // all processes receive this command, since the specified location might be + // reached in any process, even a PTC that hasn't been created yet + if (!halted) { + print(DRET_NOTIFICATION, "The 'run to' command can only be used when test " + "execution is halted."); + return; + } + temporary_breakpoint.module = mcopystr(p_module); + temporary_breakpoint.line = p_line; + resume(); +} + +void TTCN3_Debugger::halt(const char* p_batch_file, bool p_run_global_batch) { if (!halted) { halted = true; - stack_level = call_stack.size() - 1; - print(DRET_NOTIFICATION, "Test execution halted."); - TTCN_Communication::process_debug_messages(); + Free(temporary_breakpoint.module); + temporary_breakpoint.module = NULL; + temporary_breakpoint.line = 0; + if (!TTCN_Runtime::is_hc()) { + stepping_type = NOT_STEPPING; + stack_level = call_stack.size() - 1; + print(DRET_NOTIFICATION, "Test execution halted."); + if (p_batch_file != NULL) { + if (TTCN_Runtime::is_single()) { + TTCN_Debugger_UI::execute_batch_file(p_batch_file); + } + else { + TTCN_Communication::send_debug_batch(p_batch_file); + } + } + else if (p_run_global_batch && global_batch_file != NULL) { + if (TTCN_Runtime::is_single()) { + TTCN_Debugger_UI::execute_batch_file(global_batch_file); + } + else { + TTCN_Communication::send_debug_batch(global_batch_file); + } + } + if (TTCN_Runtime::is_single()) { + if (halted && !halt_at_start) { + resume(); + } + else { + TTCN_Debugger_UI::read_loop(); + } + } + else { + TTCN_Communication::process_debug_messages(); + } + } } else { print(DRET_NOTIFICATION, "Test execution is already halted."); @@ -241,21 +540,22 @@ void TTCN3_Debugger::resume() void TTCN3_Debugger::exit_(const char* p_what) { - bool exit_all; if (!strcmp(p_what, "test")) { - exit_all = false; + exiting = false; } else if (!strcmp(p_what, "all")) { - exit_all = true; + exiting = true; } else { print(DRET_NOTIFICATION, "Argument 1 is invalid. Expected 'test' or 'all'."); return; } halted = false; - print((exit_all && TTCN_Runtime::is_mtc()) ? DRET_EXIT_ALL : DRET_NOTIFICATION, - "Exiting %s.", exit_all ? "test execution" : "current test"); - TTCN_Runtime::stop_execution(); + if (!TTCN_Runtime::is_hc()) { + print((exiting && TTCN_Runtime::is_mtc()) ? DRET_EXIT_ALL : DRET_NOTIFICATION, + "Exiting %s.", exiting ? "test execution" : "current test"); + TTCN_Runtime::stop_execution(); + } } size_t TTCN3_Debugger::find_breakpoint(const char* p_module, int p_line) const @@ -343,15 +643,58 @@ char* TTCN3_Debugger::finalize_file_name(const char* p_file_name_skeleton) return ret_val; } +void TTCN3_Debugger::test_execution_started() +{ + Free(snapshots); + snapshots = NULL; + exiting = false; + if (TTCN_Runtime::is_single()) { + TTCN_Debugger_UI::init(); + if (initial_batch_file) { + halt(initial_batch_file, false); + } + else if (halt_at_start) { + halt(NULL, false); + } + } + halt_at_start = false; +} + +void TTCN3_Debugger::test_execution_finished() +{ + stepping_type = NOT_STEPPING; + Free(temporary_breakpoint.module); + temporary_breakpoint.module = NULL; + temporary_breakpoint.line = 0; + last_breakpoint_entry.module = NULL; + last_breakpoint_entry.line = 0; + if (TTCN_Runtime::is_single()) { + TTCN_Debugger_UI::clean_up(); + } +} + void TTCN3_Debugger::print(int return_type, const char* fmt, ...) const { + if (TTCN_Runtime::is_hc()) { + // don't display anything while on the HC process + return; + } va_list parameters; va_start(parameters, fmt); char* str = mprintf_va_list(fmt, parameters); va_end(parameters); - TTCN_Communication::send_debug_return_value(return_type, send_to_console ? str : NULL); + if (TTCN_Runtime::is_single()) { + if (send_to_console) { + TTCN_Debugger_UI::print(str); + } + } + else { + TTCN_Communication::send_debug_return_value(return_type, send_to_console ? str : NULL); + } if (output_file != NULL) { - fprintf(output_file, "%s\n", str); + fseek(output_file, 0, SEEK_END); // in case multiple processes are writing the same file + fputs(str, output_file); + fputc('\n', output_file); fflush(output_file); } Free(str); @@ -368,10 +711,23 @@ TTCN3_Debugger::TTCN3_Debugger() snapshots = NULL; last_breakpoint_entry.module = NULL; last_breakpoint_entry.line = 0; + last_breakpoint_entry.batch_file = NULL; // not used stack_level = -1; - fail_behavior = false; - error_behavior = false; + fail_behavior.trigger = false; + fail_behavior.batch_file = NULL; + error_behavior.trigger = false; + error_behavior.batch_file = NULL; + global_batch_file = NULL; command_result = NULL; + last_variable_list = NULL; + stepping_type = NOT_STEPPING; + stepping_stack_size = 0; + temporary_breakpoint.module = NULL; + temporary_breakpoint.line = 0; + temporary_breakpoint.batch_file = NULL; // not used + exiting = false; + halt_at_start = false; + initial_batch_file = NULL; } TTCN3_Debugger::~TTCN3_Debugger() @@ -382,6 +738,7 @@ TTCN3_Debugger::~TTCN3_Debugger() } for (size_t i = 0; i < breakpoints.size(); ++i) { Free(breakpoints[i].module); + Free(breakpoints[i].batch_file); } for (size_t i = 0; i < global_scopes.size(); ++i) { delete global_scopes[i].scope; @@ -392,8 +749,11 @@ TTCN3_Debugger::~TTCN3_Debugger() for (size_t i = 0; i < variables.size(); ++i) { delete variables[i]; } + Free(fail_behavior.batch_file); + Free(error_behavior.batch_file); + Free(global_batch_file); Free(snapshots); - Free(command_result); + Free(last_variable_list); } TTCN3_Debug_Scope* TTCN3_Debugger::add_global_scope(const char* p_module) @@ -417,42 +777,69 @@ TTCN3_Debug_Scope* TTCN3_Debugger::add_component_scope(const char* p_component) void TTCN3_Debugger::set_return_value(const CHARSTRING& p_value) { if (active && !call_stack.empty()) { - call_stack[call_stack.size() - 1]->set_return_value(p_value); + call_stack[call_stack.size() - 1].function->set_return_value(p_value); } } -void TTCN3_Debugger::breakpoint_entry(int p_line /*bool p_stepping_helper*/) +void TTCN3_Debugger::breakpoint_entry(int p_line) { if (active && !call_stack.empty()) { - const char* module_name = call_stack[call_stack.size() - 1]->get_module_name(); + const char* module_name = call_stack[call_stack.size() - 1].function->get_module_name(); bool trigger = false; const char* trigger_type; int actual_line; + const char* batch_file = NULL; switch (p_line) { case SBP_FAIL_VERDICT: - trigger = fail_behavior; - trigger_type = "Automatic breakpoint (fail verdict)"; - actual_line = last_breakpoint_entry.line; + trigger = fail_behavior.trigger; + trigger_type = "Automatic breakpoint (fail verdict) reached at"; + actual_line = TTCN_Location::get_line_number(); + batch_file = fail_behavior.batch_file; break; case SBP_ERROR_VERDICT: - trigger = error_behavior; - trigger_type = "Automatic breakpoint (error verdict)"; - actual_line = last_breakpoint_entry.line; + trigger = error_behavior.trigger; + trigger_type = "Automatic breakpoint (error verdict) reached at"; + actual_line = TTCN_Location::get_line_number(); + batch_file = error_behavior.batch_file; break; default: // code lines - // make sure it's not the same breakpoint entry as last time - trigger = (last_breakpoint_entry.line == 0 || p_line != last_breakpoint_entry.line || - module_name != last_breakpoint_entry.module) && - find_breakpoint(module_name, p_line) != breakpoints.size(); - trigger_type = "User breakpoint"; + // first: make sure it's not the same breakpoint entry as last time + if (p_line == last_breakpoint_entry.line && + module_name == last_breakpoint_entry.module) { + break; + } actual_line = p_line; + // second: check if a stepping operation ends here + if (stepping_type == STEP_INTO || + (stepping_type == STEP_OVER && call_stack.size() <= stepping_stack_size) || + (stepping_type == STEP_OUT && call_stack.size() < stepping_stack_size)) { + trigger = true; + trigger_type = "Stepped to"; + break; + } + // third: check if this is the destination of a 'run to cursor' operation + if (p_line == temporary_breakpoint.line && + !strcmp(module_name, temporary_breakpoint.module)) { + trigger = true; + trigger_type = "Ran to"; + break; + } + // fourth: check if the location matches one of the breakpoints in the list + size_t pos = find_breakpoint(module_name, p_line); + if (pos != breakpoints.size()) { + trigger = true; + batch_file = breakpoints[pos].batch_file; + } + trigger_type = "User breakpoint reached at"; break; } if (trigger) { - print(DRET_NOTIFICATION, "%s reached in module '%s' at line %d.", - trigger_type, module_name, actual_line); - TTCN_Communication::send_debug_halt_req(); - halt(); + print(DRET_NOTIFICATION, "%s line %d in module '%s'.", + trigger_type, actual_line, module_name); + if (!TTCN_Runtime::is_single()) { + TTCN_Communication::send_debug_halt_req(); + } + halt(batch_file, true); } last_breakpoint_entry.module = (char*)module_name; last_breakpoint_entry.line = p_line; @@ -461,105 +848,106 @@ void TTCN3_Debugger::breakpoint_entry(int p_line /*bool p_stepping_helper*/) CHARSTRING TTCN3_Debugger::print_base_var(const TTCN3_Debugger::variable_t& p_var) { + const void* ptr = p_var.set_function != NULL ? p_var.value : p_var.cvalue; TTCN_Logger::begin_event_log2str(); if (!strcmp(p_var.type_name, "bitstring")) { - ((const BITSTRING*)p_var.value)->log(); + ((const BITSTRING*)ptr)->log(); } else if (!strcmp(p_var.type_name, "bitstring template")) { - ((const BITSTRING_template*)p_var.value)->log(); + ((const BITSTRING_template*)ptr)->log(); } else if (!strcmp(p_var.type_name, "boolean")) { - ((const BOOLEAN*)p_var.value)->log(); + ((const BOOLEAN*)ptr)->log(); } else if (!strcmp(p_var.type_name, "boolean template")) { - ((const BOOLEAN_template*)p_var.value)->log(); + ((const BOOLEAN_template*)ptr)->log(); } else if (!strcmp(p_var.type_name, "charstring")) { - ((const CHARSTRING*)p_var.value)->log(); + ((const CHARSTRING*)ptr)->log(); } else if (!strcmp(p_var.type_name, "charstring template")) { - ((const CHARSTRING_template*)p_var.value)->log(); + ((const CHARSTRING_template*)ptr)->log(); } else if (!strcmp(p_var.type_name, "float")) { - ((const FLOAT*)p_var.value)->log(); + ((const FLOAT*)ptr)->log(); } else if (!strcmp(p_var.type_name, "float template")) { - ((const FLOAT_template*)p_var.value)->log(); + ((const FLOAT_template*)ptr)->log(); } else if (!strcmp(p_var.type_name, "hexstring")) { - ((const HEXSTRING*)p_var.value)->log(); + ((const HEXSTRING*)ptr)->log(); } else if (!strcmp(p_var.type_name, "hexstring template")) { - ((const HEXSTRING_template*)p_var.value)->log(); + ((const HEXSTRING_template*)ptr)->log(); } else if (!strcmp(p_var.type_name, "integer")) { - ((const INTEGER*)p_var.value)->log(); + ((const INTEGER*)ptr)->log(); } else if (!strcmp(p_var.type_name, "integer template")) { - ((const INTEGER_template*)p_var.value)->log(); + ((const INTEGER_template*)ptr)->log(); } else if (!strcmp(p_var.type_name, "objid")) { - ((const OBJID*)p_var.value)->log(); + ((const OBJID*)ptr)->log(); } else if (!strcmp(p_var.type_name, "objid template")) { - ((const OBJID_template*)p_var.value)->log(); + ((const OBJID_template*)ptr)->log(); } else if (!strcmp(p_var.type_name, "octetstring")) { - ((const OCTETSTRING*)p_var.value)->log(); + ((const OCTETSTRING*)ptr)->log(); } else if (!strcmp(p_var.type_name, "octetstring template")) { - ((const OCTETSTRING_template*)p_var.value)->log(); + ((const OCTETSTRING_template*)ptr)->log(); } else if (!strcmp(p_var.type_name, "universal charstring")) { - ((const UNIVERSAL_CHARSTRING*)p_var.value)->log(); + ((const UNIVERSAL_CHARSTRING*)ptr)->log(); } else if (!strcmp(p_var.type_name, "universal charstring template")) { - ((const UNIVERSAL_CHARSTRING_template*)p_var.value)->log(); + ((const UNIVERSAL_CHARSTRING_template*)ptr)->log(); } else if (!strcmp(p_var.type_name, "verdicttype")) { - ((const VERDICTTYPE*)p_var.value)->log(); + ((const VERDICTTYPE*)ptr)->log(); } else if (!strcmp(p_var.type_name, "verdicttype template")) { - ((const VERDICTTYPE_template*)p_var.value)->log(); + ((const VERDICTTYPE_template*)ptr)->log(); } else if (!strcmp(p_var.type_name, "component")) { - ((const COMPONENT*)p_var.value)->log(); + ((const COMPONENT*)ptr)->log(); } else if (!strcmp(p_var.type_name, "component template")) { - ((const COMPONENT_template*)p_var.value)->log(); + ((const COMPONENT_template*)ptr)->log(); } else if (!strcmp(p_var.type_name, "default")) { - ((const DEFAULT*)p_var.value)->log(); + ((const DEFAULT*)ptr)->log(); } else if (!strcmp(p_var.type_name, "default template")) { - ((const DEFAULT_template*)p_var.value)->log(); + ((const DEFAULT_template*)ptr)->log(); } else if (!strcmp(p_var.type_name, "timer")) { - ((const TIMER*)p_var.value)->log(); + ((const TIMER*)ptr)->log(); } else if (!strcmp(p_var.type_name, "NULL")) { - ((const ASN_NULL*)p_var.value)->log(); + ((const ASN_NULL*)ptr)->log(); } else if (!strcmp(p_var.type_name, "NULL template")) { - ((const ASN_NULL_template*)p_var.value)->log(); + ((const ASN_NULL_template*)ptr)->log(); } else if (!strcmp(p_var.type_name, "CHARACTER STRING")) { - ((const CHARACTER_STRING*)p_var.value)->log(); + ((const CHARACTER_STRING*)ptr)->log(); } else if (!strcmp(p_var.type_name, "CHARACTER STRING template")) { - ((const CHARACTER_STRING_template*)p_var.value)->log(); + ((const CHARACTER_STRING_template*)ptr)->log(); } else if (!strcmp(p_var.type_name, "EMBEDDED PDV")) { - ((const EMBEDDED_PDV*)p_var.value)->log(); + ((const EMBEDDED_PDV*)ptr)->log(); } else if (!strcmp(p_var.type_name, "EMBEDDED PDV template")) { - ((const EMBEDDED_PDV_template*)p_var.value)->log(); + ((const EMBEDDED_PDV_template*)ptr)->log(); } else if (!strcmp(p_var.type_name, "EXTERNAL")) { - ((const EXTERNAL*)p_var.value)->log(); + ((const EXTERNAL*)ptr)->log(); } else if (!strcmp(p_var.type_name, "EXTERNAL template")) { - ((const EXTERNAL_template*)p_var.value)->log(); + ((const EXTERNAL_template*)ptr)->log(); } else { TTCN_Logger::log_event_str("<unrecognized value or template>"); @@ -567,6 +955,110 @@ CHARSTRING TTCN3_Debugger::print_base_var(const TTCN3_Debugger::variable_t& p_va return TTCN_Logger::end_event_log2str(); } +boolean TTCN3_Debugger::set_base_var(variable_t& p_var, Module_Param& p_new_value) +{ + if (!strcmp(p_var.type_name, "bitstring")) { + ((BITSTRING*)p_var.value)->set_param(p_new_value); + } + else if (!strcmp(p_var.type_name, "bitstring template")) { + ((BITSTRING_template*)p_var.value)->set_param(p_new_value); + } + else if (!strcmp(p_var.type_name, "boolean")) { + ((BOOLEAN*)p_var.value)->set_param(p_new_value); + } + else if (!strcmp(p_var.type_name, "boolean template")) { + ((BOOLEAN_template*)p_var.value)->set_param(p_new_value); + } + else if (!strcmp(p_var.type_name, "charstring")) { + ((CHARSTRING*)p_var.value)->set_param(p_new_value); + } + else if (!strcmp(p_var.type_name, "charstring template")) { + ((CHARSTRING_template*)p_var.value)->set_param(p_new_value); + } + else if (!strcmp(p_var.type_name, "float")) { + ((FLOAT*)p_var.value)->set_param(p_new_value); + } + else if (!strcmp(p_var.type_name, "float template")) { + ((FLOAT_template*)p_var.value)->set_param(p_new_value); + } + else if (!strcmp(p_var.type_name, "hexstring")) { + ((HEXSTRING*)p_var.value)->set_param(p_new_value); + } + else if (!strcmp(p_var.type_name, "hexstring template")) { + ((HEXSTRING_template*)p_var.value)->set_param(p_new_value); + } + else if (!strcmp(p_var.type_name, "integer")) { + ((INTEGER*)p_var.value)->set_param(p_new_value); + } + else if (!strcmp(p_var.type_name, "integer template")) { + ((INTEGER_template*)p_var.value)->set_param(p_new_value); + } + else if (!strcmp(p_var.type_name, "objid")) { + ((OBJID*)p_var.value)->set_param(p_new_value); + } + else if (!strcmp(p_var.type_name, "objid template")) { + ((OBJID_template*)p_var.value)->set_param(p_new_value); + } + else if (!strcmp(p_var.type_name, "octetstring")) { + ((OCTETSTRING*)p_var.value)->set_param(p_new_value); + } + else if (!strcmp(p_var.type_name, "octetstring template")) { + ((OCTETSTRING_template*)p_var.value)->set_param(p_new_value); + } + else if (!strcmp(p_var.type_name, "universal charstring")) { + ((UNIVERSAL_CHARSTRING*)p_var.value)->set_param(p_new_value); + } + else if (!strcmp(p_var.type_name, "universal charstring template")) { + ((UNIVERSAL_CHARSTRING_template*)p_var.value)->set_param(p_new_value); + } + else if (!strcmp(p_var.type_name, "verdicttype")) { + ((VERDICTTYPE*)p_var.value)->set_param(p_new_value); + } + else if (!strcmp(p_var.type_name, "verdicttype template")) { + ((VERDICTTYPE_template*)p_var.value)->set_param(p_new_value); + } + else if (!strcmp(p_var.type_name, "component")) { + ((COMPONENT*)p_var.value)->set_param(p_new_value); + } + else if (!strcmp(p_var.type_name, "component template")) { + ((COMPONENT_template*)p_var.value)->set_param(p_new_value); + } + else if (!strcmp(p_var.type_name, "default")) { + ((DEFAULT*)p_var.value)->set_param(p_new_value); + } + else if (!strcmp(p_var.type_name, "default template")) { + ((DEFAULT_template*)p_var.value)->set_param(p_new_value); + } + else if (!strcmp(p_var.type_name, "NULL")) { + ((ASN_NULL*)p_var.value)->set_param(p_new_value); + } + else if (!strcmp(p_var.type_name, "NULL template")) { + ((ASN_NULL_template*)p_var.value)->set_param(p_new_value); + } + else if (!strcmp(p_var.type_name, "CHARACTER STRING")) { + ((CHARACTER_STRING*)p_var.value)->set_param(p_new_value); + } + else if (!strcmp(p_var.type_name, "CHARACTER STRING template")) { + ((CHARACTER_STRING_template*)p_var.value)->set_param(p_new_value); + } + else if (!strcmp(p_var.type_name, "EMBEDDED PDV")) { + ((EMBEDDED_PDV*)p_var.value)->set_param(p_new_value); + } + else if (!strcmp(p_var.type_name, "EMBEDDED PDV template")) { + ((EMBEDDED_PDV_template*)p_var.value)->set_param(p_new_value); + } + else if (!strcmp(p_var.type_name, "EXTERNAL")) { + ((EXTERNAL*)p_var.value)->set_param(p_new_value); + } + else if (!strcmp(p_var.type_name, "EXTERNAL template")) { + ((EXTERNAL_template*)p_var.value)->set_param(p_new_value); + } + else { + return FALSE; + } + return TRUE; +} + void TTCN3_Debugger::add_to_result(const char* fmt, ...) { va_list parameters; @@ -577,36 +1069,87 @@ void TTCN3_Debugger::add_to_result(const char* fmt, ...) void TTCN3_Debugger::add_function(TTCN3_Debug_Function* p_function) { - if (active) { - call_stack.push_back(p_function); + function_call_t function_call; + if (call_stack.empty()) { + test_execution_started(); + function_call.caller_line = 0; + } + else { + function_call.caller_line = last_breakpoint_entry.line; } + function_call.function = p_function; + call_stack.push_back(function_call); } void TTCN3_Debugger::add_scope(TTCN3_Debug_Scope* p_scope) { if (active && !call_stack.empty()) { - call_stack[call_stack.size() - 1]->add_scope(p_scope); + call_stack[call_stack.size() - 1].function->add_scope(p_scope); } } void TTCN3_Debugger::remove_function(TTCN3_Debug_Function* p_function) { - if (!call_stack.empty() && call_stack[call_stack.size() - 1] == p_function) { + if (!call_stack.empty() && call_stack[call_stack.size() - 1].function == p_function) { + bool removing_test_case = call_stack[call_stack.size() - 1].function->is_test_case(); + int caller_line = call_stack[call_stack.size() - 1].caller_line; call_stack.erase_at(call_stack.size() - 1); + if (call_stack.empty()) { + test_execution_finished(); + } + if (caller_line != 0 && (stepping_type == STEP_INTO || stepping_type == STEP_OUT || + (stepping_type == STEP_OVER && call_stack.size() != stepping_stack_size))) { + breakpoint_entry(caller_line); + } + if (exiting && TTCN_Runtime::is_single() && !call_stack.empty() && removing_test_case && + call_stack[call_stack.size() - 1].function->is_control_part()) { + // 'exit all' was requested while executing a test case called by a control + // part, which means the test case caught the original TC_End exception; + // another exception must be thrown to stop the control part, too + throw TC_End(); + } } } void TTCN3_Debugger::remove_scope(TTCN3_Debug_Scope* p_scope) { if (!call_stack.empty()) { - call_stack[call_stack.size() - 1]->remove_scope(p_scope); + call_stack[call_stack.size() - 1].function->remove_scope(p_scope); } } -const TTCN3_Debugger::variable_t* TTCN3_Debugger::add_variable(const void* p_value, - const char* p_name, - const char* p_type, - CHARSTRING (*p_print_function)(const TTCN3_Debugger::variable_t&)) +TTCN3_Debugger::variable_t* TTCN3_Debugger::add_variable(const void* p_value, + const char* p_name, + const char* p_type, + TTCN3_Debugger::print_function_t p_print_function) +{ + if (call_stack.empty()) { + // no call stack yet, so this is a global or component variable + variable_t* var = find_variable(p_value); + if (var == NULL) { + var = new TTCN3_Debugger::variable_t; + var->cvalue = p_value; + var->name = p_name; + var->type_name = p_type; + var->print_function = p_print_function; + var->set_function = NULL; + variables.push_back(var); + } + return var; + } + else if (active) { + // it's a local variable for the top-most function + return call_stack[call_stack.size() - 1].function->add_variable( + p_value, p_name, p_type, p_print_function); + } + return NULL; +} + +TTCN3_Debugger::variable_t* TTCN3_Debugger::add_variable(void* p_value, + const char* p_name, + const char* p_type, + TTCN3_Debugger::print_function_t p_print_function, + TTCN3_Debugger::set_function_t p_set_function) { if (call_stack.empty()) { // no call stack yet, so this is a global or component variable @@ -617,13 +1160,15 @@ const TTCN3_Debugger::variable_t* TTCN3_Debugger::add_variable(const void* p_val var->name = p_name; var->type_name = p_type; var->print_function = p_print_function; + var->set_function = p_set_function; variables.push_back(var); } return var; } else if (active) { // it's a local variable for the top-most function - return call_stack[call_stack.size() - 1]->add_variable(p_value, p_name, p_type, p_print_function); + return call_stack[call_stack.size() - 1].function->add_variable( + p_value, p_name, p_type, p_print_function); } return NULL; } @@ -631,7 +1176,7 @@ const TTCN3_Debugger::variable_t* TTCN3_Debugger::add_variable(const void* p_val void TTCN3_Debugger::remove_variable(const variable_t* p_var) { if (active && !call_stack.empty()) { - call_stack[call_stack.size() - 1]->remove_variable(p_var); + call_stack[call_stack.size() - 1].function->remove_variable(p_var); } } @@ -695,22 +1240,28 @@ void TTCN3_Debugger::add_snapshot(const char* p_snapshot) } \ } -#define CHECK_CALL_STACK \ +#define CHECK_CALL_STACK(print_msg) \ + if (!active) { \ + if (print_msg) { \ + print(DRET_NOTIFICATION, "This command can only be used if the debugger " \ + "is switched on."); \ + } \ + return; \ + } \ if (call_stack.empty()) { \ - print(DRET_NOTIFICATION, "This command can only be used during test execution."); \ + if (print_msg) { \ + print(DRET_NOTIFICATION, "This command can only be used if the debugger's " \ + "call stack is not empty."); \ + } \ return; \ } -#define STACK_LEVEL (stack_level >= 0) ? (size_t)stack_level : (call_stack.size() - 1) - void TTCN3_Debugger::execute_command(int p_command, int p_argument_count, char** p_arguments) { if (!enabled) { return; } - Free(command_result); - command_result = NULL; for (int i = 0; i < p_argument_count; ++i) { if (p_arguments[i] == NULL) { print(DRET_NOTIFICATION, "Argument %d is a null pointer.", i + 1); @@ -722,87 +1273,136 @@ void TTCN3_Debugger::execute_command(int p_command, int p_argument_count, CHECK_NOF_ARGUMENTS(1) switch_state(p_arguments[0]); break; - case D_ADD_BREAKPOINT: - CHECK_NOF_ARGUMENTS(2) + case D_SET_BREAKPOINT: + CHECK_NOF_ARGUMENTS_RANGE(2, 3) CHECK_INT_ARGUMENT(1) - add_breakpoint(p_arguments[0], str2int(p_arguments[1])); + set_breakpoint(p_arguments[0], str2int(p_arguments[1]), + (p_argument_count == 3) ? p_arguments[2] : NULL); break; case D_REMOVE_BREAKPOINT: - CHECK_NOF_ARGUMENTS(2) - CHECK_INT_ARGUMENT(1) - remove_breakpoint(p_arguments[0], str2int(p_arguments[1])); + CHECK_NOF_ARGUMENTS_RANGE(1, 2) + remove_breakpoint(p_arguments[0], (p_argument_count == 2) ? p_arguments[1] : NULL); break; - case D_SET_ERROR_BEHAVIOR: - CHECK_NOF_ARGUMENTS(1) - set_special_breakpoint(SBP_ERROR_VERDICT, p_arguments[0]); - break; - case D_SET_FAIL_BEHAVIOR: - CHECK_NOF_ARGUMENTS(1) - set_special_breakpoint(SBP_FAIL_VERDICT, p_arguments[0]); + case D_SET_AUTOMATIC_BREAKPOINT: + CHECK_NOF_ARGUMENTS_RANGE(2, 3) + set_automatic_breakpoint(p_arguments[0], p_arguments[1], + (p_argument_count == 3) ? p_arguments[2] : NULL); break; case D_SET_OUTPUT: CHECK_NOF_ARGUMENTS_RANGE(1, 2) set_output(p_arguments[0], (p_argument_count == 2) ? p_arguments[1] : NULL); break; + case D_SET_GLOBAL_BATCH_FILE: + CHECK_NOF_ARGUMENTS_RANGE(1, 2) + set_global_batch_file(p_arguments[0], (p_argument_count == 2) ? p_arguments[1] : NULL); + break; case D_SET_COMPONENT: - print(DRET_NOTIFICATION, "Command " D_SET_COMPONENT_TEXT " should have been " - "sent to the Main Controller."); + print(DRET_NOTIFICATION, "Command " D_SET_COMPONENT_TEXT " %s.", + TTCN_Runtime::is_single() ? "is not available in single mode" : + "should have been sent to the Main Controller"); break; case D_PRINT_CALL_STACK: - CHECK_CALL_STACK + CHECK_CALL_STACK(true) CHECK_NOF_ARGUMENTS(0) print_call_stack(); break; case D_SET_STACK_LEVEL: - CHECK_CALL_STACK + CHECK_CALL_STACK(true) CHECK_NOF_ARGUMENTS(1) CHECK_INT_ARGUMENT(0) set_stack_level(str2int(p_arguments[0])); - return; // don't print the command result in this case + break; case D_LIST_VARIABLES: - CHECK_CALL_STACK + CHECK_CALL_STACK(true) CHECK_NOF_ARGUMENTS_RANGE(1, 2) - call_stack[STACK_LEVEL]->list_variables(p_arguments[0], + call_stack[STACK_LEVEL].function->list_variables(p_arguments[0], (p_argument_count == 2) ? p_arguments[1] : NULL); break; case D_PRINT_VARIABLE: - CHECK_CALL_STACK + CHECK_CALL_STACK(true) CHECK_NOF_ARGUMENTS_MIN(1) for (int i = 0; i < p_argument_count; ++i) { - const variable_t* var = call_stack[STACK_LEVEL]->find_variable(p_arguments[i]); - if (var != NULL) { - print_variable(var); + if (i != 0) { + add_to_result("\n"); } - else { - add_to_result("Variable '%s' not found.", p_arguments[i]); + if (!strcmp(p_arguments[i], "$")) { + // '$' refers to the result of the last D_LIST_VARIABLES command + // these variable names are separated by spaces + if (last_variable_list != NULL) { + size_t len = mstrlen(last_variable_list); + size_t start = 0; + for (size_t j = 0; j < len; ++j) { + if (last_variable_list[j] == ' ') { + // extract the variable name before this space + char* var_name = mcopystrn(last_variable_list + start, j - start); + print_variable(var_name); + Free(var_name); + add_to_result("\n"); + start = j + 1; + } + } + // extract the last (or only) variable name + char* var_name = mcopystrn(last_variable_list + start, len - start); + print_variable(var_name); + Free(var_name); + } + else { + add_to_result("No previous " D_LIST_VARIABLES_TEXT " result."); + } } - if (i != p_argument_count - 1) { - add_to_result("\n"); + else { + print_variable(p_arguments[i]); } } break; - // ... + case D_OVERWRITE_VARIABLE: + CHECK_CALL_STACK(true) + CHECK_NOF_ARGUMENTS_MIN(2) + overwrite_variable(p_arguments[0], p_argument_count - 1, p_arguments + 1); + break; case D_PRINT_SNAPSHOTS: CHECK_NOF_ARGUMENTS(0) add_to_result("%s", snapshots); break; - // ... + case D_STEP_OVER: + CHECK_CALL_STACK(true) + CHECK_NOF_ARGUMENTS(0) + step(STEP_OVER); + break; + case D_STEP_INTO: + CHECK_CALL_STACK(true) + CHECK_NOF_ARGUMENTS(0) + step(STEP_INTO); + break; + case D_STEP_OUT: + CHECK_CALL_STACK(true) + CHECK_NOF_ARGUMENTS(0) + step(STEP_OUT); + break; + case D_RUN_TO_CURSOR: + if (!TTCN_Runtime::is_hc() && !TTCN_Runtime::is_single()) { + CHECK_CALL_STACK(TTCN_Runtime::is_mtc()) + } + CHECK_NOF_ARGUMENTS(2) + CHECK_INT_ARGUMENT(1) + run_to_cursor(p_arguments[0], str2int(p_arguments[1])); + break; case D_HALT: - if (TTCN_Runtime::is_mtc()) { - CHECK_CALL_STACK + if (!TTCN_Runtime::is_hc() && !TTCN_Runtime::is_single()) { + CHECK_CALL_STACK(TTCN_Runtime::is_mtc()) } CHECK_NOF_ARGUMENTS(0) - halt(); + halt(NULL, false); break; case D_CONTINUE: CHECK_NOF_ARGUMENTS(0) resume(); break; case D_EXIT: - CHECK_NOF_ARGUMENTS(1) - if (TTCN_Runtime::is_mtc()) { - CHECK_CALL_STACK + if (!TTCN_Runtime::is_hc() && !TTCN_Runtime::is_single()) { + CHECK_CALL_STACK(TTCN_Runtime::is_mtc()) } + CHECK_NOF_ARGUMENTS(1) exit_(p_arguments[0]); break; case D_SETUP: @@ -814,21 +1414,36 @@ void TTCN3_Debugger::execute_command(int p_command, int p_argument_count, set_output(p_arguments[1], p_arguments[2]); } if (strlen(p_arguments[3]) > 0) { - set_special_breakpoint(SBP_ERROR_VERDICT, p_arguments[3]); + set_automatic_breakpoint("error", p_arguments[3], + strlen(p_arguments[4]) > 0 ? p_arguments[4] : NULL); + } + if (strlen(p_arguments[5]) > 0) { + set_automatic_breakpoint("fail", p_arguments[5], + strlen(p_arguments[6]) > 0 ? p_arguments[6] : NULL); } - if (strlen(p_arguments[4]) > 0) { - set_special_breakpoint(SBP_FAIL_VERDICT, p_arguments[4]); + if (strlen(p_arguments[7]) > 0) { + set_global_batch_file(p_arguments[7], + strlen(p_arguments[8]) > 0 ? p_arguments[8] : NULL); } - for (int i = 5; i < p_argument_count; i += 2) { - add_breakpoint(p_arguments[i], str2int(p_arguments[i + 1])); + for (int i = 9; i < p_argument_count; i += 3) { + set_breakpoint(p_arguments[i], str2int(p_arguments[i + 1]), + strlen(p_arguments[i + 2]) > 0 ? p_arguments[i + 2] : NULL); } break; default: - print(DRET_NOTIFICATION, "Command not implemented."); + print(DRET_NOTIFICATION, "Invalid command received (ID: %d).", p_command); return; } if (command_result != NULL) { print(DRET_DATA, command_result); + if (p_command == D_LIST_VARIABLES) { + Free(last_variable_list); + last_variable_list = command_result; + } + else { + Free(command_result); + } + command_result = NULL; } } @@ -836,7 +1451,7 @@ void TTCN3_Debugger::open_output_file() { if (output_file == NULL && output_file_name != NULL) { char* final_file_name = finalize_file_name(output_file_name); - output_file = fopen(final_file_name, "w"); + output_file = fopen(final_file_name, TTCN_Runtime::is_mtc() ? "w" : "a"); if (output_file == NULL) { print(DRET_NOTIFICATION, "Failed to open file '%s' for writing.", final_file_name); } @@ -864,15 +1479,28 @@ TTCN3_Debug_Scope::~TTCN3_Debug_Scope() void TTCN3_Debug_Scope::add_variable(const void* p_value, const char* p_name, const char* p_type, - CHARSTRING (*p_print_function)(const TTCN3_Debugger::variable_t&)) + TTCN3_Debugger::print_function_t p_print_function) +{ + TTCN3_Debugger::variable_t* var = ttcn3_debugger.add_variable(p_value, p_name, p_type, p_print_function); + if (var != NULL) { + variables.push_back(var); + } +} + +void TTCN3_Debug_Scope::add_variable(void* p_value, + const char* p_name, + const char* p_type, + TTCN3_Debugger::print_function_t p_print_function, + TTCN3_Debugger::set_function_t p_set_function) { - const TTCN3_Debugger::variable_t* var = ttcn3_debugger.add_variable(p_value, p_name, p_type, p_print_function); + TTCN3_Debugger::variable_t* var = ttcn3_debugger.add_variable(p_value, p_name, + p_type, p_print_function, p_set_function); if (var != NULL) { variables.push_back(var); } } -const TTCN3_Debugger::variable_t* TTCN3_Debug_Scope::find_variable(const char* p_name) const +TTCN3_Debugger::variable_t* TTCN3_Debug_Scope::find_variable(const char* p_name) const { for (size_t i = 0; i < variables.size(); ++i) { if (strcmp(variables[i]->name, p_name) == 0) { @@ -951,10 +1579,29 @@ TTCN3_Debug_Function::~TTCN3_Debug_Function() ttcn3_debugger.remove_function(this); } -const TTCN3_Debugger::variable_t* TTCN3_Debug_Function::add_variable(const void* p_value, - const char* p_name, - const char* p_type, - CHARSTRING (*p_print_function)(const TTCN3_Debugger::variable_t&)) +TTCN3_Debugger::variable_t* TTCN3_Debug_Function::add_variable(const void* p_value, + const char* p_name, + const char* p_type, + TTCN3_Debugger::print_function_t p_print_function) +{ + if (ttcn3_debugger.is_on()) { + TTCN3_Debugger::variable_t* var = new TTCN3_Debugger::variable_t; + var->cvalue = p_value; + var->name = p_name; + var->type_name = p_type; + var->print_function = p_print_function; + var->set_function = NULL; + variables.push_back(var); + return var; + } + return NULL; +} + +TTCN3_Debugger::variable_t* TTCN3_Debug_Function::add_variable(void* p_value, + const char* p_name, + const char* p_type, + TTCN3_Debugger::print_function_t p_print_function, + TTCN3_Debugger::set_function_t p_set_function) { if (ttcn3_debugger.is_on()) { TTCN3_Debugger::variable_t* var = new TTCN3_Debugger::variable_t; @@ -962,6 +1609,7 @@ const TTCN3_Debugger::variable_t* TTCN3_Debug_Function::add_variable(const void* var->name = p_name; var->type_name = p_type; var->print_function = p_print_function; + var->set_function = p_set_function; variables.push_back(var); return var; } @@ -1022,7 +1670,7 @@ void TTCN3_Debug_Function::remove_variable(const TTCN3_Debugger::variable_t* p_v } } -const TTCN3_Debugger::variable_t* TTCN3_Debug_Function::find_variable(const char* p_name) const +TTCN3_Debugger::variable_t* TTCN3_Debug_Function::find_variable(const char* p_name) const { for (size_t i = 0; i < variables.size(); ++i) { if (strcmp(variables[i]->name, p_name) == 0) { @@ -1031,7 +1679,7 @@ const TTCN3_Debugger::variable_t* TTCN3_Debug_Function::find_variable(const char } // it's not a local variable, it might still be a global or component variable if (component_scope != NULL) { - const TTCN3_Debugger::variable_t* res = component_scope->find_variable(p_name); + TTCN3_Debugger::variable_t* res = component_scope->find_variable(p_name); if (res != NULL) { return res; } @@ -1125,3 +1773,12 @@ void TTCN3_Debug_Function::list_variables(const char* p_scope, const char* p_fil } } +bool TTCN3_Debug_Function::is_control_part() const +{ + return !strcmp(function_type, "control"); +} + +bool TTCN3_Debug_Function::is_test_case() const +{ + return !strcmp(function_type, "testcase"); +} diff --git a/core/Debugger.hh b/core/Debugger.hh index 370c0344919e7f6b2c1c3c01adf980463427fd35..de6eac1d09ae473af184f7f4682a0acfd8ecb19c 100644 --- a/core/Debugger.hh +++ b/core/Debugger.hh @@ -27,10 +27,13 @@ /** alias for record of charstring */ typedef PreGenRecordOf::PREGEN__RECORD__OF__CHARSTRING charstring_list; -// forward declarations +// debugger forward declarations class TTCN3_Debug_Scope; class TTCN3_Debug_Function; +// other forward declarations +class Module_Param; + ////////////////////////////////////////////////////// ////////////////// TTCN3_Debugger //////////////////// @@ -43,16 +46,29 @@ class TTCN3_Debug_Function; class TTCN3_Debugger { public: + struct variable_t; + + typedef CHARSTRING (*print_function_t)(const variable_t&); + typedef boolean (*set_function_t)(variable_t&, Module_Param&); + /** type for keeping track of a variable */ struct variable_t { /** pointer to the variable object, not owned */ - const void* value; + union { + /** container for non-constant variable objects */ + void* value; + /** container for constant variable objects */ + const void* cvalue; + }; /** variable name (used for looking up variables), not owned */ const char* name; /** name of the variable's type, not owned */ const char* type_name; /** variable printing function (using the variable object's log() function) */ - CHARSTRING (*print_function)(const variable_t&); + print_function_t print_function; + /** variable setting (overwriting) function (using the variable object's + * set_param() function) - set to NULL for constant variables */ + set_function_t set_function; }; /** this type pairs a debug scope with a name, used for storing global and @@ -65,13 +81,22 @@ public: TTCN3_Debug_Scope* scope; }; + /** type for storing a function call in the call stack */ + struct function_call_t { + /** pointer to the debug function object */ + TTCN3_Debug_Function* function; + /** TTCN-3 line number, where the function was called from */ + int caller_line; + }; + /** type for storing breakpoints */ struct breakpoint_t { /** module name, owned */ char* module; /** line number */ int line; - // const char* batch_file; + /** batch file to be executed when the breakpoint is reached (optional) */ + char* batch_file; }; /** special breakpoint types, passed to breakpoint_entry() as the line parameter, @@ -83,6 +108,22 @@ public: SBP_FAIL_VERDICT = -1 }; + /** type for storing the settings of automatic breakpoints */ + struct automatic_breakpoint_behavior_t { + /** indicates whether the breakpoint should be triggered by the associated event */ + bool trigger; + /** batch file to be executed if the breakpoint is triggered (optional) */ + char* batch_file; + }; + + /** stepping type */ + enum stepping_t { + NOT_STEPPING, + STEP_OVER, + STEP_INTO, + STEP_OUT + }; + private: /** indicates whether the debugger has been activated, meaning that the debugger's @@ -116,9 +157,10 @@ private: /** list of component scopes */ Vector<named_scope_t> component_scopes; - /** pointers to debug function objects (resembling a call stack), elements are not owned - * the current function is always the last element in the array (the top element in the stack) */ - Vector<TTCN3_Debug_Function*> call_stack; + /** pointers to debug function objects and the lines they were called from + * (resembling a call stack), the current function is always the last element + * in the array (the top element in the stack) */ + Vector<function_call_t> call_stack; /** list of breakpoints */ Vector<breakpoint_t> breakpoints; @@ -132,17 +174,44 @@ private: /** current stack level (reset when test execution is halted or resumed) */ int stack_level; - /** behavior triggered by setting the local verdict to FAIL - * (a breakpoint is activated if set to true) */ - bool fail_behavior; + /** automatic breakpoint triggered by setting the local verdict to FAIL */ + automatic_breakpoint_behavior_t fail_behavior; - /** behavior triggered by setting the local verdict to ERROR - * (a breakpoint is activated if set to true) */ - bool error_behavior; + /** automatic breakpoint triggered by setting the local verdict to ERROR */ + automatic_breakpoint_behavior_t error_behavior; - /** result of the last executed or currently executing command */ + /** batch file executed automatically when test execution is halted + * NULL if switched off + * is overridden by breakpoint-specific batch files */ + char* global_batch_file; + + /** result of the currently executing command */ char* command_result; + /** result of the last D_LIST_VARIABLES command */ + char* last_variable_list; + + /** stores which stepping option was requested by the user (if any) */ + stepping_t stepping_type; + + /** stores the size of the call stack when the last stepping operation was + * initiated */ + size_t stepping_stack_size; + + /** temporary breakpoint set by the 'run to cursor' operation */ + breakpoint_t temporary_breakpoint; + + /** true if an 'exit all' command was issued + * switched to false when test execution is restarted */ + bool exiting; + + /** test execution is automatically halted at start if set to true */ + bool halt_at_start; + + /** batch file executed automatically at the start of test execution + * if not set to NULL (not owned) */ + const char* initial_batch_file; + ////////////////////////////////////////////////////// ///////////////// internal functions ///////////////// ////////////////////////////////////////////////////// @@ -151,19 +220,28 @@ private: * handles the D_SWITCH command */ void switch_state(const char* p_state_str); - /** adds a new breakpoint at the specified module and line + /** adds a new breakpoint at the specified module and line with the specified + * batch file (if not NULL), or changes the batch file of an existing + * breakpoint * handles the D_ADD_BREAKPOINT command */ - void add_breakpoint(const char* p_module, int p_line /*const char* batch_file*/); + void set_breakpoint(const char* p_module, int p_line, const char* batch_file); /** removes the breakpoint from the specified module/line, if it exists + * can also be used to remove all breakpoints from the specified module or + * all breakpoints in all modules * handles the D_REMOVE_BREAKPOINT command */ - void remove_breakpoint(const char* p_module, int p_line); - - /** sets the behavior of a special breakpoint type - * @param p_state_str "yes" turns the special breakpoint on (as if it was an - * actual breakpoint), "no" turns it off - * handles the D_SET_ERROR_BEHAVIOR and D_SET_FAIL_BEHAVIOR commands */ - void set_special_breakpoint(special_breakpoint_t p_type, const char* p_state_str); + void remove_breakpoint(const char* p_module, const char* p_line); + + /** switches an automatic breakpoint related to the specified event on or off + * and/or sets the batch file to run when the breakpoint is triggered + * @param p_event_str string representation of the event that triggers the + * breakpoint (either "error" or "fail") + * @param p_state_str "on" or "off", indicates the new state of the breakpoint + * @param p_batch_file name of the batch file to execute (NULL means don't + * execute anything) + * handles the D_SET_AUTOMATIC_BREAKPOINT command */ + void set_automatic_breakpoint(const char* p_event_str, const char* p_state_str, + const char* p_batch_file); /** prints the current call stack * handles the D_PRINT_CALL_STACK command */ @@ -173,9 +251,13 @@ private: * handles the D_SET_STACK_LEVEL command */ void set_stack_level(int new_level); - /** prints the specified variable + /** finds the variable with the specified name, and prints its value or an + * error message * handles (one parameter of) the D_PRINT_VARIABLE command */ - void print_variable(const variable_t* p_var); + void print_variable(const char* p_var_name); + + void overwrite_variable(const char* p_var_name, int p_value_element_count, + char** p_value_elements); /** sets the debugger's output to the console and/or a text file * handles the D_SET_OUTPUT command @@ -183,9 +265,27 @@ private: * @param p_file_name output file name or NULL */ void set_output(const char* p_output_type, const char* p_file_name); + /** switches the global batch file on or off + * handles the D_SET_GLOBAL_BATCH_FILE command */ + void set_global_batch_file(const char* p_state_str, const char* p_file_name); + + /** resumes execution until the next breakpoint entry (in the stack levels + * specified by the stepping type arguments) is reached (or until test execution + * is halted for any other reason) + * handles the D_STEP_OVER, D_STEP_INTO and D_STEP_OUT commands */ + void step(stepping_t p_stepping_type); + + /** resumes execution until the specified location is reached + * (or until test execution is halted for any other reason) + * handles the D_RUN_TO_CURSOR command */ + void run_to_cursor(const char* p_module, int p_line); + /** halts test execution, processing only debug commands + * @param p_batch_file batch file executed after the halt (if not NULL) + * @param p_run_global_batch indicates whether the global batch file should + * be executed after the halt (only if p_batch_file is NULL) * handles the D_HALT command */ - void halt(); + void halt(const char* p_batch_file, bool p_run_global_batch); /** resumes the halted test execution * handles the D_CONTINUE command */ @@ -205,6 +305,14 @@ private: /** handles metacharacters in the specified file name skeleton * @return final file name (must be freed by caller) */ static char* finalize_file_name(const char* p_file_name_skeleton); + + /** initialization function, called when the first function is added to the + * call stack */ + void test_execution_started(); + + /** clean up function, called when the last function is removed from the + * call stack */ + void test_execution_finished(); public: /** constructor - called once per process (at the beginning) */ @@ -237,37 +345,61 @@ public: * the special parameter values (SBP_ERROR_VERDICT and SBP_FAIL_VERDICT) only * trigger a breakpoint if their respective behaviors have been set to do so * (does nothing if the debugger is switched off) */ - void breakpoint_entry(int p_line /*bool p_stepping_helper*/); + void breakpoint_entry(int p_line); /** variable printing function for base types */ static CHARSTRING print_base_var(const variable_t& p_var); + /** variable setting function for base types */ + static boolean set_base_var(variable_t& p_var, Module_Param& p_new_value); + /** variable printing function for value arrays */ template <typename T_type, unsigned int array_size, int index_offset> static CHARSTRING print_value_array(const variable_t& p_var) { + const void* ptr = p_var.set_function != NULL ? p_var.value : p_var.cvalue; TTCN_Logger::begin_event_log2str(); - ((VALUE_ARRAY<T_type, array_size, index_offset>*)p_var.value)->log(); + ((VALUE_ARRAY<T_type, array_size, index_offset>*)ptr)->log(); return TTCN_Logger::end_event_log2str(); } + /** variable setting function for value arrays */ + template <typename T_type, unsigned int array_size, int index_offset> + static boolean set_value_array(variable_t& p_var, Module_Param& p_new_value) + { + ((VALUE_ARRAY<T_type, array_size, index_offset>*)p_var.value)->set_param(p_new_value); + return TRUE; + } + /** variable printing function for template arrays */ template <typename T_value_type, typename T_template_type, unsigned int array_size, int index_offset> static CHARSTRING print_template_array(const variable_t& p_var) { + const void* ptr = p_var.set_function != NULL ? p_var.value : p_var.cvalue; TTCN_Logger::begin_event_log2str(); ((TEMPLATE_ARRAY<T_value_type, T_template_type, array_size, - index_offset>*)p_var.value)->log(); + index_offset>*)ptr)->log(); return TTCN_Logger::end_event_log2str(); } + /** variable setting function for template arrays */ + template <typename T_value_type, typename T_template_type, + unsigned int array_size, int index_offset> + static boolean set_template_array(variable_t& p_var, Module_Param& p_new_value) + { + ((TEMPLATE_ARRAY<T_value_type, T_template_type, array_size, + index_offset>*)p_var.value)->set_param(p_new_value); + return TRUE; + } + /** variable printing function for port arrays */ template <typename T_type, unsigned int array_size, int index_offset> static CHARSTRING print_port_array(const variable_t& p_var) { + const void* ptr = p_var.set_function != NULL ? p_var.value : p_var.cvalue; TTCN_Logger::begin_event_log2str(); - ((PORT_ARRAY<T_type, array_size, index_offset>*)p_var.value)->log(); + ((PORT_ARRAY<T_type, array_size, index_offset>*)ptr)->log(); return TTCN_Logger::end_event_log2str(); } @@ -275,8 +407,9 @@ public: template <typename T_type, unsigned int array_size, int index_offset> static CHARSTRING print_timer_array(const variable_t& p_var) { + const void* ptr = p_var.set_function != NULL ? p_var.value : p_var.cvalue; TTCN_Logger::begin_event_log2str(); - ((TIMER_ARRAY<T_type, array_size, index_offset>*)p_var.value)->log(); + ((TIMER_ARRAY<T_type, array_size, index_offset>*)ptr)->log(); return TTCN_Logger::end_event_log2str(); } @@ -284,8 +417,9 @@ public: template <typename EXPR_TYPE> static CHARSTRING print_lazy_param(const variable_t& p_var) { + const void* ptr = p_var.set_function != NULL ? p_var.value : p_var.cvalue; TTCN_Logger::begin_event_log2str(); - ((Lazy_Param<EXPR_TYPE>*)p_var.value)->log(); + ((Lazy_Param<EXPR_TYPE>*)ptr)->log(); return TTCN_Logger::end_event_log2str(); } @@ -325,14 +459,19 @@ public: * (only if the call stack is not empty) */ void remove_scope(TTCN3_Debug_Scope* p_scope); - /** finds or creates, and returns the variable entry specified by the parameters + /** finds or creates, and returns the constant variable entry specified by + * the parameters * * if the call stack is empty, an entry for a global or component variable is * created and stored in the main debugger object (if it doesn't already exist); * if the call stack is not empty (and if the debugger is switched on), the * variable entry for a local variable is created and stored by the current function */ - const variable_t* add_variable(const void* p_value, const char* p_name, const char* p_type, - CHARSTRING (*p_print_function)(const variable_t&)); + variable_t* add_variable(const void* p_value, const char* p_name, const char* p_type, + print_function_t p_print_function); + + /** same as before, but for non-constant variables */ + variable_t* add_variable(void* p_value, const char* p_name, const char* p_type, + print_function_t p_print_function, set_function_t p_set_function); /** removes the variable entry for the specified local variable in the current * function (only if the call stack is not empty) */ @@ -353,6 +492,19 @@ public: /** opens the debugger's output file for writing (if one has been set, but not * opened, in the HC process) */ void open_output_file(); + + /** indicates whether an 'exit all' command has been issued + * (this causes the execution of tests in the current queue to stop) */ + bool is_exiting() const { return exiting; } + + /** sets the debugger to halt test execution at start (only in single mode) */ + void set_halt_at_start() { halt_at_start = true; } + + /** sets the specified batch file to be executed at the start of test execution + * (only in single mode) */ + void set_initial_batch_file(const char* p_batch_file) { + initial_batch_file = p_batch_file; + } }; /** the main debugger object */ @@ -377,7 +529,7 @@ class TTCN3_Debug_Scope { /** list of pointers to local variable entries from the current function object or * global or component variable entries from the main debugger object * (the elements are not owned)*/ - Vector<const TTCN3_Debugger::variable_t*> variables; + Vector<TTCN3_Debugger::variable_t*> variables; public: @@ -393,11 +545,16 @@ public: ////////////////////////////////////////////////////// /** passes the parameters to the main debugger or current function object to - * create and store a variable entry from them, and tracks this new variable - * by storing a pointer to it + * create and store a (constant) variable entry from them, and tracks this new + * variable by storing a pointer to it * (local variables are only created and stored if the debugger is switched on) */ void add_variable(const void* p_value, const char* p_name, const char* p_type, - CHARSTRING (*p_print_function)(const TTCN3_Debugger::variable_t&)); + TTCN3_Debugger::print_function_t p_print_function); + + /** same as before, but for non-constant variables */ + void add_variable(void* p_value, const char* p_name, const char* p_type, + TTCN3_Debugger::print_function_t p_print_function, + TTCN3_Debugger::set_function_t p_set_function); ////////////////////////////////////////////////////// ////// methods called by other debugger classes ////// @@ -407,7 +564,7 @@ public: bool has_variables() const { return !variables.empty(); } /** returns the specified variable, if found, otherwise returns NULL */ - const TTCN3_Debugger::variable_t* find_variable(const char* p_name) const; + TTCN3_Debugger::variable_t* find_variable(const char* p_name) const; /** prints the names of variables in this scope that match the specified * @param p_posix_regexp the pattern converted into a POSIX regex structure @@ -483,10 +640,15 @@ public: ////// methods called from TITAN generated code ////// ////////////////////////////////////////////////////// - /** creates, stores and returns the variable entry of the local variable + /** creates, stores and returns the variable entry of the local (constant) variable * specified by the parameters (only if the debugger is switched on) */ - const TTCN3_Debugger::variable_t* add_variable(const void* p_value, const char* p_name, - const char* p_type, CHARSTRING (*p_print_function)(const TTCN3_Debugger::variable_t&)); + TTCN3_Debugger::variable_t* add_variable(const void* p_value, const char* p_name, + const char* p_type, TTCN3_Debugger::print_function_t p_print_function); + + /** same as before, but for non-constant variables */ + TTCN3_Debugger::variable_t* add_variable(void* p_value, const char* p_name, + const char* p_type, TTCN3_Debugger::print_function_t p_print_function, + TTCN3_Debugger::set_function_t p_set_function); /** stores the string representation of the value returned by the function */ void set_return_value(const CHARSTRING& p_value); @@ -513,7 +675,7 @@ public: /** searches for the variable entry with the specified name in the function's * local variable list, the global scope (if any) and the component scope (if any), * returns NULL, if the variable was not found */ - const TTCN3_Debugger::variable_t* find_variable(const char* p_name) const; + TTCN3_Debugger::variable_t* find_variable(const char* p_name) const; /** prints the function's type, name and current values of parameters */ void print_function() const; @@ -530,6 +692,12 @@ public: * - "all" - all variables visible in the function (i.e. all of the above) * @param p_filter a pattern to filter variable names further */ void list_variables(const char* p_scope, const char* p_filter) const; + + /** returns true if this instance belongs to a control part */ + bool is_control_part() const; + + /** returns true if this instance belongs to a test case */ + bool is_test_case() const; }; /** This macro stores a function's return value in the current function. diff --git a/core/DebuggerUI.cc b/core/DebuggerUI.cc new file mode 100644 index 0000000000000000000000000000000000000000..4ca6e5b055cd23f558b1ae37cf9c939c4df1afb1 --- /dev/null +++ b/core/DebuggerUI.cc @@ -0,0 +1,263 @@ +/****************************************************************************** + * 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 + * + * Contributors: + * + * Baranyi, Botond – initial implementation + * + ******************************************************************************/ + +#include "DebuggerUI.hh" +#include "DebugCommands.hh" +#include "Debugger.hh" +#include "../mctr2/editline/libedit/src/editline/readline.h" +#include <stdio.h> +#include <ctype.h> + +#define PROMPT_TEXT "DEBUG> " +#define BATCH_TEXT "batch" + +// use a different file, than the MCTR CLI, since not all commands are the same +#define TTCN3_HISTORY_FILENAME ".ttcn3_history_single" + +const TTCN_Debugger_UI::command_t TTCN_Debugger_UI::debug_command_list[] = { + { D_SWITCH_TEXT, D_SWITCH, D_SWITCH_TEXT " on|off", + "Switch the debugger on or off." }, + { D_SET_BREAKPOINT_TEXT, D_SET_BREAKPOINT, + D_SET_BREAKPOINT_TEXT " <module> <line> [<batch_file>]", + "Add a breakpoint at the specified location, or change the batch file of " + " an existing breakpoint." }, + { D_REMOVE_BREAKPOINT_TEXT, D_REMOVE_BREAKPOINT, + D_REMOVE_BREAKPOINT_TEXT " all|<module> [all|<line>]", "Remove a breakpoint, " + "or all breakpoints from a module, or all breakpoints from all modules." }, + { D_SET_AUTOMATIC_BREAKPOINT_TEXT, D_SET_AUTOMATIC_BREAKPOINT, + D_SET_AUTOMATIC_BREAKPOINT_TEXT " error|fail on|off [<batch_file>]", + "Switch an automatic breakpoint (truggered by an event) on or off, and/or " + "change its batch file." }, + { D_SET_OUTPUT_TEXT, D_SET_OUTPUT, + D_SET_OUTPUT_TEXT " console|file|both [file_name]", + "Set the output of the debugger." }, + { D_SET_GLOBAL_BATCH_FILE_TEXT, D_SET_GLOBAL_BATCH_FILE, + D_SET_GLOBAL_BATCH_FILE_TEXT " on|off [batch_file_name]", + "Set whether a batch file should be executed automatically when test execution " + "is halted (breakpoint-specific batch files override this setting)." }, + { D_SET_COMPONENT_TEXT, D_SET_COMPONENT, + D_SET_COMPONENT_TEXT " mtc|<component_reference>", + "Set the test component to print debug information from." }, + { D_PRINT_CALL_STACK_TEXT, D_PRINT_CALL_STACK, D_PRINT_CALL_STACK_TEXT, + "Print call stack." }, + { D_SET_STACK_LEVEL_TEXT, D_SET_STACK_LEVEL, D_SET_STACK_LEVEL_TEXT " <level>", + "Set the stack level to print debug information from." }, + { D_LIST_VARIABLES_TEXT, D_LIST_VARIABLES, + D_LIST_VARIABLES_TEXT " local|global|comp|all [pattern]", + "List variable names." }, + { D_PRINT_VARIABLE_TEXT, D_PRINT_VARIABLE, + D_PRINT_VARIABLE_TEXT " <variable_name>|$ [{ <variable_name>|$}]", + "Print current value of one or more variables ('$' is substituted with the " + "result of the last " D_LIST_VARIABLES_TEXT " command)." }, + { D_OVERWRITE_VARIABLE_TEXT, D_OVERWRITE_VARIABLE, + D_OVERWRITE_VARIABLE_TEXT " <variable_name> <value>", + "Overwrite the current value of a variable." }, + { D_PRINT_SNAPSHOTS_TEXT, D_PRINT_SNAPSHOTS, D_PRINT_SNAPSHOTS_TEXT, + "Print snapshots of function calls until this point." }, + // D_SET_SNAPSHOT_BEHAVIOR_TEXT + { D_STEP_OVER_TEXT, D_STEP_OVER, D_STEP_OVER_TEXT, + "Resume test execution until the next line of code (in this function or the " + "caller function)." }, + { D_STEP_INTO_TEXT, D_STEP_INTO, D_STEP_INTO_TEXT, + "Resume test execution until the next line of code (on any stack level)." }, + { D_STEP_OUT_TEXT, D_STEP_OUT, D_STEP_OUT_TEXT, + "Resume test execution until the next line of code in the caller function." }, + { D_RUN_TO_CURSOR_TEXT, D_RUN_TO_CURSOR, D_RUN_TO_CURSOR_TEXT " <module> <line>", + "Resume test execution until the specified location." }, + { D_HALT_TEXT, D_HALT, D_HALT_TEXT, "Halt test execution." }, + { D_CONTINUE_TEXT, D_CONTINUE, D_CONTINUE_TEXT, "Resume halted test execution." }, + { D_EXIT_TEXT, D_EXIT, D_EXIT_TEXT " test|all", + "Exit the current test or the execution of all tests." }, + { NULL, D_ERROR, NULL, NULL } +}; + +char* TTCN_Debugger_UI::ttcn3_history_filename = NULL; + +/** local function for extracting the command name and its arguments from an + * input line + * @param arguments [in] input line + * @param len [in] length of the input line + * @param start [in] indicates the position to start searching from + * @param start [out] the next argument's start position (set to len if no further + * arguments were found) + * @param end [out] the position of the first character after the next argument */ +static void get_next_argument_loc(const char* arguments, size_t len, size_t& start, size_t& end) +{ + while (start < len && isspace(arguments[start])) { + ++start; + } + end = start; + while (end < len && !isspace(arguments[end])) { + ++end; + } +} + +void TTCN_Debugger_UI::process_command(const char* p_line_read) +{ + // locate the command text + size_t len = strlen(p_line_read); + size_t start = 0; + size_t end = 0; + get_next_argument_loc(p_line_read, len, start, end); + if (start == len) { + // empty command + return; + } + add_history(p_line_read + start); + for (const command_t *command = debug_command_list; command->name != NULL; + ++command) { + if (!strncmp(p_line_read + start, command->name, end - start)) { + // count the arguments + int argument_count = 0; + size_t start_tmp = start; + size_t end_tmp = end; + while (start_tmp < len) { + start_tmp = end_tmp; + get_next_argument_loc(p_line_read, len, start_tmp, end_tmp); + if (start_tmp < len) { + ++argument_count; + } + } + // extract the arguments into a string array + char** arguments; + if (argument_count > 0) { + arguments = new char*[argument_count]; + for (int i = 0; i < argument_count; ++i) { + start = end; + get_next_argument_loc(p_line_read, len, start, end); + arguments[i] = mcopystrn(p_line_read + start, end - start); + } + } + else { + arguments = NULL; + } + ttcn3_debugger.execute_command(command->commandID, argument_count, arguments); + if (argument_count > 0) { + for (int i = 0; i < argument_count; ++i) { + Free(arguments[i]); + } + delete [] arguments; + } + return; + } + } + if (!strncmp(p_line_read + start, BATCH_TEXT, end - start)) { + start = end; + get_next_argument_loc(p_line_read, len, start, end); // just to skip to the argument + // the entire argument list is treated as one file name (even if it contains spaces) + execute_batch_file(p_line_read + start); + return; + } + puts("Unknown command, try again..."); +} + +void TTCN_Debugger_UI::init() +{ + // initialize history library + using_history(); + // calculate history file name + const char *home_directory = getenv("HOME"); + if (home_directory == NULL) { + home_directory = "."; + } + ttcn3_history_filename = mprintf("%s/%s", home_directory, TTCN3_HISTORY_FILENAME); + // read history from file, don't bother if it does not exist + read_history(ttcn3_history_filename); + // set our own command completion function + rl_completion_entry_function = (Function*)complete_command; +} + +void TTCN_Debugger_UI::clean_up() +{ + if (write_history(ttcn3_history_filename)) { + puts("Could not save debugger command history."); + } + Free(ttcn3_history_filename); +} + +void TTCN_Debugger_UI::read_loop() +{ + while (ttcn3_debugger.is_halted()) { + // print the prompt and read a line using the readline(), which + // automatically handles command completion and command history + char* line = readline(PROMPT_TEXT); + if (line != NULL) { + process_command(line); + free(line); + } + else { + // EOF was received -> exit all + puts("exit all"); + char** args = new char*[1]; + args[0] = (char*)"all"; + ttcn3_debugger.execute_command(D_EXIT, 1, args); + delete [] args; + } + } +} + +void TTCN_Debugger_UI::execute_batch_file(const char* p_file_name) +{ + FILE* fp = fopen(p_file_name, "r"); + if (fp == NULL) { + printf("Failed to open file '%s' for reading.\n", p_file_name); + return; + } + else { + printf("Executing batch file '%s'.\n", p_file_name); + } + char line[1024]; + while (fgets(line, sizeof(line), fp) != NULL) { + size_t len = strlen(line); + if (line[len - 1] == '\n') { + line[len - 1] = '\0'; + --len; + } + if (len != 0) { + printf("%s\n", line); + process_command(line); + } + } + if (!feof(fp)) { + printf("Error occurred while reading batch file '%s' (error code: %d).\n", + p_file_name, ferror(fp)); + } + fclose(fp); +} + +void TTCN_Debugger_UI::print(const char* p_str) +{ + puts(p_str); +} + +char* TTCN_Debugger_UI::complete_command(const char* p_prefix, int p_state) +{ + static int command_index; + static size_t prefix_len; + const char *command_name; + + if (p_state == 0) { + command_index = 0; + prefix_len = strlen(p_prefix); + } + + while ((command_name = debug_command_list[command_index].name)) { + ++command_index; + if (strncmp(p_prefix, command_name, prefix_len) == 0) { + // must allocate buffer for returned string (readline() frees it) + return strdup(command_name); + } + } + // no match found + return NULL; +} \ No newline at end of file diff --git a/core/DebuggerUI.hh b/core/DebuggerUI.hh new file mode 100644 index 0000000000000000000000000000000000000000..b3da252955d420a13afe441b09142bc7fb64fd21 --- /dev/null +++ b/core/DebuggerUI.hh @@ -0,0 +1,71 @@ +/****************************************************************************** + * 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 + * + * Contributors: + * + * Baranyi, Botond – initial implementation + * + ******************************************************************************/ + +#ifndef DEBUGGER_UI_HH +#define DEBUGGER_UI_HH + +/** Command line interface class for the TTCN-3 debugger in single mode + * Mimics the functionality of the Main Controller CLI in most cases + * Uses the editline package for reading commands (which provides command + * completion and command history tracking) */ +class TTCN_Debugger_UI { + + /** structure for storing a command */ + struct command_t { + /** command name */ + const char *name; + /** debugger command ID */ + int commandID; + /** command usage text */ + const char *synopsis; + /** command description text */ + const char *description; + }; + + /** list of commands */ + static const command_t debug_command_list[]; + + /** name of the file, where the command history is stored */ + static char* ttcn3_history_filename; + + /** processes the command in the specified input line + * if it's a valid command, then it is added to the command history and + * passed to the debugger + * if it's not valid, an error message is displayed */ + static void process_command(const char* p_line_read); + +public: + + /** initializes the UI */ + static void init(); + + /** cleans up the UI's resources */ + static void clean_up(); + + /** reads commands from the standard input and passes them on for processing, + * until test execution is no longer halted */ + static void read_loop(); + + /** executes the commands in the specified batch file + * each line is treated as a separate command */ + static void execute_batch_file(const char* p_file_name); + + /** prints the specified text to the standard output */ + static void print(const char* p_str); + + /** command completion function for editline */ + static char* complete_command(const char* p_prefix, int p_state); +}; + +#endif /* DEBUGGER_UI_HH */ + diff --git a/core/Logger.cc b/core/Logger.cc index bb0f3e0b07856700dadf993173060f57f343195d..9b7d92657660ab8f7a40f6a22b752c12e81d3af0 100644 --- a/core/Logger.cc +++ b/core/Logger.cc @@ -1510,6 +1510,14 @@ void TTCN_Location::strip_entity_name(char*& par_str) par_str = new_str; } +unsigned int TTCN_Location::get_line_number() +{ + if (innermost_location != NULL) { + return innermost_location->line_number; + } + return 0; +} + char *TTCN_Location::append_contents(char *par_str, boolean print_entity_name) const { diff --git a/core/Logger.hh b/core/Logger.hh index c394c95d199685c4f3a2c0f1bf5ffd5d7dd79b13..96d1b2d71a62de1f76c70ad6769611d8796f47b6 100644 --- a/core/Logger.hh +++ b/core/Logger.hh @@ -836,6 +836,10 @@ public: * **/ static void strip_entity_name(char*& par_str); + + /** @brief Return the innermost location's line number + **/ + static unsigned int get_line_number(); protected: char *append_contents(char *par_str, boolean print_entity_name) const; }; diff --git a/core/Makefile b/core/Makefile index a01209d85d9a7901a84cd8033546efa06866a45b..ea118e12aa206413c3f1ef79ae2c5a8c814d055a 100644 --- a/core/Makefile +++ b/core/Makefile @@ -75,12 +75,12 @@ TTCN_COMPILER_FLAGS += -o $(APIDIR) # -I. is needed because TitanLoggerApi.hh (generated) does #include <TTCN3.hh> CPPFLAGS += -I. -I$(APIDIR) -SOLARIS_LIBS := -lsocket -lnsl -lxml2 -SOLARIS8_LIBS := -lsocket -lnsl -lxml2 -LINUX_LIBS := -lxml2 -FREEBSD_LIBS := -lxml2 -WIN32_LIBS := -lxml2 -INTERIX_LIBS := -lxml2 +SOLARIS_LIBS := -lsocket -lnsl -lxml2 -lcurses +SOLARIS8_LIBS := -lsocket -lnsl -lxml2 -lcurses +LINUX_LIBS := -lxml2 -lncurses +FREEBSD_LIBS := -lxml2 -lncurses +WIN32_LIBS := -lxml2 -lncurses +INTERIX_LIBS := -lxml2 -lncurses ifeq ($(USAGE_STATS), yes) SOLARIS_LIBS += -lresolv @@ -104,7 +104,8 @@ Module_list.cc Objid.cc Octetstring.cc Parallel_main.cc Port.cc RAW.cc \ Runtime.cc Single_main.cc Snapshot.cc Struct_of.cc Template.cc TEXT.cc \ Textbuf.cc Timer.cc Param_Types.cc Universal_charstring.cc \ Verdicttype.cc XER.cc XmlReader.cc TitanLoggerControlImpl.cc TCov.cc JSON.cc \ -Profiler.cc ProfilerTools.cc ProfMerge_main.cc Debugger.cc $(RT2_SOURCES) +Profiler.cc ProfilerTools.cc ProfMerge_main.cc Debugger.cc DebuggerUI.cc \ +$(RT2_SOURCES) # Keep GENERATED_SOURCES at the beginning. This may speed up parallel builds # by starting early the compilation of the largest files. @@ -169,8 +170,13 @@ ifeq ($(USAGE_STATS), yes) COMMON_OBJECTS += ../common/usage_stats.o endif +EDITLINE_OBJECTS := $(addprefix ../mctr2/editline/build/src/.libs/, chared.o common.o \ +emacs.o fgetln.o help.o history.o map.o prompt.o read.o search.o strlcat.o term.o tty.o \ +vi.o wcsdup.o chartype.o el.o fcns.o filecomplete.o hist.o key.o parse.o readline.o \ +refresh.o sig.o strlcpy.o tokenizer.o unvis.o vis.o) + LIBRARY_OBJECTS_NOMAIN := $(filter-out Single_main.o Parallel_main.o ProfMerge_main.o, \ - $(OBJECTS)) $(COMMON_OBJECTS) + $(OBJECTS)) $(COMMON_OBJECTS) $(EDITLINE_OBJECTS) TOBECLEANED := LoggerPlugin_static.o LoggerPlugin_dynamic.o ProfilerTools.profmerge.o @@ -186,7 +192,8 @@ Port.hh Event_Handler.hh Struct_of.hh Array.hh Optional.hh Textbuf.hh Encdec.hh Module_list.hh Parameters.h Addfunc.hh RAW.hh BER.hh TEXT.hh ASN_Null.hh \ ASN_Any.hh ASN_External.hh ASN_EmbeddedPDV.hh ASN_CharacterString.hh XER.hh \ XmlReader.hh cversion.h TitanLoggerControl.ttcn TitanLoggerApi.xsd Vector.hh \ -JSON.hh Profiler.hh RefdIndex.hh ProfilerTools.hh Debugger.hh DebugCommands.hh +JSON.hh Profiler.hh RefdIndex.hh ProfilerTools.hh Debugger.hh DebugCommands.hh \ +DebuggerUI.hh # Copied during "make install" ifdef REGEX_DIR diff --git a/core/Message_types.hh b/core/Message_types.hh index b47fa1526e0271892ee745121342f107f3a4240d..b8873d663237de51200cd3b6c376881c3978a3dd 100644 --- a/core/Message_types.hh +++ b/core/Message_types.hh @@ -7,6 +7,7 @@ * * Contributors: * Balasko, Jeno + * Baranyi, Botond * Forstner, Matyas * Szabo, Janos Zoltan – initial implementation * @@ -104,6 +105,8 @@ #define MSG_UNMAP_REQ 19 #define MSG_UNMAPPED 20 #define MSG_DEBUG_HALT_REQ 101 +#define MSG_DEBUG_CONTINUE_REQ 102 +#define MSG_DEBUG_BATCH 103 /* Messages from MTC to MC (up) */ diff --git a/core/Module_list.cc b/core/Module_list.cc index 48705eeaf9bc54775fab961b1233cddde64d9ec5..f3a90fead19e76f9b57a23ace596426c6f5eafbc 100644 --- a/core/Module_list.cc +++ b/core/Module_list.cc @@ -37,6 +37,7 @@ #endif #include "../common/dbgnew.hh" +#include "Debugger.hh" #include <stdio.h> #include <string.h> @@ -985,6 +986,9 @@ void TTCN_Module::execute_all_testcases() boolean found = FALSE; for (testcase_list_item *list_iter = testcase_head; list_iter != NULL; list_iter = list_iter->next_testcase) { + if (ttcn3_debugger.is_exiting()) { + break; + } if (!list_iter->is_pard) { list_iter->testcase_function(FALSE, 0.0); found = TRUE; diff --git a/core/Param_Types.cc b/core/Param_Types.cc index 1da214635eb7e0fc4ed3316751741a327954875e..8926f32baa14a1d6e61edee7c71fb33b23f0aa45 100644 --- a/core/Param_Types.cc +++ b/core/Param_Types.cc @@ -33,6 +33,8 @@ #include "Universal_charstring.hh" #include "Logger.hh" #include "Module_list.hh" +#include "Debugger.hh" +#include "DebugCommands.hh" size_t Module_Param_Id::get_index() const { @@ -317,6 +319,9 @@ Module_Param_Reference::Module_Param_Reference(Module_Param_Name* p): mp_ref(p) } Module_Param_Ptr Module_Param_Reference::get_referenced_param() const { + if (Debugger_Value_Parsing::happening()) { + error("References to other variables are not allowed."); + } mp_ref->reset(); Module_Param_Ptr ptr = Module_List::get_param(*mp_ref); ptr.set_temporary(); @@ -635,6 +640,31 @@ void Module_Param::error(const char* err_msg, ...) const { Free(exception_str); TTCN_error_end(); } + else if (Debugger_Value_Parsing::happening()) { + char* exception_str = mcopystr("Error while overwriting "); + char* param_ctx; + if (id && id->is_custom()) { + param_ctx = mputstr(id->get_str(), " in the variable"); + } + else { + char* tmp = get_param_context(); + param_ctx = tmp != NULL ? mprintf("variable field '%s'", tmp) : + mcopystr("the variable"); + Free(tmp); + } + exception_str = mputstr(exception_str, param_ctx); + Free(param_ctx); + exception_str = mputstr(exception_str, ": "); + va_list p_var; + va_start(p_var, err_msg); + char* error_msg_str = mprintf_va_list(err_msg, p_var); + va_end(p_var); + exception_str = mputstr(exception_str, error_msg_str); + Free(error_msg_str); + ttcn3_debugger.print(DRET_NOTIFICATION, "%s", exception_str); + Free(exception_str); + throw TC_Error(); // don't log anything in this case + } TTCN_Logger::begin_event(TTCN_Logger::ERROR_UNQUALIFIED); TTCN_Logger::log_event_str("Error while "); switch (operation_type) { @@ -673,19 +703,26 @@ void Module_Param::error(const char* err_msg, ...) const { } void Module_Param::type_error(const char* expected, const char* type_name /* = NULL */) const { - const Module_Param* reporter = this; - // if it's an expression, find its head and use that to report the error - // (since that's the only parameter with a valid name) - while (reporter->parent != NULL && reporter->parent->get_type() == MP_Expression) { - reporter = reporter->parent; + if (Debugger_Value_Parsing::happening()) { + // no references when overwriting a variable through the debugger + error("Type mismatch: %s was expected instead of %s.", expected, get_type_str()); + } + else { + const Module_Param* reporter = this; + // if it's an expression, find its head and use that to report the error + // (since that's the only parameter with a valid name) + while (reporter->parent != NULL && reporter->parent->get_type() == MP_Expression) { + reporter = reporter->parent; + } + // either use this parameter's or the referenced parameter's type string + // (but never the head's type string) + reporter->error("Type mismatch: %s or reference to %s was expected%s%s instead of %s%s.", + expected, expected, + (type_name != NULL) ? " for type " : "", (type_name != NULL) ? type_name : "", + (get_type() == MP_Reference) ? "reference to " : "", + (get_type() == MP_Reference) ? get_referenced_param()->get_type_str() : get_type_str()); } - // either use this parameter's or the referenced parameter's type string - // (but never the head's type string) - reporter->error("Type mismatch: %s or reference to %s was expected%s%s instead of %s%s.", - expected, expected, - (type_name != NULL) ? " for type " : "", (type_name != NULL) ? type_name : "", - (get_type() == MP_Reference) ? "reference to " : "", - (get_type() == MP_Reference) ? get_referenced_param()->get_type_str() : get_type_str()); } bool Ttcn_String_Parsing::string_parsing = false; +bool Debugger_Value_Parsing::is_happening = false; diff --git a/core/Param_Types.hh b/core/Param_Types.hh index adc3ff779c63171c3aa3b18d710673a6aff23ad6..d85ab420294881afc6d7afdc496421183f860cac 100644 --- a/core/Param_Types.hh +++ b/core/Param_Types.hh @@ -685,6 +685,15 @@ public: static bool happening() { return string_parsing; } }; +class Debugger_Value_Parsing { +private: // only instantiation can set it to true and destruction set it back to false + static bool is_happening; +public: + Debugger_Value_Parsing() { is_happening = true; } + ~Debugger_Value_Parsing() { is_happening = false; } + static bool happening() { return is_happening; } +}; + /** Use the configuration file parser to convert a string into a TTCN-3 value. * @param mp_str the converted string (used as if it were a module parameter in a * config file) @@ -695,4 +704,6 @@ public: * be applied to components. */ extern Module_Param* process_config_string2ttcn(const char* mp_str, bool is_component); +extern Module_Param* process_config_debugger_value(const char* mp_str); + #endif diff --git a/core/Single_main.cc b/core/Single_main.cc index f78d7adc58b02e159042ef6dbcf7cad339d6a6b3..b0a615e974f483f0067a28373e6e957024490e8c 100644 --- a/core/Single_main.cc +++ b/core/Single_main.cc @@ -80,11 +80,13 @@ void signal_handler(int signum) static void usage(const char* program_name) { fprintf(stderr, "\n" - "usage: %s configuration_file\n" + "usage: %s [-h] [-b file] configuration_file\n" " or %s -l\n" " or %s -v\n" "\n" "OPTIONS:\n" + " -b file: run specified batch file at start (debugger must be activated)\n" + " -h: automatically halt execution at start (debugger must be activated)\n" " -l: list startable test cases and control parts\n" " -v: show version and module information\n", program_name, program_name, program_name); @@ -105,12 +107,26 @@ int main(int argc, char *argv[]) #endif errno = 0; int c, i, ret_val = EXIT_SUCCESS; - boolean lflag = FALSE, vflag = FALSE, errflag = FALSE; + boolean bflag = FALSE, hflag = FALSE, lflag = FALSE, vflag = FALSE, errflag = FALSE; const char *config_file = NULL; TTCN_Module *only_runnable = Module_List::single_control_part(); - while ((c = getopt(argc, argv, "lv")) != -1) { + while ((c = getopt(argc, argv, "b:hlv")) != -1) { switch (c) { + case 'b': + if (bflag || lflag || vflag) errflag = TRUE; // duplicate or conflicting + else { + bflag = TRUE; + ttcn3_debugger.set_initial_batch_file(optarg); + } + break; + case 'h': + if (hflag || lflag || vflag) errflag = TRUE; // duplicate or conflicting + else { + hflag = TRUE; + ttcn3_debugger.set_halt_at_start(); + } + break; case 'l': if (lflag || vflag) errflag = TRUE; // duplicate or conflicting else lflag = TRUE; @@ -124,13 +140,15 @@ int main(int argc, char *argv[]) } } - if (lflag || vflag) { - if (optind != argc) errflag = TRUE; // -l or -v and non-option arg - } else { - if (optind > argc - 1) { // no config file argument - errflag = (only_runnable == 0); + if (!errflag) { + if (lflag || vflag) { + if (optind != argc) errflag = TRUE; // -l or -v and non-option arg + } else { + if (optind > argc - 1) { // no config file argument + errflag = (only_runnable == 0); + } + else config_file = argv[optind]; } - else config_file = argv[optind]; } if (errflag) { @@ -272,6 +290,9 @@ int main(int argc, char *argv[]) Module_List::post_init_modules(); for (i = 0; i < execute_list_len; i++) { + if (ttcn3_debugger.is_exiting()) { + break; + } if (execute_list[i].testcase_name == NULL) Module_List::execute_control(execute_list[i].module_name); else if (!strcmp(execute_list[i].testcase_name, "*")) diff --git a/core/config_process.l b/core/config_process.l index 3e111129da3eee89f2c08f5c5eafabf3d200f721..a0396e971df43aabccb45920e189158761201dbf 100644 --- a/core/config_process.l +++ b/core/config_process.l @@ -173,7 +173,7 @@ TTCNSTRINGPARSING_COMPONENT "$#&&&(#TTCNSTRINGPARSING_COMPONENT$#&&^#% " {LINECOMMENT} current_line++; {TTCNSTRINGPARSING} { - if (Ttcn_String_Parsing::happening()) { + if (Ttcn_String_Parsing::happening() || Debugger_Value_Parsing::happening()) { BEGIN(SC_MODULE_PARAMETERS); return TtcnStringParsingKeyword; } else { diff --git a/core/config_process.y b/core/config_process.y index cd36e38249bdcfda6262c2dffd2e913888151c26..f9bc7948882e7f8d46b2b5d6a895d162953c93ac 100644 --- a/core/config_process.y +++ b/core/config_process.y @@ -56,6 +56,8 @@ #include "LoggingParam.hh" #include "Profiler.hh" +#include "Debugger.hh" +#include "DebugCommands.hh" #define YYERROR_VERBOSE @@ -71,7 +73,7 @@ static void check_duplicate_option(const char *section_name, const char *option_name, boolean& option_flag); static void check_ignored_section(const char *section_name); static void set_param(Module_Param& module_param); -static unsigned char char_to_hexdigit(char c); +static unsigned char char_to_hexdigit_(char c); static boolean error_flag = FALSE; @@ -397,7 +399,7 @@ all modules in the next module parameter (reduce). GrammarRoot: ConfigFile { - if (Ttcn_String_Parsing::happening()) { + if (Ttcn_String_Parsing::happening() || Debugger_Value_Parsing::happening()) { config_process_error("Config file cannot be parsed as ttcn string"); } } @@ -692,7 +694,7 @@ SimpleParameterValue: for (int i=0; i<n_chars; i++) { if ($1[i]=='?') chars_ptr[i] = 16; else if ($1[i]=='*') chars_ptr[i] = 17; - else chars_ptr[i] = char_to_hexdigit($1[i]); + else chars_ptr[i] = char_to_hexdigit_($1[i]); } Free($1); $$ = new Module_Param_Hexstring_Template(n_chars, chars_ptr); @@ -707,11 +709,11 @@ SimpleParameterValue: else if ($1[i]=='*') num = 257; else { // first digit - num = 16 * char_to_hexdigit($1[i]); + num = 16 * char_to_hexdigit_($1[i]); i++; if (i>=str_len) config_process_error("Unexpected end of octetstring pattern"); // second digit - num += char_to_hexdigit($1[i]); + num += char_to_hexdigit_($1[i]); } octet_vec.push_back(num); } @@ -2167,6 +2169,59 @@ Module_Param* process_config_string2ttcn(const char* mp_str, bool is_component) } } +Module_Param* process_config_debugger_value(const char* mp_str) +{ + if (parsed_module_param != NULL || parsing_error_messages != NULL) { + ttcn3_debugger.print(DRET_NOTIFICATION, + "Internal error: previously parsed TTCN string was not cleared."); + return NULL; + } + // add the hidden keyword + std::string mp_string = std::string("$#&&&(#TTCNSTRINGPARSING$#&&^#% ") + mp_str; + struct yy_buffer_state *flex_buffer = config_process__scan_bytes(mp_string.c_str(), (int)mp_string.size()); + if (flex_buffer == NULL) { + ttcn3_debugger.print(DRET_NOTIFICATION, "Internal error: flex buffer creation failed."); + return NULL; + } + reset_config_process_lex(NULL); + error_flag = FALSE; + try { + Debugger_Value_Parsing debugger_value_parsing; + if (config_process_parse()) { + error_flag = TRUE; + } + } + catch (const TC_Error& TC_error) { + if (parsed_module_param != NULL) { + delete parsed_module_param; + parsed_module_param = NULL; + } + error_flag = TRUE; + } + config_process_close(); + config_process_lex_destroy(); + + if (error_flag || parsing_error_messages != NULL) { + delete parsed_module_param; + parsed_module_param = NULL; + char* pem = parsing_error_messages != NULL ? parsing_error_messages : + mcopystr("Unknown parsing error"); + parsing_error_messages = NULL; + ttcn3_debugger.print(DRET_NOTIFICATION, "%s", pem); + Free(pem); + return NULL; + } + else { + if (parsed_module_param == NULL) { + ttcn3_debugger.print(DRET_NOTIFICATION, "Internal error: could not parse TTCN string."); + return NULL; + } + Module_Param* ret_val = parsed_module_param; + parsed_module_param = NULL; + return ret_val; + } +} + boolean process_config_string(const char *config_string, int string_len) { error_flag = FALSE; @@ -2245,14 +2300,20 @@ boolean process_config_file(const char *file_name) void config_process_error_f(const char *error_str, ...) { - if (Ttcn_String_Parsing::happening()) { + if (Ttcn_String_Parsing::happening() || Debugger_Value_Parsing::happening()) { va_list p_var; va_start(p_var, error_str); char* error_msg_str = mprintf_va_list(error_str, p_var); va_end(p_var); if (parsing_error_messages!=NULL) parsing_error_messages = mputc(parsing_error_messages, '\n'); - parsing_error_messages = mputprintf(parsing_error_messages, - "Parse error in line %d, at or before token `%s': %s", config_process_get_current_line(), config_process_text, error_msg_str); + if (Debugger_Value_Parsing::happening()) { + parsing_error_messages = mputprintf(parsing_error_messages, + "Parse error at or before token `%s': %s", config_process_text, error_msg_str); + } + else { // Ttcn_String_Parsing::happening() + parsing_error_messages = mputprintf(parsing_error_messages, + "Parse error in line %d, at or before token `%s': %s", config_process_get_current_line(), config_process_text, error_msg_str); + } Free(error_msg_str); error_flag = TRUE; return; @@ -2334,13 +2395,13 @@ static void set_param(Module_Param& param) } } -unsigned char char_to_hexdigit(char c) +unsigned char char_to_hexdigit_(char c) { if (c >= '0' && c <= '9') return c - '0'; else if (c >= 'A' && c <= 'F') return c - 'A' + 10; else if (c >= 'a' && c <= 'f') return c - 'a' + 10; else { - config_process_error_f("char_to_hexdigit(): invalid argument: %c", c); + config_process_error_f("char_to_hexdigit_(): invalid argument: %c", c); return 0; // to avoid warning } } diff --git a/core2/Basetype2.cc b/core2/Basetype2.cc index 1ddac029f5783313b5f287a4906a5fc9638c986f..9248c4b83ada915fbe615866bba0a042b2a059b2 100644 --- a/core2/Basetype2.cc +++ b/core2/Basetype2.cc @@ -2468,6 +2468,11 @@ void Record_Of_Type::set_param(Module_Param& param) { Module_Param* const curr = mp->get_elem(i); if (curr->get_type()!=Module_Param::MP_NotUsed) { get_at(i)->set_param(*curr); + if (!get_at(i)->is_bound()) { + // use null pointers for unbound elements + delete val_ptr->value_elements[i]; + val_ptr->value_elements[i] = NULL; + } } } break; @@ -2475,6 +2480,11 @@ void Record_Of_Type::set_param(Module_Param& param) { for (size_t i=0; i<mp->get_size(); ++i) { Module_Param* const current = mp->get_elem(i); get_at(current->get_id()->get_index())->set_param(*current); + if (!get_at(current->get_id()->get_index())->is_bound()) { + // use null pointers for unbound elements + delete val_ptr->value_elements[current->get_id()->get_index()]; + val_ptr->value_elements[current->get_id()->get_index()] = NULL; + } } break; default: diff --git a/etc/xsd/TPD.xsd b/etc/xsd/TPD.xsd index 200dbd202fef065c9a080e2369048debee380ed8..7812e8f45712d0419f88def2def9920d68791650 100644 --- a/etc/xsd/TPD.xsd +++ b/etc/xsd/TPD.xsd @@ -113,6 +113,7 @@ <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="activateDebugger" 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" /> diff --git a/function_test/BER_EncDec/Makefile b/function_test/BER_EncDec/Makefile index 6dbb2c13d24fa789eb30ac9fc72f6bda43d8b78c..5989dd54e61dbe35ef5ecdc0fe5d30cc539bf83f 100644 --- a/function_test/BER_EncDec/Makefile +++ b/function_test/BER_EncDec/Makefile @@ -119,11 +119,11 @@ endif # # Do not modify these unless you know what you are doing... # -SOLARIS_LIBS = -lxnet -L$(XMLDIR)/lib -lxml2 -lresolv -SOLARIS8_LIBS = -lxnet -L$(XMLDIR)/lib -lxml2 -lresolv -lnsl -lsocket -LINUX_LIBS = -L$(XMLDIR)/lib -lxml2 -lpthread -lrt -FREEBSD_LIBS = -L$(XMLDIR)/lib -lxml2 -WIN32_LIBS = -L$(XMLDIR)/lib -lxml2 +SOLARIS_LIBS = -lxnet -L$(XMLDIR)/lib -lxml2 -lresolv -lcurses +SOLARIS8_LIBS = -lxnet -L$(XMLDIR)/lib -lxml2 -lresolv -lnsl -lsocket -lcurses +LINUX_LIBS = -L$(XMLDIR)/lib -lxml2 -lpthread -lrt -lncurses +FREEBSD_LIBS = -L$(XMLDIR)/lib -lxml2 -lncurses +WIN32_LIBS = -L$(XMLDIR)/lib -lxml2 -lncurses # # Rules for building the executable... diff --git a/function_test/RAW_EncDec/Makefile b/function_test/RAW_EncDec/Makefile index 8b7f6f3598206c1d283fa99bef07a283311b9526..56b44142e4787de83534ad22a8cc9dea77a92313 100644 --- a/function_test/RAW_EncDec/Makefile +++ b/function_test/RAW_EncDec/Makefile @@ -113,11 +113,11 @@ endif # # Do not modify these unless you know what you are doing... # -SOLARIS_LIBS = -lxnet -L$(XMLDIR)/lib -lxml2 -SOLARIS8_LIBS = -lxnet -L$(XMLDIR)/lib -lxml2 -lnsl -lsocket -lresolv -LINUX_LIBS = -L$(XMLDIR)/lib -lxml2 -lpthread -lrt -FREEBSD_LIBS = -L$(XMLDIR)/lib -lxml2 -WIN32_LIBS = -L$(XMLDIR)/lib -lxml2 +SOLARIS_LIBS = -lxnet -L$(XMLDIR)/lib -lxml2 -lcurses +SOLARIS8_LIBS = -lxnet -L$(XMLDIR)/lib -lxml2 -lnsl -lsocket -lresolv -lcurses +LINUX_LIBS = -L$(XMLDIR)/lib -lxml2 -lpthread -lrt -lncurses +FREEBSD_LIBS = -L$(XMLDIR)/lib -lxml2 -lncurses +WIN32_LIBS = -L$(XMLDIR)/lib -lxml2 -lncurses # # Rules for building the executable... diff --git a/function_test/Text_EncDec/Makefile b/function_test/Text_EncDec/Makefile index c276d7e747c70d73930af9382e9aa614435bd452..f3d50efeb23bf99f436f868cc0e6aa8f56f63a9b 100644 --- a/function_test/Text_EncDec/Makefile +++ b/function_test/Text_EncDec/Makefile @@ -109,11 +109,11 @@ endif # # Do not modify these unless you know what you are doing... # -SOLARIS_LIBS = -lxnet -L$(XMLDIR)/lib -lxml2 -lresolv -SOLARIS8_LIBS = -lxnet -L$(XMLDIR)/lib -lxml2 -lresolv -lnsl -lsocket -LINUX_LIBS = -L$(XMLDIR)/lib -lxml2 -lpthread -lrt -FREEBSD_LIBS = -L$(XMLDIR)/lib -lxml2 -WIN32_LIBS = -L$(XMLDIR)/lib -lxml2 +SOLARIS_LIBS = -lxnet -L$(XMLDIR)/lib -lxml2 -lresolv -lcurses +SOLARIS8_LIBS = -lxnet -L$(XMLDIR)/lib -lxml2 -lresolv -lnsl -lsocket -lcurses +LINUX_LIBS = -L$(XMLDIR)/lib -lxml2 -lpthread -lrt -lncurses +FREEBSD_LIBS = -L$(XMLDIR)/lib -lxml2 -lncurses +WIN32_LIBS = -L$(XMLDIR)/lib -lxml2 -lncurses # # Rules for building the executable... diff --git a/function_test/XER_EncDec/Makefile b/function_test/XER_EncDec/Makefile index 94ee3ccf76521bdcc66d8dfe575932c4b577aa92..3a31f3cba349400c25ad491d827090c8f5be4ed4 100644 --- a/function_test/XER_EncDec/Makefile +++ b/function_test/XER_EncDec/Makefile @@ -109,11 +109,11 @@ endif # # Do not modify these unless you know what you are doing... # -SOLARIS_LIBS = -lxnet -L$(XMLDIR)/lib -lxml2 -SOLARIS8_LIBS = -lxnet -L$(XMLDIR)/lib -lxml2 -lnsl -lsocket -lresolv -LINUX_LIBS = -L$(XMLDIR)/lib -lxml2 -lpthread -lrt -FREEBSD_LIBS = -L$(XMLDIR)/lib -lxml2 -WIN32_LIBS = -L$(XMLDIR)/lib -lxml2 +SOLARIS_LIBS = -lxnet -L$(XMLDIR)/lib -lxml2 -lcurses +SOLARIS8_LIBS = -lxnet -L$(XMLDIR)/lib -lxml2 -lnsl -lsocket -lresolv -lcurses +LINUX_LIBS = -L$(XMLDIR)/lib -lxml2 -lpthread -lrt -lncurses +FREEBSD_LIBS = -L$(XMLDIR)/lib -lxml2 -lncurses +WIN32_LIBS = -L$(XMLDIR)/lib -lxml2 -lncurses # # Rules for building the executable... diff --git a/mctr2/cli/Cli.cc b/mctr2/cli/Cli.cc index a217c39d0f6756c892137a0c2f6680c3e666a618..3216e558a95b2c45c50b0943a232e89d8b98e28b 100644 --- a/mctr2/cli/Cli.cc +++ b/mctr2/cli/Cli.cc @@ -7,6 +7,7 @@ * * Contributors: * Balasko, Jeno + * Baranyi, Botond * Bene, Tamas * Beres, Szabolcs * Delic, Adam @@ -56,6 +57,7 @@ #define SHELL_TEXT "!" #define EXIT_TEXT "quit" #define EXIT_TEXT2 "exit" +#define BATCH_TEXT "batch" #define SHELL_ESCAPE '!' #define TTCN3_HISTORY_FILENAME ".ttcn3_history" @@ -100,6 +102,8 @@ static const Command command_list[] = { "Execute commands in subshell." }, { EXIT_TEXT, &Cli::exitCallback, EXIT_TEXT, "Exit Main Controller." }, { EXIT_TEXT2, &Cli::exitCallback, EXIT_TEXT2, "Exit Main Controller." }, + { BATCH_TEXT, &Cli::executeBatchFile, BATCH_TEXT " <batch_file>", + "Run commands from batch file." }, { NULL, NULL, NULL, NULL } }; @@ -113,21 +117,24 @@ struct DebugCommand { static const DebugCommand debug_command_list[] = { { D_SWITCH_TEXT, D_SWITCH, D_SWITCH_TEXT " on|off", "Switch the debugger on or off." }, - { D_ADD_BREAKPOINT_TEXT, D_ADD_BREAKPOINT, - D_ADD_BREAKPOINT_TEXT " <module> <line>", - "Add breakpoint at specified location." }, + { D_SET_BREAKPOINT_TEXT, D_SET_BREAKPOINT, + D_SET_BREAKPOINT_TEXT " <module> <line> [<batch_file>]", + "Add a breakpoint at the specified location, or change the batch file of " + " an existing breakpoint." }, { D_REMOVE_BREAKPOINT_TEXT, D_REMOVE_BREAKPOINT, - D_REMOVE_BREAKPOINT_TEXT " <module> <line>", - "Remove breakpoint from specified location." }, - { D_SET_ERROR_BEHAVIOR_TEXT, D_SET_ERROR_BEHAVIOR, - D_SET_ERROR_BEHAVIOR_TEXT " yes|no", - "Set whether to halt test execution when component verdict is set to 'error'." }, - { D_SET_FAIL_BEHAVIOR_TEXT, D_SET_FAIL_BEHAVIOR, - D_SET_FAIL_BEHAVIOR_TEXT " yes|no", - "Set whether to halt test execution when component verdict is set to 'fail'." }, + D_REMOVE_BREAKPOINT_TEXT " all|<module> [all|<line>]", "Remove a breakpoint, " + "or all breakpoints from a module, or all breakpoints from all modules." }, + { D_SET_AUTOMATIC_BREAKPOINT_TEXT, D_SET_AUTOMATIC_BREAKPOINT, + D_SET_AUTOMATIC_BREAKPOINT_TEXT " error|fail on|off [<batch_file>]", + "Switch an automatic breakpoint (truggered by an event) on or off, and/or " + "change its batch file." }, { D_SET_OUTPUT_TEXT, D_SET_OUTPUT, D_SET_OUTPUT_TEXT " console|file|both [file_name]", "Set the output of the debugger." }, + { D_SET_GLOBAL_BATCH_FILE_TEXT, D_SET_GLOBAL_BATCH_FILE, + D_SET_GLOBAL_BATCH_FILE_TEXT " on|off [batch_file_name]", + "Set whether a batch file should be executed automatically when test execution " + "is halted (breakpoint-specific batch files override this setting)." }, { D_SET_COMPONENT_TEXT, D_SET_COMPONENT, D_SET_COMPONENT_TEXT " mtc|<component_reference>", "Set the test component to print debug information from." }, @@ -139,8 +146,9 @@ static const DebugCommand debug_command_list[] = { D_LIST_VARIABLES_TEXT " local|global|comp|all [pattern]", "List variable names." }, { D_PRINT_VARIABLE_TEXT, D_PRINT_VARIABLE, - D_PRINT_VARIABLE_TEXT " <variable_name>[{ <variable_name>}]", - "Print current value of one or more variables." }, + D_PRINT_VARIABLE_TEXT " <variable_name>|$ [{ <variable_name>|$}]", + "Print current value of one or more variables ('$' is substituted with the " + "result of the last " D_LIST_VARIABLES_TEXT " command)." }, { D_OVERWRITE_VARIABLE_TEXT, D_OVERWRITE_VARIABLE, D_OVERWRITE_VARIABLE_TEXT " <variable_name> <value>", "Overwrite the current value of a variable." }, @@ -160,12 +168,6 @@ static const DebugCommand debug_command_list[] = { { D_CONTINUE_TEXT, D_CONTINUE, D_CONTINUE_TEXT, "Resume halted test execution." }, { D_EXIT_TEXT, D_EXIT, D_EXIT_TEXT " test|all", "Exit the current test or the execution of all tests." }, - { D_BATCH_TEXT, D_BATCH, D_BATCH_TEXT " <batch_file_name>", - "Run commands from batch file." }, - { D_SET_HALTING_BATCH_FILE_TEXT, D_SET_HALTING_BATCH_FILE, - D_SET_HALTING_BATCH_FILE_TEXT " yes|no [batch_file_name]", - "Set whether a batch file should be executed automatically when test execution " - "is halted by the debugger." }, { NULL, D_ERROR, NULL, NULL } }; @@ -802,6 +804,35 @@ void Cli::exitCallback(const char *arguments) } } +void Cli::executeBatchFile(const char* filename) +{ + FILE* fp = fopen(filename, "r"); + if (fp == NULL) { + printf("Failed to open file '%s' for reading.\n", filename); + return; + } + else { + printf("Executing batch file '%s'.\n", filename); + } + char line[1024]; + while (fgets(line, sizeof(line), fp) != NULL) { + size_t len = strlen(line); + if (line[len - 1] == '\n') { + line[len - 1] = '\0'; + --len; + } + if (len != 0) { + printf("%s\n", line); + processCommand(line); + } + } + if (!feof(fp)) { + printf("Error occurred while reading batch file '%s' (error code: %d).\n", + filename, ferror(fp)); + } + fclose(fp); +} + //---------------------------------------------------------------------------- // PRIVATE // Command completion function implementation for readline() library. diff --git a/mctr2/cli/Cli.h b/mctr2/cli/Cli.h index a552efa2084d93dbe0356d5e2cadfb4a0183d2f1..190de8f7edbb9c54631f900051d7d221f93a8ef8 100644 --- a/mctr2/cli/Cli.h +++ b/mctr2/cli/Cli.h @@ -90,6 +90,8 @@ public: void helpCallback(const char *arguments); void shellCallback(const char *arguments); void exitCallback(const char *arguments); + + virtual void executeBatchFile(const char* filename); private: /** diff --git a/mctr2/mctr/MainController.cc b/mctr2/mctr/MainController.cc index f4258e16fbfb8cd3fe59a65bd5d02d1144c80c22..64f0dfe6fb6c0b7520b8b02ad61c86c25167e4bc 100644 --- a/mctr2/mctr/MainController.cc +++ b/mctr2/mctr/MainController.cc @@ -8,6 +8,7 @@ * Contributors: * Baji, Laszlo * Balasko, Jeno + * Baranyi, Botond * Bene, Tamas * Feher, Csaba * Forstner, Matyas @@ -2711,7 +2712,8 @@ void MainController::handle_hc_data(host_struct *hc, boolean recv_from_socket) if (recv_len > 0) { try { while (text_buf.is_message()) { - text_buf.pull_int(); // message length + int msg_len = text_buf.pull_int().get_val(); + int msg_end = text_buf.get_pos() + msg_len; int message_type = text_buf.pull_int().get_val(); switch (message_type) { case MSG_ERROR: @@ -2733,7 +2735,7 @@ void MainController::handle_hc_data(host_struct *hc, boolean recv_from_socket) process_hc_ready(hc); break; case MSG_DEBUG_RETURN_VALUE: - process_debug_return_value(*hc->text_buf, hc->log_source, false); + process_debug_return_value(*hc->text_buf, hc->log_source, msg_end, false); break; default: error("Invalid message type (%d) was received on HC " @@ -2874,10 +2876,17 @@ void MainController::handle_tc_data(component_struct *tc, process_unmapped(tc); break; case MSG_DEBUG_RETURN_VALUE: - process_debug_return_value(*tc->text_buf, tc->log_source, tc == mtc); + process_debug_return_value(*tc->text_buf, tc->log_source, message_end, + tc == mtc); break; case MSG_DEBUG_HALT_REQ: - process_debug_halt_req(tc); + process_debug_broadcast_req(tc, D_HALT); + break; + case MSG_DEBUG_CONTINUE_REQ: + process_debug_broadcast_req(tc, D_CONTINUE); + break; + case MSG_DEBUG_BATCH: + process_debug_batch(tc); break; default: if (tc == mtc) { @@ -3098,11 +3107,20 @@ void MainController::clean_up() debugger_settings.output_file = NULL; Free(debugger_settings.error_behavior); debugger_settings.error_behavior = NULL; + Free(debugger_settings.error_batch_file); + debugger_settings.error_batch_file = NULL; Free(debugger_settings.fail_behavior); debugger_settings.fail_behavior = NULL; + Free(debugger_settings.fail_batch_file); + debugger_settings.fail_batch_file = NULL; + Free(debugger_settings.global_batch_state); + debugger_settings.global_batch_state = NULL; + Free(debugger_settings.global_batch_file); + debugger_settings.global_batch_file = NULL; for (int i = 0; i < debugger_settings.nof_breakpoints; ++i) { Free(debugger_settings.breakpoints[i].module); Free(debugger_settings.breakpoints[i].line); + Free(debugger_settings.breakpoints[i].batch_file); } debugger_settings.nof_breakpoints = 0; Free(debugger_settings.breakpoints); @@ -3412,15 +3430,20 @@ void MainController::send_debug_setup(host_struct *hc) Text_Buf text_buf; text_buf.push_int(MSG_DEBUG_COMMAND); text_buf.push_int(D_SETUP); - text_buf.push_int(5 + 2 * debugger_settings.nof_breakpoints); + text_buf.push_int(9 + 3 * debugger_settings.nof_breakpoints); text_buf.push_string(debugger_settings.on_switch); text_buf.push_string(debugger_settings.output_file); text_buf.push_string(debugger_settings.output_type); text_buf.push_string(debugger_settings.error_behavior); + text_buf.push_string(debugger_settings.error_batch_file); text_buf.push_string(debugger_settings.fail_behavior); + text_buf.push_string(debugger_settings.fail_batch_file); + text_buf.push_string(debugger_settings.global_batch_state); + text_buf.push_string(debugger_settings.global_batch_file); for (int i = 0; i < debugger_settings.nof_breakpoints; ++i) { text_buf.push_string(debugger_settings.breakpoints[i].module); text_buf.push_string(debugger_settings.breakpoints[i].line); + text_buf.push_string(debugger_settings.breakpoints[i].batch_file); } send_message(hc->hc_fd, text_buf); } @@ -5415,66 +5438,145 @@ void MainController::process_unmapped(component_struct *tc) status_change(); } -void MainController::process_debug_return_value(Text_Buf& text_buf, char* log_source, bool from_mtc) +void MainController::process_debug_return_value(Text_Buf& text_buf, char* log_source, + int msg_end, bool from_mtc) { int return_type = text_buf.pull_int().get_val(); - timeval tv; - tv.tv_sec = text_buf.pull_int().get_val(); - tv.tv_usec = text_buf.pull_int().get_val(); - char* message = text_buf.pull_string(); - if (return_type == DRET_DATA) { - char* result = mprintf("\n%s", message); - notify(&tv, log_source, TTCN_Logger::DEBUG_UNQUALIFIED, result); - Free(result); - } - else { - if (from_mtc) { - if (return_type == DRET_SETTING_CHANGE) { - switch (last_debug_command.command) { - case D_SWITCH: - Free(debugger_settings.on_switch); - debugger_settings.on_switch = mcopystr(last_debug_command.arguments); + if (text_buf.get_pos() != msg_end) { + timeval tv; + tv.tv_sec = text_buf.pull_int().get_val(); + tv.tv_usec = text_buf.pull_int().get_val(); + char* message = text_buf.pull_string(); + if (return_type == DRET_DATA) { + char* result = mprintf("\n%s", message); + notify(&tv, log_source, TTCN_Logger::DEBUG_UNQUALIFIED, result); + Free(result); + } + else { + notify(&tv, log_source, TTCN_Logger::DEBUG_UNQUALIFIED, message); + } + delete [] message; + } + if (from_mtc) { + if (return_type == DRET_SETTING_CHANGE) { + switch (last_debug_command.command) { + case D_SWITCH: + Free(debugger_settings.on_switch); + debugger_settings.on_switch = mcopystr(last_debug_command.arguments); + break; + case D_SET_OUTPUT: { + Free(debugger_settings.output_type); + Free(debugger_settings.output_file); + debugger_settings.output_file = NULL; + size_t args_len = mstrlen(last_debug_command.arguments); + size_t start = 0; + size_t end = 0; + get_next_argument_loc(last_debug_command.arguments, args_len, start, end); + debugger_settings.output_type = mcopystrn(last_debug_command.arguments + start, end - start); + if (end < args_len) { + start = end; + get_next_argument_loc(last_debug_command.arguments, args_len, start, end); + debugger_settings.output_file = mcopystrn(last_debug_command.arguments + start, end - start); + } + break; } + case D_SET_AUTOMATIC_BREAKPOINT: { + size_t args_len = mstrlen(last_debug_command.arguments); + size_t start = 0; + size_t end = 0; + get_next_argument_loc(last_debug_command.arguments, args_len, start, end); + char* event_str = mcopystrn(last_debug_command.arguments + start, end - start); + char** event_behavior; + char** event_batch_file; + if (!strcmp(event_str, "error")) { + event_behavior = &debugger_settings.error_behavior; + event_batch_file = &debugger_settings.error_batch_file; + } + else if (!strcmp(event_str, "fail")) { + event_behavior = &debugger_settings.fail_behavior; + event_batch_file = &debugger_settings.fail_batch_file; + } + else { // should never happen + Free(event_str); break; - case D_SET_OUTPUT: { - Free(debugger_settings.output_type); - Free(debugger_settings.output_file); - debugger_settings.output_file = NULL; - size_t args_len = mstrlen(last_debug_command.arguments); - size_t start = 0; - size_t end = 0; + } + Free(event_str); + Free(*event_behavior); + Free(*event_batch_file); + *event_batch_file = NULL; + start = end; + get_next_argument_loc(last_debug_command.arguments, args_len, start, end); + *event_behavior = mcopystrn(last_debug_command.arguments + start, end - start); + if (end < args_len) { + start = end; + get_next_argument_loc(last_debug_command.arguments, args_len, start, end); + *event_batch_file = mcopystrn(last_debug_command.arguments + start, end - start); + } + break; } + case D_SET_GLOBAL_BATCH_FILE: { + Free(debugger_settings.global_batch_state); + Free(debugger_settings.global_batch_file); + debugger_settings.global_batch_file = NULL; + size_t args_len = mstrlen(last_debug_command.arguments); + size_t start = 0; + size_t end = 0; + get_next_argument_loc(last_debug_command.arguments, args_len, start, end); + debugger_settings.global_batch_state = mcopystrn(last_debug_command.arguments + start, end - start); + if (end < args_len) { + start = end; get_next_argument_loc(last_debug_command.arguments, args_len, start, end); - debugger_settings.output_type = mcopystrn(last_debug_command.arguments + start, end - start); - if (end < args_len) { - start = end; - get_next_argument_loc(last_debug_command.arguments, args_len, start, end); - debugger_settings.output_file = mcopystrn(last_debug_command.arguments + start, end - start); + debugger_settings.global_batch_file = mcopystrn(last_debug_command.arguments + start, end - start); + } + break; } + case D_SET_BREAKPOINT: { + size_t args_len = mstrlen(last_debug_command.arguments); + size_t start = 0; + size_t end = 0; + get_next_argument_loc(last_debug_command.arguments, args_len, start, end); + char* module = mcopystrn(last_debug_command.arguments + start, end - start); + start = end; + get_next_argument_loc(last_debug_command.arguments, args_len, start, end); + char* line = mcopystrn(last_debug_command.arguments + start, end - start); + char* batch_file = NULL; + if (end < args_len) { + start = end; + get_next_argument_loc(last_debug_command.arguments, args_len, start, end); + batch_file = mcopystrn(last_debug_command.arguments + start, end - start); + } + int pos; + for (pos = 0; pos < debugger_settings.nof_breakpoints; ++pos) { + if (!strcmp(debugger_settings.breakpoints[pos].module, module) && + !strcmp(debugger_settings.breakpoints[pos].line, line)) { + break; } - break; } - case D_SET_ERROR_BEHAVIOR: - Free(debugger_settings.error_behavior); - debugger_settings.error_behavior = mcopystr(last_debug_command.arguments); - break; - case D_SET_FAIL_BEHAVIOR: - Free(debugger_settings.fail_behavior); - debugger_settings.fail_behavior = mcopystr(last_debug_command.arguments); - break; - case D_ADD_BREAKPOINT: { + } + if (pos == debugger_settings.nof_breakpoints) { + // not found, add a new one debugger_settings.breakpoints = (debugger_settings_struct::breakpoint_struct*) Realloc(debugger_settings.breakpoints, (debugger_settings.nof_breakpoints + 1) * sizeof(debugger_settings_struct::breakpoint_struct)); - size_t args_len = mstrlen(last_debug_command.arguments); - size_t start = 0; - size_t end = 0; - get_next_argument_loc(last_debug_command.arguments, args_len, start, end); - debugger_settings.breakpoints[debugger_settings.nof_breakpoints].module = - mcopystrn(last_debug_command.arguments + start, end - start); - start = end; - get_next_argument_loc(last_debug_command.arguments, args_len, start, end); - debugger_settings.breakpoints[debugger_settings.nof_breakpoints].line = - mcopystrn(last_debug_command.arguments + start, end - start); ++debugger_settings.nof_breakpoints; - break; } - case D_REMOVE_BREAKPOINT: { + debugger_settings.breakpoints[pos].module = module; + debugger_settings.breakpoints[pos].line = line; + } + else { + Free(debugger_settings.breakpoints[pos].batch_file); + Free(module); + Free(line); + } + debugger_settings.breakpoints[pos].batch_file = batch_file; + break; } + case D_REMOVE_BREAKPOINT: + if (!strcmp(last_debug_command.arguments, "all")) { + for (int i = 0; i < debugger_settings.nof_breakpoints; ++i) { + Free(debugger_settings.breakpoints[i].module); + Free(debugger_settings.breakpoints[i].line); + Free(debugger_settings.breakpoints[i].batch_file); + } + Free(debugger_settings.breakpoints); + debugger_settings.breakpoints = NULL; + debugger_settings.nof_breakpoints = 0; + } + else { size_t args_len = mstrlen(last_debug_command.arguments); size_t start = 0; size_t end = 0; @@ -5483,53 +5585,68 @@ void MainController::process_debug_return_value(Text_Buf& text_buf, char* log_so start = end; get_next_argument_loc(last_debug_command.arguments, args_len, start, end); char* line = mcopystrn(last_debug_command.arguments + start, end - start); + bool all_in_module = !strcmp(line, "all"); for (int i = 0; i < debugger_settings.nof_breakpoints; ++i) { if (!strcmp(debugger_settings.breakpoints[i].module, module) && - !strcmp(debugger_settings.breakpoints[i].line, line)) { + (all_in_module || !strcmp(debugger_settings.breakpoints[i].line, line))) { Free(debugger_settings.breakpoints[i].module); Free(debugger_settings.breakpoints[i].line); + Free(debugger_settings.breakpoints[i].batch_file); for (int j = i; j < debugger_settings.nof_breakpoints - 1; ++j) { debugger_settings.breakpoints[j] = debugger_settings.breakpoints[j + 1]; } - debugger_settings.breakpoints = (debugger_settings_struct::breakpoint_struct*) - Realloc(debugger_settings.breakpoints, (debugger_settings.nof_breakpoints - 1) * - sizeof(debugger_settings_struct::breakpoint_struct)); --debugger_settings.nof_breakpoints; - break; + if (!all_in_module) { + break; + } } } + debugger_settings.breakpoints = (debugger_settings_struct::breakpoint_struct*) + Realloc(debugger_settings.breakpoints, debugger_settings.nof_breakpoints * + sizeof(debugger_settings_struct::breakpoint_struct)); Free(module); Free(line); - break; } - default: - break; } + break; + default: + break; } - else if (return_type == DRET_EXIT_ALL) { - stop_requested = TRUE; - } } - notify(&tv, log_source, TTCN_Logger::DEBUG_UNQUALIFIED, message); + else if (return_type == DRET_EXIT_ALL) { + stop_requested = TRUE; + } } - delete [] message; } -void MainController::process_debug_halt_req(component_struct* tc) +void MainController::process_debug_broadcast_req(component_struct* tc, int commandID) { - //lock(); - // don't send the halt command back to the requesting component + // don't send the command back to the requesting component if (tc != mtc) { - send_debug_command(mtc->tc_fd, D_HALT, ""); + send_debug_command(mtc->tc_fd, commandID, ""); } for (component i = tc_first_comp_ref; i < n_components; ++i) { component_struct* comp = components[i]; if (tc != comp && comp->tc_state != PTC_STALE && comp->tc_state != TC_EXITED) { - send_debug_command(comp->tc_fd, D_HALT, ""); + send_debug_command(comp->tc_fd, commandID, ""); } } debugger_active_tc = tc; - //status_change(); - //unlock(); + for (int i = 0; i < n_hosts; i++) { + host_struct* host = hosts[i]; + if (host->hc_state != HC_DOWN) { + send_debug_command(hosts[i]->hc_fd, commandID, ""); + } + } +} + +void MainController::process_debug_batch(component_struct* tc) +{ + Text_Buf& text_buf = *tc->text_buf; + const char* batch_file = text_buf.pull_string(); + unlock(); + ui->executeBatchFile(batch_file); + lock(); + delete [] batch_file; } void MainController::process_testcase_started() @@ -5739,7 +5856,11 @@ void MainController::initialize(UserInterface& par_ui, int par_max_ptcs) debugger_settings.output_type = NULL; debugger_settings.output_file = NULL; debugger_settings.error_behavior = NULL; + debugger_settings.error_batch_file = NULL; debugger_settings.fail_behavior = NULL; + debugger_settings.fail_batch_file = NULL; + debugger_settings.global_batch_state = NULL; + debugger_settings.global_batch_file = NULL; debugger_settings.nof_breakpoints = 0; debugger_settings.breakpoints = NULL; last_debug_command.command = D_ERROR; @@ -6401,43 +6522,48 @@ void MainController::debug_command(int commandID, char* arguments) case D_STEP_OVER: case D_STEP_INTO: case D_STEP_OUT: - case D_RUN_TO_CURSOR: // it's a data printing or stepping command, needs to be sent to the // active component - if (debugger_active_tc == NULL) { - // set the MTC as active if test execution hasn't halted and no - // D_SET_COMPONENT command has been issued + if (debugger_active_tc == NULL || + debugger_active_tc->tc_state == PTC_STALE || + debugger_active_tc->tc_state == TC_EXITED) { + // set the MTC as active in the beginning or if the active PTC has + // finished executing debugger_active_tc = mtc; } send_debug_command(debugger_active_tc->tc_fd, commandID, arguments); break; case D_SWITCH: case D_SET_OUTPUT: - case D_SET_ERROR_BEHAVIOR: - case D_SET_FAIL_BEHAVIOR: - case D_ADD_BREAKPOINT: + case D_SET_AUTOMATIC_BREAKPOINT: + case D_SET_GLOBAL_BATCH_FILE: + case D_SET_BREAKPOINT: case D_REMOVE_BREAKPOINT: - // it's a global setting, needs to be sent to all HCs and TCs - for (int i = 0; i < n_hosts; i++) { - send_debug_command(hosts[i]->hc_fd, commandID, arguments); - } - // store this command, the next MSG_DEBUG_RETURN_VALUE message might need it + // it's a global setting, store it, the next MSG_DEBUG_RETURN_VALUE message + // might need it last_debug_command.command = commandID; Free(last_debug_command.arguments); last_debug_command.arguments = mcopystr(arguments); - // no break, send it to TCs, too + // no break + case D_RUN_TO_CURSOR: case D_HALT: case D_CONTINUE: case D_EXIT: - // it's a global setting or a command related to the halted state, - // needs to be sent to all TCs + // it's a global setting, a 'run to' command or a command related to the + // halted state, needs to be sent to all HCs and TCs send_debug_command(mtc->tc_fd, commandID, arguments); for (component i = FIRST_PTC_COMPREF; i < n_components; ++i) { - component_struct *comp = components[i]; + component_struct* comp = components[i]; if (comp != NULL && comp->tc_state != PTC_STALE && comp->tc_state != TC_EXITED) { send_debug_command(comp->tc_fd, commandID, arguments); } } + for (int i = 0; i < n_hosts; i++) { + host_struct* host = hosts[i]; + if (host->hc_state != HC_DOWN) { + send_debug_command(host->hc_fd, commandID, arguments); + } + } break; default: break; @@ -6446,7 +6572,6 @@ void MainController::debug_command(int commandID, char* arguments) else { notify("Cannot execute debug commands before the MTC is created."); } - status_change(); unlock(); } diff --git a/mctr2/mctr/MainController.h b/mctr2/mctr/MainController.h index 4993bffadcbcf62b0b3854dd594d2002164b29b8..1f0f0a00bb7c45f6399734068a41763bb676ffb6 100644 --- a/mctr2/mctr/MainController.h +++ b/mctr2/mctr/MainController.h @@ -8,6 +8,7 @@ * Contributors: * Baji, Laszlo * Balasko, Jeno + * Baranyi, Botond * Bene, Tamas * Czimbalmos, Eduard * Feher, Csaba @@ -247,11 +248,16 @@ struct debugger_settings_struct { char* output_type; char* output_file; char* error_behavior; + char* error_batch_file; char* fail_behavior; + char* fail_batch_file; + char* global_batch_state; + char* global_batch_file; int nof_breakpoints; struct breakpoint_struct { char* module; char* line; + char* batch_file; }* breakpoints; }; @@ -436,6 +442,8 @@ class MainController { static struct sigaction new_action, old_action; static void register_termination_handlers(); static void termination_handler(int signum); + + static void execute_batch_file(const char* file_name); public: static void error(const char *fmt, ...) @@ -588,8 +596,10 @@ private: static void process_mapped(component_struct *tc); static void process_unmap_req(component_struct *tc); static void process_unmapped(component_struct *tc); - static void process_debug_return_value(Text_Buf& text_buf, char* log_source, bool from_mtc); - static void process_debug_halt_req(component_struct *tc); + static void process_debug_return_value(Text_Buf& text_buf, char* log_source, + int msg_end, bool from_mtc); + static void process_debug_broadcast_req(component_struct *tc, int commandID); + static void process_debug_batch(component_struct *tc); /* Incoming messages from MTC */ static void process_testcase_started(); diff --git a/mctr2/mctr/UserInterface.cc b/mctr2/mctr/UserInterface.cc index e645ad8cdda10adff28051887c0334bc092148c4..ead29cf819fda1360b4441b669375e86d340137d 100644 --- a/mctr2/mctr/UserInterface.cc +++ b/mctr2/mctr/UserInterface.cc @@ -34,6 +34,11 @@ void UserInterface::initialize() } +void UserInterface::executeBatchFile(const char* /* filename */) +{ + error(/* severity */ 0, "This user interface does not support batch files."); +} + //---------------------------------------------------------------------------- // Local Variables: // mode: C++ diff --git a/mctr2/mctr/UserInterface.h b/mctr2/mctr/UserInterface.h index 0f534f1467ceef673495d4feb33bd0f243e24056..c3f2267a2484380ead89701a9e0bbcd8859d9267 100644 --- a/mctr2/mctr/UserInterface.h +++ b/mctr2/mctr/UserInterface.h @@ -68,6 +68,8 @@ public: */ virtual void notify(const struct timeval* timestamp, const char* source, int severity, const char* message) = 0; + + virtual void executeBatchFile(const char* filename); }; diff --git a/regression_test/Makefile.regression b/regression_test/Makefile.regression index 9357b044986dedba10c16effb973e69846e5e236..71957f99dddb2b679a8d6863fa8c211ad3caf89d 100644 --- a/regression_test/Makefile.regression +++ b/regression_test/Makefile.regression @@ -175,12 +175,12 @@ else EXESUFFIX := endif # WIN32 -SOLARIS_LIBS = -lxnet -L${XMLDIR}/lib -lxml2 -lresolv -SOLARIS8_LIBS = $(SOLARIS_LIBS) -lresolv -LINUX_LIBS = -L${XMLDIR}/lib -lxml2 -lpthread -lrt -FREEBSD_LIBS = -WIN32_LIBS = -L${XMLDIR}/lib -lxml2 -INTERIX_LIBS = -L${XMLDIR}/lib -lxml2 -liconv +SOLARIS_LIBS = -lxnet -L${XMLDIR}/lib -lxml2 -lresolv -lcurses +SOLARIS8_LIBS = $(SOLARIS_LIBS) -lresolv -lcurses +LINUX_LIBS = -L${XMLDIR}/lib -lxml2 -lpthread -lrt -lncurses +FREEBSD_LIBS = -lncurses +WIN32_LIBS = -L${XMLDIR}/lib -lxml2 -lncurses +INTERIX_LIBS = -L${XMLDIR}/lib -lxml2 -liconv -lncurses # diff --git a/regression_test/XML/XMLqualif/Makefile b/regression_test/XML/XMLqualif/Makefile index 360c2b8b4d14dac90d73c0d09b028e17a56ecdf0..a0c69c23f31f45e42d6aba1a2aa1b0448ab568e6 100644 --- a/regression_test/XML/XMLqualif/Makefile +++ b/regression_test/XML/XMLqualif/Makefile @@ -121,11 +121,11 @@ TARGET = POtest$(EXESUFFIX) # Do not modify these unless you know what you are doing... # Platform specific additional libraries: # -SOLARIS_LIBS = -lsocket -lnsl -lxml2 -lresolv -SOLARIS8_LIBS = -lsocket -lnsl -lxml2 -lresolv -LINUX_LIBS = -lxml2 -lpthread -lrt -FREEBSD_LIBS = -lxml2 -liconv -WIN32_LIBS = -lxml2 -liconv +SOLARIS_LIBS = -lsocket -lnsl -lxml2 -lresolv -lcurses +SOLARIS8_LIBS = -lsocket -lnsl -lxml2 -lresolv -lcurses +LINUX_LIBS = -lxml2 -lpthread -lrt -lncurses +FREEBSD_LIBS = -lxml2 -liconv -lncurses +WIN32_LIBS = -lxml2 -liconv -lncurses # # Rules for building the executable... diff --git a/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_enumeration_restriction3_e.ttcn b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_enumeration_restriction3_e.ttcn new file mode 100644 index 0000000000000000000000000000000000000000..c36a1d358fb4f680f0162e83685a69a2693b33f1 --- /dev/null +++ b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_enumeration_restriction3_e.ttcn @@ -0,0 +1,118 @@ +/******************************************************************************* +* Copyright (c) 2000-2016 Ericsson Telecom AB +* +* XSD to TTCN-3 Translator version: CRL 113 200/5 R5A +* +* 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 +* +* Contributors: +* Balasko, Jeno +* Szabo, Bence Janos +* +*******************************************************************************/ +// +// File: www_example_org_enumeration_restriction3_e.ttcn +// Description: +// References: +// Rev: +// Prodnr: +// Updated: Tue May 31 11:21:08 2015 +// Contact: http://ttcn.ericsson.se +// +//////////////////////////////////////////////////////////////////////////////// +// Generated from file(s): +// - enumeration_restriction3_e.xsd +// /* xml version = "1.0" encoding = "UTF-8" */ +// /* targetnamespace = "www.example.org/enumeration_restriction3/e" */ +//////////////////////////////////////////////////////////////////////////////// +// Modification header(s): +//----------------------------------------------------------------------------- +// Modified by: +// Modification date: +// Description: +// Modification contact: +//------------------------------------------------------------------------------ +//////////////////////////////////////////////////////////////////////////////// + + +module www_example_org_enumeration_restriction3 { + + +import from XSD all; + + +type CType C +with { + variant "element"; +}; + + +type enumerated CType +{ + b2, + uNKNOWN +} +with { + variant "text 'b2' as capitalized"; + variant "text 'uNKNOWN' as capitalized"; +}; + + +type enumerated CTypeEnum +{ + b2 +} +with { + variant "text 'b2' as capitalized"; +}; + + +type CTypeEnum C2 +with { + variant "element"; +}; + + +type enumerated Mountainbikesize +{ + medium, + small +} +with { + variant "name as uncapitalized"; +}; + + +type record FamilyMountainBikeSizes +{ + XSD.String familyMember optional, + Mountainbikesize base +} +with { + variant (familyMember) "attribute"; + variant (base) "untagged"; +}; + + +type record ChildMountainBikeSizes +{ + XSD.String familyMember optional, + enumerated { + small + } base +} +with { + variant (familyMember) "attribute"; + variant (base) "untagged"; +}; + + +} +with { + encode "XML"; + variant "namespace as 'www.example.org/enumeration_restriction3' prefix 'nse'"; + variant "controlNamespace 'http://www.w3.org/2001/XMLSchema-instance' prefix 'xsi'"; +} diff --git a/regression_test/XML/XmlWorkflow/src/xmlTest.prj b/regression_test/XML/XmlWorkflow/src/xmlTest.prj index a4d477c0c68eae1825277b8c3a854c4e37f805da..080be3e59fea336243f73ec3257b18af8da642f2 100644 --- a/regression_test/XML/XmlWorkflow/src/xmlTest.prj +++ b/regression_test/XML/XmlWorkflow/src/xmlTest.prj @@ -163,6 +163,7 @@ <File path="../xsd/including_module.xsd" /> <File path="../xsd/included_without_namespace.xsd" /> <File path="../xsd/list_complextype.xsd" /> + <File path="../xsd/enumeration_restriction3.xsd" /> </File_Group> <File_Group name="XmlTest_xsds" > <File path="../XmlTest_xsds/XmlTest_boolean.xsd" /> @@ -396,6 +397,7 @@ <File path="../XmlTest_expectedTtcns/www_example_org_attribute_enumeration_variant_e.ttcn" /> <File path="../XmlTest_expectedTtcns/www_example_org_including_module_e.ttcn" /> <File path="../XmlTest_expectedTtcns/www_example_org_list_complextype_e.ttcn" /> + <File path="../XmlTest_expectedTtcns/www_example_org_enumeration_restriction3_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 164b88872ea3ed212ec6cdfce9ab38073ae3889a..f78a24b2bcdba4437a3ef5ff5af9a7374a9b7c04 100644 --- a/regression_test/XML/XmlWorkflow/src/xmlTest_Testcases.ttcn +++ b/regression_test/XML/XmlWorkflow/src/xmlTest_Testcases.ttcn @@ -1130,6 +1130,18 @@ group UnionTest { } } + testcase tc_enumeration_restriction3() runs on xmlTest_CT { + + f_shellCommandWithVerdict("xsd2ttcn enumeration_restriction3.xsd","",c_shell_successWithoutWarningAndError) + + if(getverdict==pass) { + f_compareFiles( + "www_example_org_enumeration_restriction3_e.ttcn", + "www_example_org_enumeration_restriction3.ttcn", c_numOfDiff_headerAndModuleName); + } + } + + testcase tc_enumeration_remove_dup() runs on xmlTest_CT { f_shellCommandWithVerdict("xsd2ttcn enumeration_remove_dup.xsd","",c_shell_successWithoutWarningAndError) @@ -2599,6 +2611,7 @@ control { execute(tc_union_optional());//CR_TR18883 execute(tc_enumeration_union_restriction()); execute(tc_enumeration_union_restriction2()); + execute(tc_enumeration_restriction3()); execute(tc_enumeration_remove_dup()); //===complex=== execute(tc_complex1()); //Passed diff --git a/regression_test/XML/XmlWorkflow/xsd/enumeration_restriction3.xsd b/regression_test/XML/XmlWorkflow/xsd/enumeration_restriction3.xsd new file mode 100644 index 0000000000000000000000000000000000000000..8b2e6498131e3fb3ff64e6e87409c25058b022fe --- /dev/null +++ b/regression_test/XML/XmlWorkflow/xsd/enumeration_restriction3.xsd @@ -0,0 +1,53 @@ +<?xml version="1.0" encoding="UTF-8"?> +<schema xmlns="http://www.w3.org/2001/XMLSchema" + targetNamespace="www.example.org/enumeration_restriction3" + xmlns:nse="www.example.org/enumeration_restriction3"> + +<element name="C"> + <simpleType> + <restriction base="nse:CType" /> + </simpleType> +</element> + +<simpleType name="CType"> + <restriction base="string"> + <maxLength value="32" /> + <enumeration value="B2" /> + <enumeration value="UNKNOWN" /> + </restriction> +</simpleType> + +<simpleType name="CTypeEnum"> + <restriction base="nse:CType" > + <enumeration value="B2" /> + </restriction> +</simpleType> + +<element name="C2" type="nse:CTypeEnum"/> + + +<simpleType name="mountainbikesize"> + <restriction base="string"> + <enumeration value="small"/> + <enumeration value="medium"/> + </restriction> +</simpleType> + +<complexType name="FamilyMountainBikeSizes"> + <simpleContent> + <extension base="nse:mountainbikesize"> + <attribute name="familyMember" type="string" /> + </extension> + </simpleContent> +</complexType> + +<complexType name="ChildMountainBikeSizes"> + <simpleContent> + <restriction base="nse:FamilyMountainBikeSizes" > + <enumeration value="small"/> + </restriction> + </simpleContent> +</complexType> + + +</schema> diff --git a/regression_test/XML/xsdConverter/Makefile.converter b/regression_test/XML/xsdConverter/Makefile.converter index 26fc5065bca7418af832b75a23e5f0eb63af9761..b5ff34d4f04a06e4a53e085e9377804f39f00752 100644 --- a/regression_test/XML/xsdConverter/Makefile.converter +++ b/regression_test/XML/xsdConverter/Makefile.converter @@ -29,11 +29,11 @@ OBJECTS = $(GENERATED_SOURCES:.cc=.o) OTHER_FILES = Makefile -SOLARIS_LIBS = -lsocket -lnsl -lxml2 -lresolv -SOLARIS8_LIBS = -lsocket -lnsl -lxml2 -lresolv -LINUX_LIBS = -lxml2 -lpthread -lrt -FREEBSD_LIBS = -lxml2 -WIN32_LIBS = -lxml2 +SOLARIS_LIBS = -lsocket -lnsl -lxml2 -lresolv -lcurses +SOLARIS8_LIBS = -lsocket -lnsl -lxml2 -lresolv -lcurses +LINUX_LIBS = -lxml2 -lpthread -lrt -lncurses +FREEBSD_LIBS = -lxml2 -lncurses +WIN32_LIBS = -lxml2 -lncurses all: $(TARGET) ; diff --git a/regression_test/recofOper/TrecofOper.ttcn b/regression_test/recofOper/TrecofOper.ttcn index b2458f2b3ddd768949ab9d89370cecef4254c319..4014102740ba861cf53bda7908cd9f9a91054586 100644 --- a/regression_test/recofOper/TrecofOper.ttcn +++ b/regression_test/recofOper/TrecofOper.ttcn @@ -1317,6 +1317,30 @@ testcase tc_sizeof_lengthof_standard6() runs on recofOper_mycomp { if(lengthof(tr_roI5)==3) { setverdict(pass)}else { setverdict(fail) }; } +// test cases for bug 494614: +// when initializing a record-of-record element with an empty value ('{}') through module parameters, +// an actual unbound record element was created, instead of the usual null pointer used for unbound elements; +// copying this empty record caused a dynamic test case error + +modulepar recofOper_myrecof3 recofOper_mymodulepar; // initialized with value list notation +modulepar recofOper_myrecof3 recofOper_mymodulepar2; // initialized with assignment notation + +testcase tc_empty_record_element() runs on recofOper_mycomp { + var recofOper_myrecof3 copy := recofOper_mymodulepar; + copy[0].x1 := omit; // this is where the record-of is actually copied, and where the DTE occured + copy[0].x2 := 1.0; + if (copy == { { omit, 1.0 } }) { setverdict(pass); } + else { setverdict(fail); } +} + +testcase tc_empty_record_element2() runs on recofOper_mycomp { + var recofOper_myrecof3 copy := recofOper_mymodulepar2; + copy[0].x1 := omit; // this is where the record-of is actually copied, and where the DTE occured + copy[0].x2 := 1.0; + if (copy == { { omit, 1.0 } }) { setverdict(pass); } + else { setverdict(fail); } +} + control { const recofOper_trecord cl_temp1:={ x1:=omit, x2:=3.4 }; // constants in the control part const recofOper_trecof cl_temp2:={ 'AF12'O }; @@ -1390,6 +1414,9 @@ control { execute(tc_sizeof_lengthof_standard2()); execute(tc_sizeof_lengthof_standard4()); execute(tc_sizeof_lengthof_standard6()); + + execute(tc_empty_record_element()); + execute(tc_empty_record_element2()); } } diff --git a/regression_test/recofOper/config.cfg b/regression_test/recofOper/config.cfg index 1e893b4828997470684056ffa092a4f2dec034d0..eb20bd25a39909fa4d6c2ccbba10cb3465e69afa 100644 --- a/regression_test/recofOper/config.cfg +++ b/regression_test/recofOper/config.cfg @@ -12,6 +12,8 @@ # ############################################################################### [MODULE_PARAMETERS] +recofOper_mymodulepar := { {} } +recofOper_mymodulepar2 := { [0] := {} } [LOGGING] Logfile := "recofOper.log" FileMask := LOG_ALL diff --git a/regression_test/recofOper/config_rt2.cfg b/regression_test/recofOper/config_rt2.cfg index 268d161835b217f0bd97b53bd8603cac18a698a1..7572603a43cb89bf868ef515115976cbc3d36dfe 100644 --- a/regression_test/recofOper/config_rt2.cfg +++ b/regression_test/recofOper/config_rt2.cfg @@ -11,6 +11,8 @@ # ############################################################################### [MODULE_PARAMETERS] +recofOper_mymodulepar := { {} } +recofOper_mymodulepar2 := { [0] := {} } [LOGGING] Logfile := "recofOper.log" FileMask := LOG_ALL diff --git a/titan_executor_api/doc/Titan_Executor_API_User_Guide.doc b/titan_executor_api/doc/Titan_Executor_API_User_Guide.doc index 73ba1539fe791fa4e2cd31d845f49c75c3b7d639..5d4f624838c2ac8a33f5a69ce9b0aa638afffb33 100644 Binary files a/titan_executor_api/doc/Titan_Executor_API_User_Guide.doc and b/titan_executor_api/doc/Titan_Executor_API_User_Guide.doc differ diff --git a/usrguide/PRI.docx b/usrguide/PRI.docx index cc75fcd8f6cbfd51fc82dbc50fe12205178af932..0b9d1d0def62f5332e2cb5a3daacdce8cbc6f506 100644 Binary files a/usrguide/PRI.docx and b/usrguide/PRI.docx differ diff --git a/usrguide/SoC_TITAN.docx b/usrguide/SoC_TITAN.docx new file mode 100644 index 0000000000000000000000000000000000000000..c6a80105fb63b00a53be831d6b6ce6feaf0f6845 Binary files /dev/null and b/usrguide/SoC_TITAN.docx differ diff --git a/usrguide/apiguide.doc b/usrguide/apiguide.doc index bde8b0c4445a8d3e4af061bf2a875cdcfe6fc6c6..b9e3d894a8d9f719e007e304118fbcd975dd08ab 100644 Binary files a/usrguide/apiguide.doc and b/usrguide/apiguide.doc differ diff --git a/usrguide/installationguide.doc b/usrguide/installationguide.doc index 4d700ba39ab78c483dd46b272c3cf3572fd6b419..c72477bdf56b0c95ff8ddc4e423dc294ca6f406a 100644 Binary files a/usrguide/installationguide.doc and b/usrguide/installationguide.doc differ diff --git a/usrguide/referenceguide.doc b/usrguide/referenceguide.doc index e3f879b085398c344d8e1cec0c3cab7849511efb..dbdca14f2a7e1e4c2a47e644da2882ccf5e8ccf3 100644 Binary files a/usrguide/referenceguide.doc and b/usrguide/referenceguide.doc differ diff --git a/usrguide/releasenotes.doc b/usrguide/releasenotes.doc index a8e583d3506fb147d80f06c7512d1091080d0ee7..f1d4f89b329a0a90e1b11c89b1dd4f8481a0a024 100644 Binary files a/usrguide/releasenotes.doc and b/usrguide/releasenotes.doc differ diff --git a/usrguide/userguide.doc b/usrguide/userguide.doc index 94c04f97e01ffcf102fd872dc696db9c2ed57e29..23ea19d352dd74b977f3e4e1fe4e3215aa3fd130 100644 Binary files a/usrguide/userguide.doc and b/usrguide/userguide.doc differ diff --git a/xsdconvert/ComplexType.cc b/xsdconvert/ComplexType.cc index 74cac06614d91ae4ae84ca6619c87dc510f0172a..12dc49b212436f30d4937ca558d008dcc3287af5 100644 --- a/xsdconvert/ComplexType.cc +++ b/xsdconvert/ComplexType.cc @@ -1782,6 +1782,15 @@ void ComplexType::resolveSimpleTypeExtension() { st->addToNameDepList(basefield); basefield->nameDep = st; addNameSpaceAsVariant(basefield, st); + const Mstring old_type = basefield->getType().originalValueWoPrefix; + basefield->applyReference(*st); + // If st has enumeration then the type is restored to the original value + // because enumerations cannot be extended here and this way we just + // create an alias. + if (st->getEnumeration().modified) { + basefield->setTypeValue(old_type); + basefield->getEnumeration().modified = false; + } } } else if(!isBuiltInType(basefield->getType().convertedValue)){ printError(module->getSchemaname(), name.convertedValue, diff --git a/xsdconvert/SimpleType.cc b/xsdconvert/SimpleType.cc index 85fbf8148b7ea12f7b0580e687a056a0d6522562..6f52bc2447a59b1d00db3a7b7d42181bbe10eabb 100644 --- a/xsdconvert/SimpleType.cc +++ b/xsdconvert/SimpleType.cc @@ -1149,8 +1149,11 @@ EnumerationType::EnumerationType(SimpleType * a_simpleType) void EnumerationType::applyReference(const EnumerationType & other) { if (!modified) modified = other.modified; - for (List<Mstring>::iterator facet = other.facets.begin(); facet; facet = facet->Next) { - facets.push_back(facet->Data); + if ((other.parent->getXsdtype() == n_NOTSET && parent->getMode() != SimpleType::restrictionMode) + || parent->getXsdtype() == n_simpleType) { + for (List<Mstring>::iterator facet = other.facets.begin(); facet; facet = facet->Next) { + facets.push_back(facet->Data); + } } }