-!Makefile
+!Makefile
\ No newline at end of file
+******************************************************************************
+* Copyright (c) 2000-2015 Ericsson Telecom AB
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+******************************************************************************
+
Cygwin setup\r
- If Cygwin is installed already, refresh your Cygwin installation\r
Titan is always build for the newest Cygwin version available. \r
-Build and install Titan on Linux\r
-\r
-1.Install required libraries: \r
-(examples are given for Ubuntu 12.04/14.04; for other Linuxes, pls. use the relevant library installation method)\r
-\r
-sudo apt-get install g++ expect libssl-dev libxml2-dev libncurses5-dev flex bison\r
-xutils-dev is needed by makedepend:\r
-sudo apt-get install xutils-dev\r
-The following packages may be needed for titan_eclipse/automatic_build:\r
-sudo apt-get install ant xsltproc\r
-\r
-2.Clone the titan directory from git into /home/<user_id>/titan\r
-\r
-git clone https://github.com/eclipse/titan.core titan\r
-\r
-3. Configure the build \r
-\r
-cd titan\r
-check that MakefileFOSS.cfg is present and has the following content:\r
-cat MakefileFOSS.cfg\r
-\r
-# Configurations for the Free Open Source Software version\r
-LICENSING := no\r
-USAGE_STATS := no\r
-\r
-\r
-Several build options are possible; for details on options , please read through the Makefile.cfg.\r
-Options can be overridden by the content of a file named Makefile.personal which can be used to \r
-adapt to local installation directories, change config options etc.\r
-Below, a small number of typical scenarios are presented.\r
-\r
-1) JNI disabled\r
-\r
-The JNI interface is used by the Eclipse Titan Executor or by the Java Executor API.\r
-If you don't need them , Titan can be compiled without JNI. \r
-\r
-Create ~/titan/Makefile.personal to override settings in Makefile.cfg with the following content:\r
-(replace paths with values relevant to your installation)\r
-\r
-TTCN3_DIR := /home/<user id>/titan/Install\r
-OPENSSL_DIR := /usr\r
-#JDKDIR := /usr/lib/jvm/java-7-openjdk-amd64\r
-XMLDIR := /usr\r
-JNI := no\r
-GEN_PDF := no\r
-\r
-\r
-\r
-\r
-2) JNI enabled\r
-\r
-install JDK into /home/<user id>/jdk\r
-\r
-Create ~/titan/Makefile.personal to override settings in Makefile.cfg with the following content:\r
-(replace paths with values relevant to your installation)\r
-\r
-TTCN3_DIR := /home/<user id>/titan/Install\r
-OPENSSL_DIR := /usr\r
-JDKDIR := /usr/lib/jvm/java-7-openjdk-amd64\r
-XMLDIR := /usr\r
-JNI := yes\r
-GEN_PDF := no\r
-\r
-\r
-\r
-3. Run make\r
-\r
-make\r
-\r
-4. Run make install\r
-\r
-make install\r
-\r
-This will install Titan into /home/<user id>/titan/Install\r
-\r
-5. Optionally , run function/regression tests\r
-\r
-set environment variable TTCN3_DIR to /home/<user id>/titan/Install\r
-\r
-(setenv TTCN3_DIR /home/<user id>/titan/Install for csh,\r
-export TTCN3_DIR=/home/<user id>/titan/Install for bash )\r
-\r
-\r
-\r
-cd /home/<user id>/titan/function_test\r
-\r
-in the following Makefiles \r
-\r
-XER_EncDec/Makefile\r
-Text_EncDec/Makefile\r
-RAW_EncDec/Makefile\r
-\r
-edit the value of XMLDIR to match your installation values \r
-\r
-run the tests\r
-\r
-make\r
-\r
-( or make |& tee outputfile if you want to save the output for verification)\r
-\r
-cd /home/<user id>/titan/regression_test\r
-make run\r
-\r
-( or make run |& tee outputfile if you want to save the output for verification)\r
-\r
-These tests might run for half an hour (regr.tests) to two hours (func.tests)\r
-\r
-6. Optionally , copy Titan into its' final directory.\r
-From here on, you can continue with the Titan installation guide, see /Install/docs, to set environment variables etc.\r
-\r
-\r
-\r
-\r
+******************************************************************************
+* Copyright (c) 2000-2015 Ericsson Telecom AB
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+******************************************************************************
+
+Build and install Titan on Linux
+
+1.Install required libraries:
+(examples are given for Ubuntu 12.04/14.04; for other Linuxes, pls. use the relevant library installation method)
+
+sudo apt-get install g++ expect libssl-dev libxml2-dev libncurses5-dev flex bison
+xutils-dev is needed by makedepend:
+sudo apt-get install xutils-dev
+The following packages may be needed for titan_eclipse/automatic_build:
+sudo apt-get install ant xsltproc
+
+2.Clone the titan directory from git into /home/<user_id>/titan
+
+git clone https://github.com/eclipse/titan.core titan
+
+3. Configure the build
+
+cd titan
+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
+
+
+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.
+
+1) JNI disabled
+
+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.
+
+Create ~/titan/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/Install
+OPENSSL_DIR := /usr
+#JDKDIR := /usr/lib/jvm/java-7-openjdk-amd64
+XMLDIR := /usr
+JNI := no
+GEN_PDF := no
+
+
+
+
+2) JNI enabled
+
+install JDK into /home/<user id>/jdk
+
+Create ~/titan/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/Install
+OPENSSL_DIR := /usr
+JDKDIR := /usr/lib/jvm/java-7-openjdk-amd64
+XMLDIR := /usr
+JNI := yes
+GEN_PDF := no
+
+
+
+3. Run make
+
+make
+
+4. Run make install
+
+make install
+
+This will install Titan into /home/<user id>/titan/Install
+
+5. Optionally , run function/regression tests
+
+set environment variable TTCN3_DIR to /home/<user id>/titan/Install
+
+(setenv TTCN3_DIR /home/<user id>/titan/Install for csh,
+export TTCN3_DIR=/home/<user id>/titan/Install for bash )
+
+
+
+cd /home/<user id>/titan/function_test
+
+in the following Makefiles
+
+XER_EncDec/Makefile
+Text_EncDec/Makefile
+RAW_EncDec/Makefile
+
+edit the value of XMLDIR to match your installation values
+
+run the tests
+
+make
+
+( or make |& tee outputfile if you want to save the output for verification)
+
+cd /home/<user id>/titan/regression_test
+make run
+
+( or make run |& tee outputfile if you want to save the output for verification)
+
+These tests might run for half an hour (regr.tests) to two hours (func.tests)
+
+6. Optionally , copy Titan into its' final directory.
+From here on, you can continue with the Titan installation guide, see /Install/docs, to set environment variables etc.
+
##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.1.pl0-linux32-gcc4.1.0-sles10.tgz
-* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.1.pl0-linux32-gcc4.1.0-sles10.tgz.sha512
-* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.1.pl0-linux32-gcc4.1.2-sled10.2.tgz
-* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.1.pl0-linux32-gcc4.1.2-sled10.2.tgz.sha512
-* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.1.pl0-linux32-gcc4.3-SLED11.1.tgz
-* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.1.pl0-linux32-gcc4.3-SLED11.1.tgz.sha512
-* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.1.pl0-linux64-gcc4.1.2-rhel5.tgz
-* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.1.pl0-linux64-gcc4.1.2-rhel5.tgz.sha512
-* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.1.pl0-linux64-gcc4.3-SLED11.1.tgz
-* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.1.pl0-linux64-gcc4.3-SLED11.1.tgz.sha512
-* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.1.pl0-linux64-gcc4.3-sled11.0.tgz
-* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.1.pl0-linux64-gcc4.3-sled11.0.tgz.sha512
-* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.1.pl0-linux64-gcc4.3-sles11.1.tgz
-* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.1.pl0-linux64-gcc4.3-sles11.1.tgz.sha512
-* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.1.pl0-linux64-gcc4.4.5-rhel6.tgz
-* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.1.pl0-linux64-gcc4.4.5-rhel6.tgz.sha512
-* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.1.pl0-linux64-gcc4.6-ubuntu12.04.tgz
-* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.1.pl0-linux64-gcc4.6-ubuntu12.04.tgz.sha512
-* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.1.pl0-linux64-gcc4.8-ubuntu14.04.tgz
-* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.1.pl0-linux64-gcc4.8-ubuntu14.04.tgz.sha512
+* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.2.pl0-linux32-gcc4.1.0-sles10.tgz
+* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.2.pl0-linux32-gcc4.1.0-sles10.tgz.sha512
+* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.2.pl0-linux32-gcc4.1.2-sled10.2.tgz
+* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.2.pl0-linux32-gcc4.1.2-sled10.2.tgz.sha512
+* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.2.pl0-linux32-gcc4.3-SLED11.1.tgz
+* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.2.pl0-linux32-gcc4.3-SLED11.1.tgz.sha512
+* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.2.pl0-linux64-gcc4.1.2-rhel5.tgz
+* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.2.pl0-linux64-gcc4.1.2-rhel5.tgz.sha512
+* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.2.pl0-linux64-gcc4.3-SLED11.1.tgz
+* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.2.pl0-linux64-gcc4.3-SLED11.1.tgz.sha512
+* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.2.pl0-linux64-gcc4.3-sled11.0.tgz
+* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.2.pl0-linux64-gcc4.3-sled11.0.tgz.sha512
+* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.2.pl0-linux64-gcc4.3-sles11.1.tgz
+* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.2.pl0-linux64-gcc4.3-sles11.1.tgz.sha512
+* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.2.pl0-linux64-gcc4.4.5-rhel6.tgz
+* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.2.pl0-linux64-gcc4.4.5-rhel6.tgz.sha512
+* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.2.pl0-linux64-gcc4.6-ubuntu12.04.tgz
+* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.2.pl0-linux64-gcc4.6-ubuntu12.04.tgz.sha512
+* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.2.pl0-linux64-gcc4.8-ubuntu14.04.tgz
+* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.2.pl0-linux64-gcc4.8-ubuntu14.04.tgz.sha512
# Related products:
--- /dev/null
+# titan.core
+
+TTCN-3 is a standardized, modular language specifically designed for testing.
+Eclipse Titan offers a free and open source (FOSS) compiler both for TTCN-3 and for
+ASN.1 (Abstract Syntax Notation One).
+
+# Standards page (also including downloadable code):
+
+* http://www.ttcn-3.org/
+
+# Main project page:
+
+* https://projects.eclipse.org/projects/tools.titan
+
+##Introductory video of a presentation about Titan held at EclipseCon 2014:
+* https://www.youtube.com/watch?v=2knzZuwzn-Y.
+
+##Titan Datasheet on polarsys.org:
+http://polarsys.org/sites/default/files/custom_uploads/TITAN%20Datasheet%20A4%202.1.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.1.pl0-linux32-gcc4.1.0-sles10.tgz
+* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.1.pl0-linux32-gcc4.1.0-sles10.tgz.sha512
+* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.1.pl0-linux32-gcc4.1.2-sled10.2.tgz
+* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.1.pl0-linux32-gcc4.1.2-sled10.2.tgz.sha512
+* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.1.pl0-linux32-gcc4.3-SLED11.1.tgz
+* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.1.pl0-linux32-gcc4.3-SLED11.1.tgz.sha512
+* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.1.pl0-linux64-gcc4.1.2-rhel5.tgz
+* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.1.pl0-linux64-gcc4.1.2-rhel5.tgz.sha512
+* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.1.pl0-linux64-gcc4.3-SLED11.1.tgz
+* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.1.pl0-linux64-gcc4.3-SLED11.1.tgz.sha512
+* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.1.pl0-linux64-gcc4.3-sled11.0.tgz
+* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.1.pl0-linux64-gcc4.3-sled11.0.tgz.sha512
+* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.1.pl0-linux64-gcc4.3-sles11.1.tgz
+* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.1.pl0-linux64-gcc4.3-sles11.1.tgz.sha512
+* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.1.pl0-linux64-gcc4.4.5-rhel6.tgz
+* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.1.pl0-linux64-gcc4.4.5-rhel6.tgz.sha512
+* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.1.pl0-linux64-gcc4.6-ubuntu12.04.tgz
+* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.1.pl0-linux64-gcc4.6-ubuntu12.04.tgz.sha512
+* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.1.pl0-linux64-gcc4.8-ubuntu14.04.tgz
+* https://www.eclipse.org/downloads/download.php?file=/titan/ttcn3-5.1.pl0-linux64-gcc4.8-ubuntu14.04.tgz.sha512
+
+
+# Related products:
+
+## Test Ports:
+
+* https://github.com/eclipse/titan.TestPorts.Common_Components.Abstract_Socket
+* https://github.com/eclipse/titan.TestPorts.HTTPmsg
+* https://github.com/eclipse/titan.TestPorts.LANL2asp
+* https://github.com/eclipse/titan.TestPorts.PCAPasp
+* https://github.com/eclipse/titan.TestPorts.PIPEasp
+* https://github.com/eclipse/titan.TestPorts.SCTPasp
+* https://github.com/eclipse/titan.TestPorts.SIPmsg
+* https://github.com/eclipse/titan.TestPorts.SQLasp
+* https://github.com/eclipse/titan.TestPorts.TCPasp
+* https://github.com/eclipse/titan.TestPorts.TELNETasp
+* https://github.com/eclipse/titan.TestPorts.UDPasp
+
+
+## Protocol Modules:
+
+* https://github.com/eclipse/titan.ProtocolModules.COMMON
+* https://github.com/eclipse/titan.ProtocolModules.DHCP
+* https://github.com/eclipse/titan.ProtocolModules.DHCPv6
+* https://github.com/eclipse/titan.ProtocolModules.DIAMETER_ProtocolModule_Generator
+* https://github.com/eclipse/titan.ProtocolModules.DNS
+* https://github.com/eclipse/titan.ProtocolModules.ICMP
+* https://github.com/eclipse/titan.ProtocolModules.ICMPv6
+* https://github.com/eclipse/titan.ProtocolModules.IP
+* https://github.com/eclipse/titan.ProtocolModules.RTP
+* https://github.com/eclipse/titan.ProtocolModules.RTSP
+* https://github.com/eclipse/titan.ProtocolModules.SMPP
+* https://github.com/eclipse/titan.ProtocolModules.SMTP
+* https://github.com/eclipse/titan.ProtocolModules.SNMP
+* https://github.com/eclipse/titan.ProtocolModules.TCP
+* https://github.com/eclipse/titan.ProtocolModules.UDP
+* https://github.com/eclipse/titan.ProtocolModules.XMPP
--- /dev/null
+******************************************************************************
+* Copyright (c) 2000-2015 Ericsson Telecom AB
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+******************************************************************************
+
+MinGW setup
+
+ (A) Download the MinGW installer from the MinGW site:
+ http://www.mingw.org/
+
+ (B) Follow the install steps found on the MinGW getting started page:
+ http://www.mingw.org/wiki/getting_started
+ Select the mingw-gcc-v3 packages because Titan only compiles
+ with older gcc. If you select the gcc4 packages, then the make process
+ stops immediately with some error messages. Select the msys packages too.
+
+ (C) Check the PATH system variable:
+ System -> Advanced system settings -> Environment Variables -> Path
+ The MinGW installation path must be present to use the installed
+ executables and files. For example:
+ echo %PATH%
+ C:\MinGW\bin;C:\MinGW\usr\bin...
+
+ (D) Working environment:
+ Use the <Install folder>\msys\<version>\msys.bat file to start a shell.
+ Download and extract the Titan source files and folders to a directory,
+ and create a Makefile.personal in the top directory. Please check the
+ installation guide and set all the needed variables like TTCN3_DIR. The
+ MinGW compilation needs a few extra changes in the Makefile.cfg also. Set
+ the PLATFORM and MINGW values:
+ PLATFORM := WIN32
+ MINGW := -DMINGW -mno-cygwin
+
+ (E) Compile Titan:
+ cd titan
+ make -j
+ make install
+ The compiled files will be placed into the ./Install directory.
+
+ (F) If the build process stops with a Windows error message saying that some files
+ are missing, search for the indicated Cygwin package and download it from the Cygwin page.
+ You can search fast and easily with the Cygwin Package Search tool:
+ https://cygwin.com/cgi-bin2/package-grep.cgi
+ Extract the downloaded package into the MinGW installation directory, and
+ restart the build process.
}
"["{WS}LOGGING{WS}"]" BEGIN(INITIAL);
+"["{WS}PROFILER{WS}"]" BEGIN(INITIAL);
"["{WS}EXECUTE{WS}"]" BEGIN(INITIAL);
"["{WS}EXTERNAL_COMMANDS{WS}"]" BEGIN(INITIAL);
"["{WS}GROUPS{WS}"]" BEGIN(INITIAL);
/* Version numbers */
#define TTCN3_MAJOR 5
-#define TTCN3_MINOR 1
+#define TTCN3_MINOR 2
#define TTCN3_PATCHLEVEL 0
//#define TTCN3_BUILDNUMBER 0
* TTCN3_VERSION = TTCN3_MAJOR * 1000000 + TTCN3_MINOR * 10000 +
* TTCN3_PATCHLEVEL * 100 + TTCN3_BUILDNUMBER
*/
-#define TTCN3_VERSION 50100
+#define TTCN3_VERSION 50200
/* A monotonically increasing version number.
* An official release is deemed to have the highest possible build number (99)
return versions;
}
- void Modules::add_types_to_json_schema(JSON_Tokenizer& json)
+ void Modules::generate_json_schema(JSON_Tokenizer& json, map<Type*, JSON_Tokenizer>& json_refs)
{
for(size_t i = 0; i < mods_v.size(); ++i) {
- mods_v[i]->add_types_to_json_schema(json);
- }
- }
-
- void Modules::add_func_to_json_schema(map<Type*, JSON_Tokenizer>& json_refs)
- {
- for(size_t i = 0; i < mods_v.size(); ++i) {
- mods_v[i]->add_func_to_json_schema(json_refs);
+ mods_v[i]->generate_json_schema(json, json_refs);
}
}
mputprintf(effective_module_functions, "%s\"%s\"",
(effective_module_functions ? ", " : ""), get_modid().get_dispname().c_str());
}
+ if (profiler_enabled && MOD_TTCN == get_moduletype()) {
+ output->source.static_function_bodies = mputprintf(output->source.static_function_bodies,
+ "TTCN3_Stack_Depth stack_depth;\n"
+ "ttcn3_prof.enter_function(\"%s\", 0, \"%s\");\n",
+ get_filename(), get_modid().get_dispname().c_str());
+ }
}
output->source.static_function_bodies =
mputstr(output->source.static_function_bodies, output->functions.pre_init);
mputprintf(effective_module_functions, "%s\"%s\"",
(effective_module_functions ? ", " : ""), get_modid().get_dispname().c_str());
}
+ if (profiler_enabled && MOD_TTCN == get_moduletype()) {
+ output->source.static_function_bodies = mputprintf(output->source.static_function_bodies,
+ "TTCN3_Stack_Depth stack_depth;\n"
+ "ttcn3_prof.enter_function(\"%s\", 0, \"%s\");\n",
+ get_filename(), get_modid().get_dispname().c_str());
+ }
}
output->source.static_function_bodies =
mputstr(output->source.static_function_bodies, output->functions.post_init);
void generate_code(CodeGenHelper& cgh);
void dump(unsigned level=1) const;
- /** Generates JSON schema segments for the types defined in the modules
- * and adds them to the JSON schema parameter. */
- void add_types_to_json_schema(JSON_Tokenizer& json);
-
- /** Generates JSON schemas containing references to the types defined in the
- * modules. Information related to the types' JSON encoding and decoding
- * functions is also inserted after the references. */
- void add_func_to_json_schema(map<Type*, JSON_Tokenizer>& json_refs);
+ /** Generates JSON schema segments for the types defined in the modules,
+ * and references to these types. Information related to the types'
+ * JSON encoding and decoding functions is also inserted after the references.
+ *
+ * @param json JSON document containing the main schema, schema segments for
+ * the types will be inserted here
+ * @param json_refs map of JSON documents containing the references and function
+ * info related to each type */
+ void generate_json_schema(JSON_Tokenizer& json, map<Type*, JSON_Tokenizer>& json_refs);
};
/**
void generate_code(CodeGenHelper& cgh);
virtual void dump(unsigned level) const;
- /** Generates JSON schema segments for the types defined in the module
- * and adds them to the JSON schema parameter. */
- virtual void add_types_to_json_schema(JSON_Tokenizer&) = 0;
-
- /** Generates JSON schemas containing references to the types that have JSON
- * encoding and/or decoding functions declared in the module. Information
- * related to these functions is also inserted after the references
- * (only for TTCN-3 modules). */
- virtual void add_func_to_json_schema(map<Type*, JSON_Tokenizer>&) = 0;
+ /** Generates JSON schema segments for the types defined in the modules,
+ * and references to these types. Information related to the types'
+ * JSON encoding and decoding functions is also inserted after the references.
+ *
+ * @param json JSON document containing the main schema, schema segments for
+ * the types will be inserted here
+ * @param json_refs map of JSON documents containing the references and function
+ * info related to each type */
+ virtual void generate_json_schema(JSON_Tokenizer& json, map<Type*, JSON_Tokenizer>& json_refs) = 0;
};
/**
if (++error_count >= max_errors) {
fputs("Maximum number of errors reached, aborting.\n", stderr);
fflush(stderr);
- abort();
+ exit(EXIT_FAILURE);
}
}
Type.cc Type_chk.cc Type_codegen.cc TypeCompat.cc \
Typestuff.cc ustring.cc Value.cc Valuestuff.cc XerAttributes.cc subtypestuff.cc CodeGenHelper.cc
-MFGEN_SOURCES := makefile.c xpather.cc
+MFGEN_SOURCES := makefile.c xpather.cc ProjectGenHelper.cc
TCOV2LCOV_SOURCES := tcov2lcov.cc
--- /dev/null
+///////////////////////////////////////////////////////////////////////////////\r
+// Copyright (c) 2000-2014 Ericsson Telecom AB\r
+// All rights reserved. This program and the accompanying materials\r
+// are made available under the terms of the Eclipse Public License v1.0\r
+// which accompanies this distribution, and is available at\r
+// http://www.eclipse.org/legal/epl-v10.html\r
+///////////////////////////////////////////////////////////////////////////////\r
+#include "ProjectGenHelper.hh"\r
+#include "../common/memory.h"\r
+\r
+#include "error.h"\r
+#include <limits>\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+\r
+const std::string ProjectDescriptor::emptyString = std::string();\r
+\r
+ProjectDescriptor::ProjectDescriptor(const char * name) :\r
+ projectName(std::string(name)),\r
+ tpdFileName(),\r
+ targetExecutableName(),\r
+ projectAbsTpdDir(),\r
+ projectAbsWorkingDir(),\r
+ projectWorkingDir(),\r
+ library(false),\r
+ dynamicLinked(false),\r
+ referencedProjects(),\r
+ refProjWorkingDirs(),\r
+ libSearchPaths(),\r
+ linkerLibraries(),\r
+ ttcn3ModuleNames(),\r
+ asn1ModuleNames(),\r
+ userSources(),\r
+ userHeaders(),\r
+ ttcnPP(),\r
+ initialized(false)\r
+{}\r
+\r
+void ProjectDescriptor::cleanUp()\r
+{\r
+ referencedProjects.clear();\r
+ refProjWorkingDirs.clear(),\r
+ libSearchPaths.clear();\r
+ linkerLibraries.clear();\r
+ ttcn3ModuleNames.clear();\r
+ asn1ModuleNames.clear();\r
+ userSources.clear();\r
+ userHeaders.clear();\r
+ ttcnPP.clear();\r
+}\r
+\r
+bool ProjectDescriptor::isInitialized()\r
+{\r
+ if (!projectName.empty() &&\r
+ !targetExecutableName.empty() &&\r
+ !projectAbsTpdDir.empty() &&\r
+ !projectAbsWorkingDir.empty() &&\r
+ !projectWorkingDir.empty())\r
+ initialized = true;\r
+ return initialized;\r
+}\r
+\r
+void ProjectDescriptor::setTPDFileName(const char* name)\r
+{\r
+ const char SEPARATOR = '/';\r
+ std::string fileName(name);\r
+ size_t refProjPos = fileName.find_last_of(SEPARATOR);\r
+ if (std::string::npos == refProjPos) {\r
+ tpdFileName = fileName;\r
+ }\r
+ else {\r
+ tpdFileName = fileName.substr(refProjPos + 1);\r
+ }\r
+}\r
+\r
+void ProjectDescriptor::setProjectAbsWorkingDir(const char* name)\r
+{\r
+ if (!name) {\r
+ ERROR("No path was given to the working directory. Check if 'r' flag is set ");\r
+ return;\r
+ }\r
+ projectAbsWorkingDir = std::string(name);\r
+ ProjectGenHelper::Instance().setRootDirOS(name);\r
+}\r
+\r
+void ProjectDescriptor::addToReferencedProjects(const char* refProjName)\r
+{\r
+ std::vector<std::string>::iterator it;\r
+ for (it = referencedProjects.begin(); it != referencedProjects.end(); ++it) {\r
+ if (*it == std::string(refProjName)) return;\r
+ }\r
+ referencedProjects.push_back(std::string(refProjName));\r
+}\r
+\r
+void ProjectDescriptor::addToRefProjWorkingDirs(const std::string& subProjDir)\r
+{\r
+ std::vector<std::string>::iterator it;\r
+ for (it = refProjWorkingDirs.begin(); it != refProjWorkingDirs.end(); ++it) {\r
+ if (*it == subProjDir) return;\r
+ }\r
+ refProjWorkingDirs.push_back(subProjDir);\r
+}\r
+\r
+bool ProjectDescriptor::hasLinkerLibTo(const std::string& refProjName) const\r
+{\r
+ ProjectDescriptor* refProj = ProjectGenHelper::Instance().getTargetOfProject(refProjName.c_str());\r
+ for (size_t i = 0; i < referencedProjects.size(); ++i){\r
+ if (refProj && refProj->library) return true;\r
+ }\r
+ return false;\r
+}\r
+\r
+bool ProjectDescriptor::hasLinkerLib(const char* libName) const\r
+{\r
+ std::string linkerLibName(libName);\r
+ std::vector<std::string>::const_iterator it;\r
+ for (it = linkerLibraries.begin(); it != linkerLibraries.end(); ++it) {\r
+ if (*it == linkerLibName) return true;\r
+ }\r
+ return false;\r
+}\r
+\r
+void ProjectDescriptor::addToLibSearchPaths(const char* libSearchPath)\r
+{\r
+ std::string searchPath(libSearchPath);\r
+ std::vector<std::string>::iterator it;\r
+ for (it = libSearchPaths.begin(); it != libSearchPaths.end(); ++it) {\r
+ if (*it == searchPath) return;\r
+ }\r
+ libSearchPaths.push_back(libSearchPath);\r
+}\r
+\r
+void ProjectDescriptor::addToLinkerLibs(const char* linkerLibs)\r
+{\r
+ std::string llibs(linkerLibs);\r
+ std::vector<std::string>::iterator it;\r
+ for (it = linkerLibraries.begin(); it != linkerLibraries.end(); ++it) {\r
+ if (*it == llibs) return;\r
+ }\r
+ linkerLibraries.push_back(linkerLibs);\r
+}\r
+\r
+size_t ProjectDescriptor::getLibSearchPathIndex(const std::string& subProjName) const\r
+{\r
+\r
+ for (size_t i = 0; i < libSearchPaths.size(); ++i) {\r
+ if (std::string::npos != libSearchPaths[i].find(subProjName))\r
+ return i;\r
+ }\r
+ return std::numeric_limits<unsigned int>::max();\r
+}\r
+\r
+const char* ProjectDescriptor::getLibSearchPath(const std::string& subProjName) const\r
+{\r
+ for (size_t i = 0; i < libSearchPaths.size(); ++i) {\r
+ if (std::string::npos != libSearchPaths[i].find(subProjName))\r
+ return libSearchPaths[i].c_str();\r
+ }\r
+ return NULL;\r
+}\r
+\r
+bool ProjectDescriptor::hasTtcn3ModuleName(const char* moduleName) const\r
+{\r
+ std::string modName(moduleName);\r
+ std::vector<std::string>::const_iterator it;\r
+ for (it = ttcn3ModuleNames.begin(); it != ttcn3ModuleNames.end(); ++it) {\r
+ if (*it == modName) return true;\r
+ }\r
+ return false;\r
+}\r
+\r
+bool ProjectDescriptor::hasAsn1ModuleName(const char* moduleName) const\r
+{\r
+ std::string modName(moduleName);\r
+ std::vector<std::string>::const_iterator it;\r
+ for (it = asn1ModuleNames.begin(); it != asn1ModuleNames.end(); ++it) {\r
+ if (*it == modName) return true;\r
+ }\r
+ return false;\r
+}\r
+\r
+bool ProjectDescriptor::hasUserSource(const char* userSourceName) const\r
+{\r
+ std::string sourceName(userSourceName);\r
+ std::vector<std::string>::const_iterator it;\r
+ for (it = userSources.begin(); it != userSources.end(); ++it) {\r
+ if (*it == sourceName) return true;\r
+ }\r
+ return false;\r
+}\r
+\r
+bool ProjectDescriptor::hasUserHeader(const char* userHeaderName) const\r
+{\r
+ std::string headerName(userHeaderName);\r
+ std::vector<std::string>::const_iterator it;\r
+ for (it = userHeaders.begin(); it != userHeaders.end(); ++it) {\r
+ if (*it == headerName) return true;\r
+ }\r
+ return false;\r
+}\r
+\r
+bool ProjectDescriptor::hasTtcn3PP(const char* ttcnPPName) const\r
+{\r
+ std::string ttcnPPFile(ttcnPPName);\r
+ std::vector<std::string>::const_iterator it;\r
+ for (it = ttcnPP.begin(); it != ttcnPP.end(); ++it) {\r
+ if (*it == ttcnPPFile) return true;\r
+ }\r
+ return false;\r
+}\r
+\r
+std::string ProjectDescriptor::setRelativePathTo(const std::string& absPathTo)\r
+{\r
+ if (projectAbsWorkingDir.empty()) return std::string();\r
+ const char SEPARATOR = '/';\r
+ if (projectAbsWorkingDir.at(0) != SEPARATOR || absPathTo.at(0) != SEPARATOR) \r
+ ERROR("Expecting absolute path to generate LinkerLibSearchPath ");\r
+ size_t length = projectAbsWorkingDir.size() > absPathTo.size() ? absPathTo.size() : projectAbsWorkingDir.size();\r
+ size_t lastSlash = 0;\r
+ size_t i;\r
+ for(i = 0; i < length && projectAbsWorkingDir.at(i) == absPathTo.at(i); ++i) {\r
+ if (projectAbsWorkingDir.at(i) == SEPARATOR && absPathTo.at(i) == SEPARATOR) {\r
+ lastSlash = i; // the same path until now...\r
+ }\r
+ }\r
+ if (length == i) { // got subdirectory\r
+ if (projectAbsWorkingDir == absPathTo) {\r
+ return std::string("."); // the same pathes were given \r
+ }\r
+ else if ((projectAbsWorkingDir.size() > absPathTo.size() && projectAbsWorkingDir.at(length) == SEPARATOR) ||\r
+ (projectAbsWorkingDir.size() < absPathTo.size() && absPathTo.at(length) == SEPARATOR))\r
+ lastSlash = length;\r
+ }\r
+\r
+ size_t slashCount = 0;\r
+ for (size_t i = lastSlash; i < projectAbsWorkingDir.size(); ++i) {\r
+ if (projectAbsWorkingDir.at(i) == SEPARATOR)\r
+ ++slashCount;\r
+ }\r
+\r
+ std::string relPath;\r
+ const std::string upDir("../");\r
+ for (size_t i = 0; i < slashCount; ++i)\r
+ relPath.append(upDir);\r
+\r
+ std::string pathTo = absPathTo.substr(lastSlash+1); // we left the heading slash\r
+ relPath.append(pathTo);\r
+ return std::string(relPath);\r
+}\r
+\r
+void ProjectDescriptor::print()\r
+{\r
+ fprintf( stderr, "project name %s and it is %s initialized\n", projectName.c_str(), isInitialized() ? "" : "not");\r
+ fprintf( stderr, " target executable name %s\n",targetExecutableName.c_str());\r
+ fprintf( stderr, " project abs TPD dir %s\n", projectAbsTpdDir.c_str());\r
+ fprintf( stderr, " project abs working dir %s\n", projectAbsWorkingDir.c_str());\r
+ fprintf( stderr, " project working dir %s\n", projectWorkingDir.c_str());\r
+ fprintf( stderr, " project is %s\n", library ? "Library" : "Executable");\r
+ fprintf( stderr, " project linking is %s\n", dynamicLinked ? "dynamic" : "static");\r
+ std::vector<std::string>::iterator it;\r
+ for (it = referencedProjects.begin(); it != referencedProjects.end(); ++it) {\r
+ fprintf( stderr, " Referenced project %s\n",(*it).c_str());\r
+ }\r
+ for (it = refProjWorkingDirs.begin(); it != refProjWorkingDirs.end(); ++it) {\r
+ fprintf( stderr, " Working dir of referenced project %s\n",(*it).c_str());\r
+ }\r
+ for (it = linkerLibraries.begin(); it != linkerLibraries.end(); ++it) {\r
+ fprintf( stderr, " Linker library %s\n", (*it).c_str());\r
+ }\r
+ for (it = libSearchPaths.begin(); it != libSearchPaths.end(); ++it) {\r
+ fprintf( stderr, " Linker lib search path %s\n", (*it).c_str());\r
+ }\r
+ for (it = ttcn3ModuleNames.begin(); it != ttcn3ModuleNames.end(); ++it) {\r
+ fprintf( stderr, " TTCN3 Module Name: %s\n", (*it).c_str());\r
+ }\r
+ for (it = asn1ModuleNames.begin(); it != asn1ModuleNames.end(); ++it) {\r
+ fprintf( stderr, " ASN1 Module Name: %s\n", (*it).c_str());\r
+ }\r
+ for (it = userSources.begin(); it != userSources.end(); ++it) {\r
+ fprintf( stderr, " Source Name: %s\n", (*it).c_str());\r
+ }\r
+ for (it = userHeaders.begin(); it != userHeaders.end(); ++it) {\r
+ fprintf( stderr, " Header Name: %s\n", (*it).c_str());\r
+ }\r
+ for (it = ttcnPP.begin(); it != ttcnPP.end(); ++it) {\r
+ fprintf( stderr, " TTCN PP Name: %s\n", (*it).c_str());\r
+ }\r
+ fprintf( stderr, "\n");\r
+}\r
+\r
+ProjectGenHelper& ProjectGenHelper::Instance()\r
+{\r
+ static ProjectGenHelper singleton;\r
+ return singleton;\r
+}\r
+\r
+const std::string ProjectGenHelper::emptyString = std::string();\r
+\r
+ProjectGenHelper::ProjectGenHelper() :\r
+ nameOfTopLevelProject(),\r
+ rootDirOS(),\r
+ relPathToRootDirOS(),\r
+ Zflag(false),\r
+ Wflag(false),\r
+ Hflag(false),\r
+ projs(),\r
+ checkedProjs()\r
+{}\r
+\r
+void ProjectGenHelper::addTarget(const char* projName)\r
+{\r
+ if (!Zflag) return;\r
+ if (projs.end() != projs.find(std::string(projName))) return; // we have it \r
+ ProjectDescriptor newLib(projName);\r
+ projs.insert(std::pair<std::string, ProjectDescriptor> (std::string(projName), newLib));\r
+}\r
+\r
+void ProjectGenHelper::setToplevelProjectName(const char* name)\r
+{\r
+ if (!nameOfTopLevelProject.empty()) return;\r
+ nameOfTopLevelProject = std::string(name);\r
+}\r
+\r
+void ProjectGenHelper::setRootDirOS( const char* name)\r
+{\r
+ if (rootDirOS.empty()) {\r
+ rootDirOS = std::string(name);\r
+ }\r
+ else { //compare the 2 string and get the common part\r
+ const char* root = rootDirOS.c_str();\r
+ const char* head = root;\r
+ for (; *root++ == *name++; ) ;\r
+ size_t length = root - head - 1; //minus the non-matching\r
+ if (rootDirOS.size() > length) {\r
+ rootDirOS.resize(length);\r
+ }\r
+ }\r
+}\r
+\r
+const std::string& ProjectGenHelper::getRootDirOS(const char* name)\r
+{\r
+ ProjectDescriptor* proj = getProject(name);\r
+ if (!proj) return emptyString;\r
+ relPathToRootDirOS = proj->setRelativePathTo(rootDirOS);\r
+ return relPathToRootDirOS;\r
+}\r
+\r
+ProjectDescriptor* ProjectGenHelper::getTargetOfProject(const char* projName)\r
+{\r
+ if (!Zflag) return NULL;\r
+ if (projs.end() == projs.find(std::string(projName))) return NULL;\r
+ return getProject(projName);\r
+}\r
+\r
+const ProjectDescriptor* ProjectGenHelper::getTargetOfProject(const char* projName) const\r
+{\r
+ if (!Zflag) return NULL;\r
+ if (projs.end() == projs.find(std::string(projName))) return NULL;\r
+ return getProject(projName);\r
+}\r
+\r
+ProjectDescriptor* ProjectGenHelper::getProjectDescriptor(const char* targetName)\r
+{\r
+ if (!Zflag) return NULL;\r
+ for (std::map<std::string, ProjectDescriptor>::iterator it = projs.begin(); it != projs.end(); ++it) {\r
+ if ((it->second).getTargetExecName() == std::string(targetName))\r
+ return &(it->second);\r
+ }\r
+ return NULL;\r
+}\r
+\r
+std::map<std::string, ProjectDescriptor>::const_iterator ProjectGenHelper::getHead() const\r
+{\r
+ return projs.begin();\r
+}\r
+\r
+std::map<std::string, ProjectDescriptor>::const_iterator ProjectGenHelper::getEnd() const\r
+{\r
+ return projs.end();\r
+}\r
+\r
+void ProjectGenHelper::addTtcn3ModuleToProject(const char* projName, const char* moduleName)\r
+{\r
+ if (!Zflag) return;\r
+ if (projs.end() == projs.find(std::string(projName))) return;\r
+ ProjectDescriptor* proj = getProject(projName);\r
+ if (proj && !proj->hasTtcn3ModuleName(moduleName)) {\r
+ proj->addTtcn3ModuleName(moduleName);\r
+ }\r
+}\r
+\r
+void ProjectGenHelper::addAsn1ModuleToProject(const char* projName, const char* moduleName)\r
+{\r
+ if (!Zflag) return;\r
+ if (projs.end() == projs.find(std::string(projName))) return;\r
+ ProjectDescriptor* proj = getProject(projName);\r
+ if (proj &&!proj->hasAsn1ModuleName(moduleName)) {\r
+ proj->addAsn1ModuleName(moduleName);\r
+ }\r
+}\r
+\r
+void ProjectGenHelper::addUserSourceToProject(const char* projName, const char* userSourceName)\r
+{\r
+ if (!Zflag) return;\r
+ if (projs.end() == projs.find(std::string(projName))) return;\r
+ ProjectDescriptor* proj = getProject(projName);\r
+ if (proj && !proj->hasUserSource(userSourceName)) {\r
+ proj->addUserSource(userSourceName);\r
+ }\r
+}\r
+\r
+void ProjectGenHelper::addUserHeaderToProject(const char* projName, const char* userHeaderName)\r
+{\r
+ if (!Zflag) return;\r
+ if (projs.end() == projs.find(std::string(projName))) return;\r
+ ProjectDescriptor* proj = getProject(projName);\r
+ if (proj && !proj->hasUserHeader(userHeaderName)) {\r
+ proj->addUserHeader(userHeaderName);\r
+ }\r
+}\r
+\r
+void ProjectGenHelper::addTtcnPPToProject(const char* projName, const char* ttcnPPName)\r
+{\r
+ if (!Zflag) return;\r
+ if (projs.end() == projs.find(std::string(projName))) return;\r
+ ProjectDescriptor* proj = getProject(projName);\r
+ if (proj && !proj->hasTtcn3PP(ttcnPPName)) {\r
+ proj->addTtcn3PP(ttcnPPName);\r
+ }\r
+}\r
+\r
+void ProjectGenHelper::generateRefProjectWorkingDirsTo(const char* projName)\r
+{\r
+ if (!Zflag) return;\r
+ std::map<std::string,ProjectDescriptor>::iterator iter = projs.find(projName);\r
+ if (projs.end() == iter) {\r
+ ERROR("Project \"%s\" is not found in the project hierarchy ", projName);\r
+ return;\r
+ }\r
+ if (nameOfTopLevelProject != (iter->second).getProjectName()) {\r
+ ERROR("Project \"%s\" is not the on the top-level ", projName);\r
+ return;\r
+ }\r
+ ProjectDescriptor* proj = &(iter->second); // the Top level project\r
+\r
+ for (size_t i = 0; i < proj->numOfReferencedProjects(); ++i) {\r
+ const std::string& refProjName = proj->getReferencedProject(i);\r
+ ProjectDescriptor* refProj = getTargetOfProject(refProjName.c_str());\r
+ if (!refProj) return; // for sure...\r
+ const std::string& absWorkingDir = refProj->getProjectAbsWorkingDir();\r
+ if (!absWorkingDir.empty()) {\r
+ std::string relPath = proj->setRelativePathTo(absWorkingDir);\r
+ proj->addToRefProjWorkingDirs(relPath);\r
+ }\r
+ }\r
+}\r
+\r
+size_t ProjectGenHelper::numOfLibs() const\r
+{\r
+ if (!Zflag) return 0;\r
+ size_t num = 0;\r
+ for (std::map<std::string, ProjectDescriptor>::const_iterator it = projs.begin(); it != projs.end(); ++it) {\r
+ if ((it->second).isLibrary()) {\r
+ ++num;\r
+ }\r
+ }\r
+ return num;\r
+}\r
+\r
+struct CompareStr\r
+{\r
+ bool operator () (const char* lhs, const char* rhs) {\r
+ int ret = strcmp(lhs, rhs);\r
+ return (0 > ret);\r
+ }\r
+};\r
+\r
+void ProjectGenHelper::getExternalLibs(std::vector<const char*>& extLibs)\r
+{\r
+ if (!Zflag) return;\r
+ std::map<const char*, const char*, CompareStr> libs;\r
+ for (std::map<std::string, ProjectDescriptor>::iterator it = projs.begin(); it != projs.end(); ++it) {\r
+ if ((it->second).numOfLinkerLibs() > 0) {\r
+ for (size_t i = 0; i < (it->second).numOfLinkerLibs(); ++i) {\r
+ const char* key = (it->second).getLinkerLib(i);\r
+ const char* value = (it->second).getProjectName().c_str();\r
+ libs.insert(std::pair<const char*,const char*>(key,value)); // filter duplicates\r
+ }\r
+ }\r
+ }\r
+ std::map<const char*, const char*>::iterator it;\r
+ for (it = libs.begin(); it != libs.end(); ++it) {\r
+ extLibs.push_back(it->first);\r
+ }\r
+}\r
+\r
+void ProjectGenHelper::getExternalLibSearchPathes(std::vector<const char*>& extLibPathes)\r
+{\r
+ if (!Zflag) return;\r
+ std::map<const char*, const char*, CompareStr> libPathes;\r
+ for (std::map<std::string, ProjectDescriptor>::iterator it = projs.begin(); it != projs.end(); ++it) {\r
+ if ((it->second).numOfLibSearchPaths() > 0) {\r
+ for (size_t i = 0; i < (it->second).numOfLibSearchPaths(); ++i) {\r
+ const char* key = (it->second).getLibSearchPath(i);\r
+ const char* value = (it->second).getProjectName().c_str();\r
+ libPathes.insert(std::pair<const char*,const char*>(key,value)); // filter duplicates\r
+ }\r
+ }\r
+ }\r
+ std::map<const char*, const char*>::iterator it;\r
+ for (it = libPathes.begin(); it != libPathes.end(); ++it) {\r
+ extLibPathes.push_back(it->first);\r
+ }\r
+}\r
+\r
+bool ProjectGenHelper::hasReferencedProject()\r
+{\r
+ if (!Zflag) return false;\r
+ ProjectDescriptor* topLevel = getTargetOfProject(nameOfTopLevelProject.c_str());\r
+ if (topLevel && topLevel->numOfReferencedProjects()) return true;\r
+ return false;\r
+}\r
+\r
+bool ProjectGenHelper::isTtcn3ModuleInLibrary(const char* moduleName) const\r
+{\r
+ if (!Zflag) return false;\r
+ for (std::map<std::string, ProjectDescriptor>::const_iterator it = projs.begin(); it != projs.end(); ++it) {\r
+ if ((it->second).hasTtcn3ModuleName(moduleName) && (it->second).isLibrary()) return true;\r
+ }\r
+ return false;\r
+}\r
+\r
+bool ProjectGenHelper::isAsn1ModuleInLibrary(const char* moduleName) const\r
+{\r
+ if (!Zflag) return false;\r
+ for (std::map<std::string, ProjectDescriptor>::const_iterator it = projs.begin(); it != projs.end(); ++it) {\r
+ if ((it->second).hasAsn1ModuleName(moduleName) && (it->second).isLibrary()) return true;\r
+ }\r
+ return false;\r
+}\r
+\r
+bool ProjectGenHelper::isSourceFileInLibrary(const char* fileName) const\r
+{\r
+ if (!Zflag || NULL == fileName) return false;\r
+ for (std::map<std::string, ProjectDescriptor>::const_iterator it = projs.begin(); it != projs.end(); ++it) {\r
+ if ((it->second).hasUserSource(fileName) && (it->second).isLibrary()) return true;\r
+ }\r
+ return false;\r
+}\r
+\r
+bool ProjectGenHelper::isHeaderFileInLibrary(const char* fileName) const\r
+{\r
+ if (!Zflag || NULL == fileName) return false;\r
+\r
+ for (std::map<std::string, ProjectDescriptor>::const_iterator it = projs.begin(); it != projs.end(); ++it) {\r
+ if ((it->second).hasUserHeader(fileName) && (it->second).isLibrary()) return true;\r
+ }\r
+ return false;\r
+}\r
+\r
+bool ProjectGenHelper::isTtcnPPFileInLibrary(const char* fileName) const\r
+{\r
+ if (!Zflag || NULL == fileName) return false;\r
+\r
+ for (std::map<std::string, ProjectDescriptor>::const_iterator it = projs.begin(); it != projs.end(); ++it) {\r
+ if ((it->second).hasTtcn3PP(fileName) && (it->second).isLibrary()) return true;\r
+ }\r
+ return false;\r
+}\r
+\r
+bool ProjectGenHelper::isCPPSourceFile(const char* fileName) const\r
+{\r
+ std::string fnStr(fileName);\r
+ size_t pos = fnStr.find_last_of('.');\r
+ if (std::string::npos == pos) return false;\r
+ const std::string EXT_CC("cc");\r
+ const std::string EXT_CPP("cpp");\r
+ int length = 0;\r
+ if (std::string::npos != fnStr.find (EXT_CC, pos + 1))\r
+ length = EXT_CC.size();\r
+ else if (std::string::npos != fnStr.find (EXT_CPP, pos + 1))\r
+ length = EXT_CPP.size();\r
+\r
+ if (length && fnStr.size() == pos + length + 1)\r
+ return true;\r
+ else \r
+ return false;\r
+}\r
+\r
+bool ProjectGenHelper::isCPPHeaderFile(const char* fileName) const\r
+{\r
+ std::string fnStr(fileName);\r
+ size_t pos = fnStr.find_last_of('.');\r
+ if (std::string::npos == pos) return false;\r
+ const std::string EXT_HPP("hpp");\r
+ const std::string EXT_HH("hh");\r
+ const std::string EXT_H("h");\r
+ int length = 0;\r
+ if (std::string::npos != fnStr.find (EXT_HH, pos + 1))\r
+ length = EXT_HH.size();\r
+ else if (std::string::npos != fnStr.find (EXT_HPP, pos + 1))\r
+ length = EXT_HPP.size();\r
+ else if (std::string::npos != fnStr.find (EXT_H, pos + 1))\r
+ length = EXT_H.size();\r
+\r
+ if (length && fnStr.size() == pos + length + 1)\r
+ return true;\r
+ else\r
+ return false;\r
+}\r
+\r
+bool ProjectGenHelper::isTtcnPPFile(const char* fileName) const\r
+{\r
+ std::string fnStr(fileName);\r
+ size_t pos = fnStr.find_last_of('.');\r
+ if (std::string::npos == pos) return false;\r
+ const std::string EXT_TTCNPP("ttcnpp");\r
+ int length = 0;\r
+ if (std::string::npos != fnStr.find (EXT_TTCNPP, pos + 1))\r
+ length = EXT_TTCNPP.size();\r
+\r
+ if (length && fnStr.size() == pos + length + 1)\r
+ return true;\r
+ else\r
+ return false;\r
+}\r
+\r
+void ProjectGenHelper::print()\r
+{\r
+ if (!Zflag) return;\r
+ fprintf(stderr, "Top Level project : %s\n", nameOfTopLevelProject.c_str());\r
+ for (std::map<std::string, ProjectDescriptor>::iterator it = projs.begin(); it != projs.end(); ++it) {\r
+ (it->second).print();\r
+ }\r
+}\r
+\r
+bool ProjectGenHelper::sanityCheck()\r
+{\r
+ if (!Zflag) return true;\r
+ bool ret = true;\r
+// if toplevel is a dynamic linked executable (not library) all executable shall set to the same linking method\r
+ {\r
+ ProjectDescriptor* topLevel = getTargetOfProject(nameOfTopLevelProject.c_str());\r
+ bool isDynamicLinked = topLevel->getLinkingStrategy();\r
+ if (!topLevel->isLibrary() && isDynamicLinked) { // dynamic linked executable\r
+ for (std::map<std::string, ProjectDescriptor>::iterator it = projs.begin(); it != projs.end(); ++it) {\r
+ if (!(it->second).isLibrary()) { //if exectubale \r
+ if (isDynamicLinked != (it->second).getLinkingStrategy()) {\r
+ ERROR("project \"%s\" is set to %s linking. Sub project \"%s\" is set to %s linking. "\r
+ "All sub-level executable shall be set to the %s's type.",\r
+ nameOfTopLevelProject.c_str(),\r
+ isDynamicLinked ? "dynamic" : "static",\r
+ ((it->second).getProjectName()).c_str(),\r
+ isDynamicLinked ? "static" : "dynamic",\r
+ nameOfTopLevelProject.c_str());\r
+ ret = false;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+// under a dynamic linked library every project shall be linked dynamic library too.\r
+ {\r
+ checkedProjs.clear();\r
+ bool found = false; // search for executable under dynamic linked library\r
+ char* execName = NULL;\r
+ for (std::map<std::string, ProjectDescriptor>::reverse_iterator rit = projs.rbegin(); rit != projs.rend(); ++rit) {\r
+ if ((rit->second).isLibrary() && (rit->second).getLinkingStrategy()) { //dynamic library \r
+ ProjectDescriptor& proj = rit->second;\r
+ found = DynamicLibraryChecker(&proj, found, &execName);\r
+ if (found) {\r
+ ERROR("Project \"%s\" is dynamic linked library. Sub project \"%s\" is executable.\n"\r
+ "in TPD file, %s's all sub-level defaultTarget shall be set library too.",\r
+ proj.getProjectName().c_str(), execName, proj.getProjectName().c_str());\r
+ ret = false;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+ProjectDescriptor* ProjectGenHelper::getProject(const char* projName)\r
+{\r
+ if (!projName) return NULL;\r
+ for (std::map<std::string, ProjectDescriptor>::iterator it = projs.begin(); it != projs.end(); ++it) {\r
+ if (it->first == std::string(projName)) {\r
+ return &(it->second);\r
+ }\r
+ }\r
+ return NULL;\r
+}\r
+\r
+const ProjectDescriptor* ProjectGenHelper::getProject(const char* projName) const\r
+{\r
+ if (!projName) return NULL;\r
+ for (std::map<std::string, ProjectDescriptor>::const_iterator it = projs.begin(); it != projs.end(); ++it) {\r
+ if (it->first == std::string(projName)) {\r
+ return &(it->second);\r
+ }\r
+ }\r
+ return NULL;\r
+}\r
+\r
+\r
+void ProjectGenHelper::cleanUp()\r
+{\r
+ if (!Zflag) return;\r
+ checkedProjs.clear();\r
+ for (std::map<std::string, ProjectDescriptor>::iterator it = projs.begin(); it != projs.end(); ++it) {\r
+ (it->second).cleanUp();\r
+ }\r
+}\r
+\r
+bool ProjectGenHelper::DynamicLibraryChecker(const ProjectDescriptor* desc,\r
+ bool& found,\r
+ char** executableName)\r
+{\r
+ if (found || !desc) return true;\r
+ for (size_t i = 0; i < desc->numOfReferencedProjects(); ++i) {\r
+ char* refProjName = const_cast<char*> (desc->getReferencedProject(i).c_str());\r
+ const ProjectDescriptor* subProj = getTargetOfProject(refProjName);\r
+ if (0 == checkedProjs.count(subProj->getProjectName())) {\r
+ if (subProj->isLibrary()) {\r
+ found = DynamicLibraryChecker(subProj, found, executableName);\r
+ }\r
+ else { // search for executable under dynamic linked library\r
+ found = true;\r
+ *executableName = refProjName;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ // it is checked, no such executable was found. Store it not to iterate again\r
+ if (!found)\r
+ checkedProjs.insert(std::pair<const std::string, const ProjectDescriptor*> \r
+ (desc->getProjectName(), desc));\r
+ return found;\r
+}\r
+\r
--- /dev/null
+///////////////////////////////////////////////////////////////////////////////\r
+// Copyright (c) 2000-2014 Ericsson Telecom AB\r
+// All rights reserved. This program and the accompanying materials\r
+// are made available under the terms of the Eclipse Public License v1.0\r
+// which accompanies this distribution, and is available at\r
+// http://www.eclipse.org/legal/epl-v10.html\r
+///////////////////////////////////////////////////////////////////////////////\r
+#ifndef _LIB_GEN_HELPER_HH\r
+#define _LIB_GEN_HELPER_HH\r
+#include <string>\r
+#include <map>\r
+#include <vector>\r
+#include <cstdio>\r
+class ProjectGenHelper;\r
+class ProjectDescriptor {\r
+public:\r
+ explicit ProjectDescriptor(const char* name);\r
+ ~ProjectDescriptor() { cleanUp(); };\r
+\r
+ const std::string& getProjectName() const { return projectName; }\r
+ void setTPDFileName( const char* name);\r
+ const std::string& getTPDFileName() const { return tpdFileName; }\r
+ void setTargetExecName(const char* name) { targetExecutableName = std::string(name); }\r
+ const std::string& getTargetExecName() const { return targetExecutableName; }\r
+ void setProjectAbsTpdDir(const char* name) { projectAbsTpdDir = std::string(name); }\r
+ const std::string& getProjectAbsTpdDir() const { return projectAbsTpdDir; }\r
+ void setProjectAbsWorkingDir(const char* name);\r
+ void setProjectWorkingDir(const char* name) { projectWorkingDir = std::string(name); }\r
+ const std::string& getProjectAbsWorkingDir() const { return projectAbsWorkingDir; }\r
+ const std::string& getProjectWorkingDir() const { return projectWorkingDir; }\r
+ void setLinkingStrategy(bool strategy) { dynamicLinked = strategy; }\r
+ bool getLinkingStrategy() const { return dynamicLinked; }\r
+ void setLibrary(bool isLib) { library = isLib; }\r
+ bool isLibrary() const { return library; }\r
+ bool isInitialized();\r
+ void addToReferencedProjects(const char* refProjName);\r
+ void addToRefProjWorkingDirs(const std::string& subProjDir);\r
+ bool hasLinkerLibTo(const std::string& refProjName) const; \r
+ bool hasLinkerLib(const char* libName) const; // Linker Lib got from TPD\r
+ void addToLibSearchPaths(const char* libSearchPath);\r
+ void addToLinkerLibs(const char* linkerLibs);\r
+ void print();\r
+ void cleanUp();\r
+ size_t numOfReferencedProjects() const { return referencedProjects.size(); };\r
+ size_t numOfRefProjWorkingDirs() const { return refProjWorkingDirs.size(); };\r
+ size_t numOfLibSearchPaths() const { return libSearchPaths.size(); };\r
+ size_t numOfLinkerLibs() const { return linkerLibraries.size(); };\r
+ const std::string& getReferencedProject(size_t index) const \r
+ { return index < referencedProjects.size() ? referencedProjects[index] : emptyString; };\r
+ const std::string& getRefProjWorkingDir(size_t index) const \r
+ { return index < refProjWorkingDirs.size() ? refProjWorkingDirs[index] : emptyString; };\r
+ const char* getLibSearchPath(const std::string& subProjName) const;\r
+ const char* getLibSearchPath(size_t index) const { return libSearchPaths[index].c_str(); };\r
+ const char* getLinkerLib(const std::string& subProjName) const;\r
+ const char* getLinkerLib(size_t index) const { return linkerLibraries[index].c_str(); };\r
+ size_t getLibSearchPathIndex(const std::string& subProjName) const;\r
+ void setLibSearchPath(size_t index, const std::string& relPath) { libSearchPaths[index] = relPath; };\r
+ void addTtcn3ModuleName(const char* name) { ttcn3ModuleNames.push_back(name); };\r
+ bool hasTtcn3ModuleName(const char* moduleName) const;\r
+ void addAsn1ModuleName(const char* name) { asn1ModuleNames.push_back(name); };\r
+ bool hasAsn1ModuleName(const char* moduleName) const;\r
+ void addUserSource(const char* name) { userSources.push_back(name); };\r
+ bool hasUserSource(const char* userSourceName) const;\r
+ void addUserHeader(const char* name) { userHeaders.push_back(name); };\r
+ bool hasUserHeader(const char* userHeaderName) const;\r
+ void addTtcn3PP(const char* name) { ttcnPP.push_back(name); };\r
+ bool hasTtcn3PP(const char* ttcnPPName) const;\r
+ std::string setRelativePathTo(const std::string& absPathTo);\r
+\r
+private:\r
+ static const std::string emptyString;\r
+ std::string projectName;\r
+ std::string tpdFileName;\r
+ std::string targetExecutableName; //Library or Executable(only the top level)\r
+ std::string projectAbsTpdDir;\r
+ std::string projectAbsWorkingDir;\r
+ std::string projectWorkingDir;\r
+ bool library;\r
+ bool dynamicLinked;\r
+ std::vector<std::string> referencedProjects;\r
+ std::vector<std::string> refProjWorkingDirs;\r
+ std::vector<std::string> libSearchPaths;\r
+ std::vector<std::string> linkerLibraries;\r
+ std::vector<std::string> ttcn3ModuleNames;\r
+ std::vector<std::string> asn1ModuleNames;\r
+ std::vector<std::string> userSources; // *.cc ; *.cpp\r
+ std::vector<std::string> userHeaders; // *.hh ; *.h ; *.hpp\r
+ std::vector<std::string> ttcnPP; // *.ttcnpp\r
+ bool initialized;\r
+};\r
+\r
+class ProjectGenHelper {\r
+public:\r
+ static ProjectGenHelper &Instance();\r
+ ~ProjectGenHelper() { cleanUp(); };\r
+ void setZflag(bool flag) { Zflag = flag; };\r
+ bool getZflag() const { return Zflag; };\r
+ void setWflag(bool flag) { Wflag = flag; };\r
+ bool getWflag() const { return Wflag; };\r
+ void setHflag(bool flag) { Hflag = flag; };\r
+ bool getHflag() const { return Hflag; };\r
+ void setToplevelProjectName(const char* name);\r
+ const std::string& getToplevelProjectName() const { return nameOfTopLevelProject; };\r
+ void setRootDirOS(const char* name);\r
+ const std::string& getRootDirOS(const char* name);\r
+ void addTarget(const char* projName);\r
+ void generateRefProjectWorkingDirsTo(const char* projName);\r
+ void addTtcn3ModuleToProject(const char* projName, const char* moduleName);\r
+ void addAsn1ModuleToProject(const char* projName, const char* moduleName);\r
+ void addUserSourceToProject(const char* projName, const char* userSourceName);\r
+ void addUserHeaderToProject(const char* projName, const char* userHeaderName);\r
+ void addTtcnPPToProject(const char* projName, const char* ttcnPPName);\r
+ bool isTtcn3ModuleInLibrary(const char* moduleName) const;\r
+ bool isAsn1ModuleInLibrary(const char* moduleName) const;\r
+ bool isSourceFileInLibrary(const char* fileName) const;\r
+ bool isHeaderFileInLibrary(const char* fileName) const;\r
+ bool isTtcnPPFileInLibrary(const char* fileName) const;\r
+ ProjectDescriptor* getTargetOfProject(const char* projName);\r
+ const ProjectDescriptor* getTargetOfProject(const char* projName) const;\r
+ ProjectDescriptor* getProjectDescriptor(const char* targetName); //target_executable_name\r
+ std::map<std::string, ProjectDescriptor>::const_iterator getHead() const;\r
+ std::map<std::string, ProjectDescriptor>::const_iterator getEnd() const;\r
+ size_t numOfLibs() const;\r
+ void getExternalLibs(std::vector<const char*>& extLibs);\r
+ void getExternalLibSearchPathes(std::vector<const char*>& extLibPathes);\r
+ bool hasReferencedProject();\r
+ size_t numOfProjects() const { return projs.size();};\r
+ bool isCPPSourceFile(const char* fileName) const;\r
+ bool isCPPHeaderFile(const char* fileName) const;\r
+ bool isTtcnPPFile(const char* fileName) const;\r
+ void print();\r
+ bool sanityCheck(); // tests if the structure generated from TPDs is consistent\r
+ void cleanUp();\r
+\r
+private:\r
+ ProjectGenHelper();\r
+ ProjectGenHelper(const ProjectGenHelper &rhs);\r
+ ProjectGenHelper &operator=(const ProjectGenHelper &rhs);\r
+ ProjectDescriptor* getProject(const char* projName);\r
+ const ProjectDescriptor* getProject(const char* projName) const;\r
+ bool DynamicLibraryChecker(const ProjectDescriptor* desc,\r
+ bool& found,\r
+ char** executableName);\r
+private:\r
+ static ProjectGenHelper& intance;\r
+ static const std::string emptyString;\r
+ std::string nameOfTopLevelProject;\r
+ std::string rootDirOS; // make archive needs the top dir on OS level\r
+ std::string relPathToRootDirOS;\r
+ bool Zflag; // the makefilegen switch wether to use this option at all\r
+ bool Wflag; // prefix woring directory\r
+ bool Hflag; // hierarchical make structure\r
+ std::map<const std::string, ProjectDescriptor> projs;\r
+ std::map<const std::string, const ProjectDescriptor*> checkedProjs;\r
+};\r
+\r
+#endif // _LIB_GEN_HELPER_HH\r
mputprintf(effective_module_functions, "%s\"%s\"",
(effective_module_functions ? ", " : ""), entityname);
}
+ if (profiler_enabled) {
+ str = mputprintf(str,
+ "TTCN3_Stack_Depth stack_depth;\n"
+ "ttcn3_prof.enter_function(\"%s\", %d, \"%s\");\n",
+ filename, yyloc.first_line, entityname);
+ }
}
return str;
}
if (include_location_info && !transparency) {
str = mputprintf(str, "current_location.update_lineno(%d);\n",
yyloc.first_line);
+ if (profiler_enabled) {
+ str = mputprintf(str, "ttcn3_prof.execute_line(\"%s\", %d);\n",
+ get_filename(), yyloc.first_line);
+ }
if (tcov_file_name && in_tcov_files(get_filename())) {
effective_module_lines =
mputprintf(effective_module_lines, "%s%d",
else return false;
}
- Type *Scope::get_mtc_system_comptype(bool is_system, bool is_connecting)
+ Type *Scope::get_mtc_system_comptype(bool is_system)
{
- if (parent_scope) return parent_scope->get_mtc_system_comptype(is_system, is_connecting);
+ if (parent_scope) return parent_scope->get_mtc_system_comptype(is_system);
else return 0;
}
virtual bool has_ass_withId(const Identifier& p_id);
virtual bool is_valid_moduleid(const Identifier& p_id);
/** Returns the TTCN-3 component type that is associated with
- * keywords 'mtc' or 'system'. Returns NULL outside testcase definitions
- * (unless it's a 'map' or 'connect' statement block) or if the component type
- * cannot be determined. */
- virtual Type *get_mtc_system_comptype(bool is_system, bool is_connecting);
+ * keywords 'mtc' or 'system'. Returns NULL if the component type
+ * cannot be determined (i.e. outside testcase definitions). */
+ virtual Type *get_mtc_system_comptype(bool is_system);
/** Checks the 'runs on' clause of definition \a p_ass that it can
* be called from this scope unit. Parameters \a p_loc and \a
* p_what are used in error messages. \a p_what contains "call" or
ownertype = OT_UNKNOWN;
owner = 0;
chk_finished = false;
+ pard_type_instance = false;
}
void Type::clean_up()
bool Type::hasEncodeAttr(const MessageEncodingType_t encoding_type)
{
- if (CT_JSON == encoding_type &&
- (is_asn1() || (is_ref() && get_type_refd()->is_asn1()))) {
+ if (CT_JSON == encoding_type && (implicit_json_encoding
+ || is_asn1() || (is_ref() && get_type_refd()->is_asn1()))) {
// ASN.1 types automatically support JSON encoding
return true;
}
case T_UNIVERSALSTRING:
case T_BMPSTRING:
case T_VERDICT:
+ case T_NULL:
+ case T_OID:
+ case T_ROID:
+ case T_ANY:
// these basic types support JSON encoding by default
return json_mem.remember(t, ANSWER_YES);
case T_SEQ_T:
case T_SEQ_A:
+ case T_OPENTYPE:
case T_SET_T:
case T_SET_A:
case T_CHOICE_T:
case T_ENUM_T:
case T_ENUM_A:
break; // check for an encode attribute
- default:
+ default:
return json_mem.remember(t, ANSWER_NO);
} // switch
return json_mem.remember(t, hasEncodeAttr(CT_JSON) ? ANSWER_YES : ANSWER_NO);
string Type::get_dispname() const
{
- if (T_REFD == typetype) {
- // cannot calculate the display name for referenced types this way
- FATAL_ERROR("Type::get_dispname()");
- }
string dispname = genname;
size_t pos = 0;
while(pos < dispname.size()) {
/** True if chk() has finished running.
* Prevents force_raw() from running chk_raw(), chk_text() or chk_json() on unchecked types. */
bool chk_finished;
+
+ /** Signifies that this type is an instance of an ASN.1 parameterized type.
+ * It will not have its own segment and reference generated in the JSON schema,
+ * its schema segment will be generated as an embedded type's would. */
+ bool pard_type_instance;
/** Copy constructor, for the use of Type::clone() only. */
Type(const Type& p);
* If \a v is correct and it is or refers to a constant the constant value
* is returned for further checking. Otherwise the return value is NULL. */
Value *chk_range_boundary(Value *v, const char *which, const Location& loc);
+ void chk_range_boundary_infinity(Value *v, bool is_upper);
void chk_this_template_builtin(Template *t);
void chk_this_template_Int_Real(Template *t);
void chk_this_template_Enum(Template *t);
bool is_untagged() const;
+ inline boolean is_pard_type_instance() { return pard_type_instance; }
+ inline void set_pard_type_instance() { pard_type_instance = true; }
+
/** Calculates the type's display name from the genname (replaces double
* underscore characters with single ones) */
string get_dispname() const;
/** Generates the JSON schema segment that would validate a union type or
* an anytype and inserts it into the main schema. */
void generate_json_schema_union(JSON_Tokenizer& json);
+
+ /** Generates a reference to this type's schema segment and inserts it into
+ * the given schema. */
+ void generate_json_schema_ref(JSON_Tokenizer& json);
};
/** @} end of AST_Type group */
for (size_t x = 0; x < parent_type->get_nof_comps(); ++x) {
CompField * cf = parent_type->get_comp_byIndex(x);
if (cf->get_type() != this) continue;
- if (cf->has_default() || cf->get_is_optional()) {
- error("The field with ANY-ATTRIBUTES cannot be OPTIONAL or DEFAULT");
+ if (cf->has_default()) {
+ error("The field with ANY-ATTRIBUTES cannot have DEFAULT");
}
}
break;
}
}
+void Type::chk_range_boundary_infinity(Value *v, bool is_upper)
+{
+ if (v) {
+ v->set_my_governor(this);
+ {
+ Error_Context cntxt2(v, "In %s boundary", is_upper ? "upper" : "lower");
+ chk_this_value_ref(v);
+ Value *v_last = v->get_value_refd_last(0, EXPECTED_STATIC_VALUE);
+ if (v_last->get_valuetype() == Value::V_OMIT) {
+ v->error("`omit' value is not allowed in this context");
+ v->set_valuetype(Value::V_ERROR);
+ return;
+ }
+ if (sub_type != NULL) {
+ if (is_upper) {
+ if (!sub_type->get_root()->is_upper_limit_infinity()) {
+ v->error("Infinity is not a valid value for type '%s' which has subtype %s",
+ asString(), sub_type->to_string().c_str());
+ }
+ }
+ else {
+ if (!sub_type->get_root()->is_lower_limit_infinity()) {
+ v->error("Infinity is not a valid value for type '%s' which has subtype %s",
+ asString(), sub_type->to_string().c_str());
+ }
+ }
+ }
+ }
+ }
+}
+
Value *Type::chk_range_boundary(Value *v, const char *which,
const Location& loc)
{
FATAL_ERROR("Type::chk_this_template_Int_Real()");
}
}
+ if (v_lower && !v_upper) {
+ chk_range_boundary_infinity(v_lower, true);
+ }
+ if (!v_lower && v_upper) {
+ chk_range_boundary_infinity(v_upper, false);
+ }
break;}
default:
t->error("%s cannot be used for type `%s'", t->get_templatetype_str(),
case OT_TYPE_DEF:
case OT_COMP_FIELD:
case OT_RECORD_OF:
+ case OT_REF_SPEC:
force_xer = has_encoding(CT_XER); // && (is_ref() || (xerattrib && !xerattrib->empty()));
break;
default:
case T_UNIVERSALSTRING:
case T_BMPSTRING:
case T_VERDICT:
+ case T_NULL:
+ case T_OID:
+ case T_ROID:
+ case T_ANY:
// use predefined JSON descriptors instead of null pointers for basic types
target->source.global_vars = mputprintf(target->source.global_vars,
"&%s_json_, ", gennamejsondescriptor.c_str());
break;
+ case T_ENUM_T:
+ case T_ENUM_A:
+ // use a predefined JSON descriptor for enumerated types
+ target->source.global_vars = mputstr(target->source.global_vars,
+ "&ENUMERATED_json_, ");
+ break;
default:
target->source.global_vars = mputstr(target->source.global_vars,
"NULL, ");
"const TTCN_Typedescriptor_t& %s_descr_ = %s_descr_;\n",
gennameown_str, gennametypedescriptor.c_str());
}
- else {
- /* In general, we avoid generating a XER descriptor for
- * "artificial" types. */
-
- if (ownertype==OT_REF_SPEC) {
- // A XER descriptor without a TTCN descriptor to own it
- generate_code_xerdescriptor(target);
- }
#ifndef NDEBUG
- else
- target->source.global_vars = mputprintf(target->source.global_vars,
- "// %s_xer_ elided\n", gennameown_str);
-
+ else {
target->source.global_vars = mputprintf( target->source.global_vars,
"// %s_descr_ not needed, use %s_descr_\n",
gennameown_str, gennametypedescriptor.c_str());
-#endif
} // if(needs_alias())
+#endif
+
} // if (gennameown == gennametypedescriptor)
}
// stored if this is a field of a union with the "as value" coding instruction
if (ownertype == OT_COMP_FIELD) {
CompField* cf = static_cast<CompField*>(owner);
- if(as_value || (cf->get_type()->jsonattrib != NULL
- && cf->get_type()->jsonattrib->alias != NULL)) {
+ if (as_value || (cf->get_type()->jsonattrib != NULL
+ && cf->get_type()->jsonattrib->alias != NULL)) {
json.put_next_token(JSON_TOKEN_NAME, "originalName");
- char* field_str = mprintf("\"%s\"", cf->get_name().get_dispname().c_str());
+ char* field_str = mprintf("\"%s\"", cf->get_name().get_ttcnname().c_str());
json.put_next_token(JSON_TOKEN_STRING, field_str);
Free(field_str);
}
Free(alias_str);
}
}
-
+
// get the type at the end of the reference chain
Type* last = get_type_refd_last();
// if the type has its own definition and it's embedded in another type, then
// its schema already exists, only add a reference to it
- if (embedded && (last->ownertype == OT_TYPE_DEF /* TTCN-3 type definition */
+ // exception: instances of ASN.1 parameterized types, always embed their schemas
+ if (embedded && (!is_ref() || !get_type_refd()->pard_type_instance) &&
+ (last->ownertype == OT_TYPE_DEF /* TTCN-3 type definition */
|| last->ownertype == OT_TYPE_ASS /* ASN.1 type assignment */ )) {
json.put_next_token(JSON_TOKEN_NAME, "$ref");
char* ref_str = mprintf("\"#/definitions/%s/%s\"",
- last->my_scope->get_scope_mod()->get_modid().get_dispname().c_str(),
- last->get_dispname().c_str());
+ last->my_scope->get_scope_mod()->get_modid().get_ttcnname().c_str(),
+ (is_ref() && last->pard_type_instance) ? get_type_refd()->get_dispname().c_str() : last->get_dispname().c_str());
json.put_next_token(JSON_TOKEN_STRING, ref_str);
Free(ref_str);
} else {
case T_BSTR_A:
case T_HSTR:
case T_OSTR:
+ case T_ANY:
// use the JSON string type and add a pattern to only allow bits or hex digits
json.put_next_token(JSON_TOKEN_NAME, "type");
json.put_next_token(JSON_TOKEN_STRING, "\"string\"");
json.put_next_token(JSON_TOKEN_NAME, "subType");
- json.put_next_token(JSON_TOKEN_STRING, (last->typetype == T_OSTR) ? "\"octetstring\"" :
+ json.put_next_token(JSON_TOKEN_STRING,
+ (last->typetype == T_OSTR || last->typetype == T_ANY) ? "\"octetstring\"" :
((last->typetype == T_HSTR) ? "\"hexstring\"" : "\"bitstring\""));
json.put_next_token(JSON_TOKEN_NAME, "pattern");
json.put_next_token(JSON_TOKEN_STRING,
- (last->typetype == T_OSTR) ? "\"^([0-9A-Fa-f][0-9A-Fa-f])*$\"" :
+ (last->typetype == T_OSTR || last->typetype == T_ANY) ? "\"^([0-9A-Fa-f][0-9A-Fa-f])*$\"" :
((last->typetype == T_HSTR) ? "\"^[0-9A-Fa-f]*$\"" : "\"^[01]*$\""));
break;
case T_CSTR:
json.put_next_token(JSON_TOKEN_NAME, "subType");
json.put_next_token(JSON_TOKEN_STRING, "\"universal charstring\"");
break;
+ case T_OID:
+ case T_ROID:
+ json.put_next_token(JSON_TOKEN_NAME, "type");
+ json.put_next_token(JSON_TOKEN_STRING, "\"string\"");
+ json.put_next_token(JSON_TOKEN_NAME, "subType");
+ json.put_next_token(JSON_TOKEN_STRING, "\"objid\"");
+ json.put_next_token(JSON_TOKEN_NAME, "pattern");
+ json.put_next_token(JSON_TOKEN_STRING, "\"^[0-2][.][1-3]?[0-9]([.][0-9]|([1-9][0-9]+))*$\"");
+ break;
case T_VERDICT:
// enumerate the possible values
json.put_next_token(JSON_TOKEN_NAME, "enum");
// enumerate the possible values
json.put_next_token(JSON_TOKEN_NAME, "enum");
json.put_next_token(JSON_TOKEN_ARRAY_START);
- for (size_t i = 0; i < u.enums.eis->get_nof_eis(); ++i) {
- char* enum_str = mprintf("\"%s\"", get_ei_byIndex(i)->get_name().get_dispname().c_str());
+ for (size_t i = 0; i < last->u.enums.eis->get_nof_eis(); ++i) {
+ char* enum_str = mprintf("\"%s\"", last->get_ei_byIndex(i)->get_name().get_ttcnname().c_str());
json.put_next_token(JSON_TOKEN_STRING, enum_str);
Free(enum_str);
}
// list the numeric values for the enumerated items
json.put_next_token(JSON_TOKEN_NAME, "numericValues");
json.put_next_token(JSON_TOKEN_ARRAY_START);
- for (size_t i = 0; i < u.enums.eis->get_nof_eis(); ++i) {
- char* num_val_str = mprintf("%lli", get_ei_byIndex(i)->get_value()->get_val_Int()->get_val());
+ for (size_t i = 0; i < last->u.enums.eis->get_nof_eis(); ++i) {
+ char* num_val_str = mprintf("%lli", last->get_ei_byIndex(i)->get_value()->get_val_Int()->get_val());
json.put_next_token(JSON_TOKEN_NUMBER, num_val_str);
Free(num_val_str);
}
json.put_next_token(JSON_TOKEN_ARRAY_END);
break;
+ case T_NULL:
+ // use the JSON null value for the ASN.1 NULL type
+ json.put_next_token(JSON_TOKEN_NAME, "type");
+ json.put_next_token(JSON_TOKEN_STRING, "\"null\"");
+ break;
case T_SEQOF:
case T_SETOF:
case T_ARRAY:
case T_CHOICE_T:
case T_CHOICE_A:
case T_ANYTYPE:
+ case T_OPENTYPE:
last->generate_json_schema_union(json);
break;
default:
// use the field's alias if it has one
json.put_next_token(JSON_TOKEN_NAME,
(field->jsonattrib != NULL && field->jsonattrib->alias != NULL) ?
- field->jsonattrib->alias : get_comp_byIndex(i)->get_name().get_dispname().c_str());
+ field->jsonattrib->alias : get_comp_byIndex(i)->get_name().get_ttcnname().c_str());
// optional fields can also get the JSON null value
if (get_comp_byIndex(i)->get_is_optional()) {
- json.put_next_token(JSON_TOKEN_OBJECT_START);
- json.put_next_token(JSON_TOKEN_NAME, "anyOf");
- json.put_next_token(JSON_TOKEN_ARRAY_START);
- json.put_next_token(JSON_TOKEN_OBJECT_START);
- json.put_next_token(JSON_TOKEN_NAME, "type");
- json.put_next_token(JSON_TOKEN_STRING, "\"null\"");
- json.put_next_token(JSON_TOKEN_OBJECT_END);
+ // special case: ASN NULL type, since it uses the JSON literal "null" as a value
+ if (T_NULL != field->get_type_refd_last()->typetype) {
+ json.put_next_token(JSON_TOKEN_OBJECT_START);
+ json.put_next_token(JSON_TOKEN_NAME, "anyOf");
+ json.put_next_token(JSON_TOKEN_ARRAY_START);
+ json.put_next_token(JSON_TOKEN_OBJECT_START);
+ json.put_next_token(JSON_TOKEN_NAME, "type");
+ json.put_next_token(JSON_TOKEN_STRING, "\"null\"");
+ json.put_next_token(JSON_TOKEN_OBJECT_END);
+ }
} else if (!has_non_optional) {
has_non_optional = true;
}
// for optional fields: specify the presence of the "omit as null" coding instruction
// and close structures
- if (get_comp_byIndex(i)->get_is_optional()) {
+ if (get_comp_byIndex(i)->get_is_optional() &&
+ T_NULL != field->get_type_refd_last()->typetype) {
json.put_next_token(JSON_TOKEN_ARRAY_END);
json.put_next_token(JSON_TOKEN_NAME, "omitAsNull");
json.put_next_token((field->jsonattrib != NULL && field->jsonattrib->omit_as_null) ?
// use the field's alias if it has one
char* field_str = mprintf("\"%s\"",
(field->jsonattrib != NULL && field->jsonattrib->alias != NULL) ?
- field->jsonattrib->alias : get_comp_byIndex(i)->get_name().get_dispname().c_str());
+ field->jsonattrib->alias : get_comp_byIndex(i)->get_name().get_ttcnname().c_str());
json.put_next_token(JSON_TOKEN_STRING, field_str);
Free(field_str);
}
// use the field's alias if it has one
char* field_str = mprintf("\"%s\"",
(field->jsonattrib != NULL && field->jsonattrib->alias != NULL) ?
- field->jsonattrib->alias : get_comp_byIndex(i)->get_name().get_dispname().c_str());
+ field->jsonattrib->alias : get_comp_byIndex(i)->get_name().get_ttcnname().c_str());
json.put_next_token(JSON_TOKEN_STRING, field_str);
Free(field_str);
}
// use the alternative's alias if it has one
json.put_next_token(JSON_TOKEN_NAME,
(field->jsonattrib != NULL && field->jsonattrib->alias != NULL) ?
- field->jsonattrib->alias : get_comp_byIndex(i)->get_name().get_dispname().c_str());
+ field->jsonattrib->alias : get_comp_byIndex(i)->get_name().get_ttcnname().c_str());
// let the alternative's type insert its schema
field->generate_json_schema(json, true, false);
// use the alternative's alias here as well
char* field_str = mprintf("\"%s\"",
(field->jsonattrib != NULL && field->jsonattrib->alias != NULL) ?
- field->jsonattrib->alias : get_comp_byIndex(i)->get_name().get_dispname().c_str());
+ field->jsonattrib->alias : get_comp_byIndex(i)->get_name().get_ttcnname().c_str());
json.put_next_token(JSON_TOKEN_STRING, field_str);
Free(field_str);
json.put_next_token(JSON_TOKEN_ARRAY_END);
}
+void Type::generate_json_schema_ref(JSON_Tokenizer& json)
+{
+ // start the object containing the reference
+ json.put_next_token(JSON_TOKEN_OBJECT_START);
+
+ // insert the reference
+ json.put_next_token(JSON_TOKEN_NAME, "$ref");
+ char* ref_str = mprintf("\"#/definitions/%s/%s\"",
+ my_scope->get_scope_mod()->get_modid().get_ttcnname().c_str(),
+ get_dispname().c_str());
+ json.put_next_token(JSON_TOKEN_STRING, ref_str);
+ Free(ref_str);
+
+ // the object will be closed later, as it may contain other properties
+}
+
+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
} // namespace Common
case OPTYPE_CONCAT:
return get_expr_governor_v1v2(exp_val);
case OPTYPE_COMP_MTC:
- if (my_scope) return my_scope->get_mtc_system_comptype(false, false);
+ if (my_scope) return my_scope->get_mtc_system_comptype(false);
else return 0;
case OPTYPE_COMP_SYSTEM:
- if (my_scope) return my_scope->get_mtc_system_comptype(true, false);
+ if (my_scope) return my_scope->get_mtc_system_comptype(true);
else return 0;
case OPTYPE_COMP_SELF:
if (my_scope) {
if(valuetype != V_INVOKE) FATAL_ERROR("Value::get_invoked_type()");
return u.invoke.v->get_expr_governor(exp_val);
}
-
- Type* Value::get_component_governor()
- {
- if (V_EXPR == valuetype && OPTYPE_COMP_MTC == u.expr.v_optype) {
- if (my_scope) {
- return my_scope->get_mtc_system_comptype(false, true);
- } else {
- return 0;
- }
- }
- return get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE);
- }
const char* Value::get_opname() const
{
Type *t_comptype;
switch (u.expr.v_optype) {
case OPTYPE_COMP_MTC:
- t_comptype = my_scope->get_mtc_system_comptype(false, false);
+ t_comptype = my_scope->get_mtc_system_comptype(false);
break;
case OPTYPE_COMP_SYSTEM:
- t_comptype = my_scope->get_mtc_system_comptype(true, false);
+ t_comptype = my_scope->get_mtc_system_comptype(true);
break;
case OPTYPE_COMP_SELF: {
Ttcn::RunsOnScope *t_ros = my_scope->get_scope_runs_on();
string Value::create_stringRepr()
{
+ // note: cannot call is_asn1() when only parsing (scopes are not properly set)
switch (valuetype) {
case V_ERROR:
return string("<erroneous>");
case V_NULL:
return string("NULL");
case V_BOOL:
- if (is_asn1()) {
+ if (!parse_only && is_asn1()) {
if (u.val_bool) return string("TRUE");
else return string("FALSE");
}
case V_OID:
case V_ROID: {
string ret_val;
- if (!is_asn1()) ret_val += "objid ";
+ if (parse_only || !is_asn1()) ret_val += "objid ";
ret_val += "{ ";
for (size_t i = 0; i < u.oid_comps->size(); i++) {
if (i>0) ret_val += ' ';
ret_val += " }";
return ret_val; }
case V_CHOICE:
- if (is_asn1()) {
+ if (!parse_only && is_asn1()) {
string ret_val(u.choice.alt_name->get_dispname());
ret_val += " : ";
ret_val += u.choice.alt_value->get_stringRepr();
case V_SEQ:
case V_SET: {
string ret_val("{ ");
- bool asn1_flag = is_asn1();
+ bool asn1_flag = !parse_only && is_asn1();
for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++) {
if (i > 0) ret_val += ", ";
NamedValue *nv = u.val_nvs->get_nv_byIndex(i);
Type* get_expr_governor_last();
/** get the type invoked */
Type *get_invoked_type(Type::expected_value_t exp_val);
-
- /** An alternative version of get_expr_governor for components. This will
- * return the MTC component type in function and altstep scopes as well.
- * Calls get_expr_governor in all other cases. */
- Type* get_component_governor();
private:
const char* get_opname() const;
/** Used to determine whether the reference points to value or
asss->add_ass(p_ass);
}
- void Module::add_types_to_json_schema(JSON_Tokenizer& json)
+ void Module::generate_json_schema(JSON_Tokenizer& json, map<Type*, JSON_Tokenizer>& json_refs)
{
// add a new property for this module
- json.put_next_token(JSON_TOKEN_NAME, modid->get_dispname().c_str());
+ json.put_next_token(JSON_TOKEN_NAME, modid->get_ttcnname().c_str());
// add type definitions into an object
json.put_next_token(JSON_TOKEN_OBJECT_START);
- // pass the JSON tokenizer onto each type definition
+ // cycle through all type assignments, insert schema segments and references
+ // when needed
for (size_t i = 0; i < asss->get_nof_asss(); ++i) {
Common::Assignment* ass = asss->get_ass_byIndex(i);
if (Common::Assignment::A_TYPE == ass->get_asstype()) {
- Type* t = ass->get_Type();
- if (t->has_encoding(Type::CT_JSON)) {
- t->generate_json_schema(json, false, false);
+ Asn::Assignment* asn_ass = dynamic_cast<Asn::Assignment*>(ass);
+ // skip parameterized types and their instances
+ if (NULL == asn_ass || NULL == asn_ass->get_ass_pard()) {
+ Type* t = ass->get_Type();
+ if (!t->is_pard_type_instance() && t->has_encoding(Type::CT_JSON)) {
+ // insert type's schema segment
+ t->generate_json_schema(json, false, false);
+
+ if (json_refs_for_all_types && !json_refs.has_key(t)) {
+ // create JSON schema reference for the type
+ JSON_Tokenizer* json_ref = new JSON_Tokenizer;
+ json_refs.add(t, json_ref);
+ t->generate_json_schema_ref(*json_ref);
+ }
+ }
}
}
}
classify_ass(refch);
return asstype != A_ERROR ? ass->is_asstype(p_asstype, refch) : false;
}
+
+ Ass_pard* Ass_Undef::get_ass_pard() const
+ {
+ if (NULL != ass) {
+ return ass->get_ass_pard();
+ }
+ return ass_pard;
+ }
bool Ass_Undef::_error_if_pard()
{
virtual void set_right_scope(Scope *p_scope) =0;
void set_dontgen() {dontgen=true;}
/** Returns 0 if assignment is not parameterized! */
- Ass_pard* get_ass_pard() const { return ass_pard; }
+ virtual Ass_pard* get_ass_pard() const { return ass_pard; }
/** Returns 0 if this assignment is not parameterized! */
Assignment* new_instance(Common::Module *p_mod);
virtual Type* get_Type();
void add_ass(Assignment *p_ass);
TagDefault::tagdef_t get_tagdef() const { return tagdef; }
- /** Generates JSON schema segments for the types defined in the module
- * and adds them to the JSON schema parameter. */
- virtual void add_types_to_json_schema(JSON_Tokenizer&);
-
- /** Does nothing. ASN.1 modules can't contain functions. */
- virtual void add_func_to_json_schema(map<Type*, JSON_Tokenizer>&) {}
+ /** Generates JSON schema segments for the types defined in the modules,
+ * and references to these types.
+ *
+ * @param json JSON document containing the main schema, schema segments for
+ * the types will be inserted here
+ * @param json_refs map of JSON documents containing the references to each type */
+ virtual void generate_json_schema(JSON_Tokenizer& json, map<Type*, JSON_Tokenizer>& json_refs);
};
/**
virtual void set_my_scope(Scope *p_scope);
virtual void set_right_scope(Scope *p_scope);
virtual bool is_asstype(asstype_t p_asstype, ReferenceChain* refch=0);
+ virtual Ass_pard* get_ass_pard() const;
virtual Setting* get_Setting();
virtual Type* get_Type();
virtual Value* get_Value();
new_ass->set_location(*this);
new_ass->set_dontgen();
new_ass->chk();
-
+
+ if (Common::Assignment::A_TYPE == new_ass->get_asstype()) {
+ new_ass->get_Type()->set_pard_type_instance();
+ }
+
ref_ds=new Ref_defd_simple(new Identifier(my_mod->get_modid()),
new Identifier(new_ass_id));
ref_ds->set_fullname(get_fullname());
.br
.B compiler
.B \-v
+.br
+or
+.br
+.B compiler \-\-ttcn2json
+.RB "[\| " \-jf " \|]"
+.RB "[\| " \-T " \|]"
+module.ttcn ...
+.RB "[\| " \-A " \|]"
+module.asn ...
+.RB "[\| " \-
+schema.json
+.RB " \|]"
.SH DESCRIPTION
-This manual page is a quick reference for the TTCN-3 and ASN.1 to C++
+This manual page is a quick reference for the TTCN-3 and ASN.1 to C++ (or JSON schema)
compiler of the TTCN-3 Test Executor. It only summarizes the meaning of
all command line options. For more details please consult the
.B Programmer's Technical Reference for TITAN TTCN-3 Test Executor.
line the compiler will generate code for
.I all
modules.
+.TP
+.B \-\-ttcn2json
+Generates a JSON schema from the types defined in the specified TTCN-3 and ASN.1 modules.
+Must always be the first compiler option. From the previously listed options only
+.B \-T
+and
+.B \-A
+can be used, instead the JSON schema generator has options of its own:
+.TP
+.B \-j
+Only types that have JSON coding enabled are included in the schema.
+.TP
+.B \-f
+The schema only validates types that have a JSON encoding or decoding method declared.
+.TP
+.BI \- " file"
+The single dash character as command line argument specifies the name of the generated
+JSON schema file. If it is not present, then the schema file name is generated from
+the name of the first input file (by replacing its suffix with
+.I \.json
+or appending
+.I \.json
+to the end of the file).
.SH EXIT STATUS
The compiler exits with a status of zero when no errors were encountered
during its operation. A status of one will be returned if syntax or
#ifndef NDEBUG
"// written by %s in " __FILE__ " at %d\n"
#endif
- "int XER_encode(const XERdescriptor_t&, TTCN_Buffer&, unsigned int, int) const;\n"
- "int XER_decode(const XERdescriptor_t&, XmlReaderWrap&, unsigned int);\n"
+ "int XER_encode(const XERdescriptor_t&, TTCN_Buffer&, unsigned int, int, "
+ "embed_values_enc_struct_t*) const;\n"
+ "int XER_decode(const XERdescriptor_t&, XmlReaderWrap&, unsigned int, "
+ "embed_values_dec_struct_t*);\n"
"static boolean can_start(const char *name, const char *uri, "
"XERdescriptor_t const& xd, unsigned int);\n"
"%s"
/* Do not use %s_xer_ here. It supplies the XER descriptor of oldtype
* even if encoding newtype for:
* <ttcn>type newtype oldtype;</ttcn> */
- " XER_encode(*(p_td.xer),p_buf, XER_coding, 0);\n"
+ " XER_encode(*(p_td.xer),p_buf, XER_coding, 0, 0);\n"
" p_buf.put_c('\\n');\n" /* make sure it has a newline */
" break;}\n"
" case TTCN_EncDec::CT_JSON: {\n"
" for (int rd_ok=reader.Read(); rd_ok==1; rd_ok=reader.Read()) {\n"
" if (reader.NodeType() == XML_READER_TYPE_ELEMENT) break;\n"
" }\n"
- " XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL);\n"
+ " XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL, 0);\n"
" size_t bytes = reader.ByteConsumed();\n"
" p_buf.set_pos(bytes);\n"
" break;}\n"
src = mputprintf(src,
"int %s::XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf,"
- " unsigned int p_flavor, int p_indent) const\n"
+ " unsigned int p_flavor, int p_indent, embed_values_enc_struct_t*) const\n"
"{\n"
" int encoded_length=(int)p_buf.get_len();\n"
" const boolean e_xer = is_exer(p_flavor);\n"
"// written by %s in " __FILE__ " at %d\n"
#endif
"int %s::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& p_reader,"
- " unsigned int p_flavor)\n"
+ " unsigned int p_flavor, embed_values_dec_struct_t*)\n"
"{\n"
" int rd_ok = 1, type;\n"
semantic_check_only = FALSE, output_only_linenum = FALSE,
default_as_optional = FALSE, enable_set_bound_out_param = FALSE,
use_runtime_2 = FALSE, gcc_compat = FALSE, asn1_xer = FALSE,
- check_subtype = TRUE, suppress_context = FALSE, display_up_to_date = FALSE;
+ check_subtype = TRUE, suppress_context = FALSE, display_up_to_date = FALSE,
+ implicit_json_encoding = FALSE, json_refs_for_all_types = TRUE,
+ profiler_enabled = FALSE;
// Default code splitting mode is set to 'no splitting'.
CodeGenHelper::split_type code_splitting_mode = CodeGenHelper::SPLIT_NONE;
" [-U none|type] [-P modulename.top_level_pdu_name] [-Q number] ...\n"
" [-T] module.ttcn [-A] module.asn ...\n"
" or %s -v\n"
- " or %s --ttcn2json [-T] module.ttcn [-A] module.asn ... - schema.json\n"
+ " or %s --ttcn2json [-jf] ... [-T] module.ttcn [-A] module.asn ... [- schema.json]\n"
"\n"
"OPTIONS:\n"
" -a: force XER in ASN.1 files\n"
" -f: force overwriting of output files\n"
" -g: emulate GCC error/warning message format\n"
" -i: use only line numbers in error/warning messages\n"
+ " -j: disable JSON encoder/decoder functions\n"
" -l: include source line info in C++ code\n"
" -L: add source line info for logging\n"
" -K file: enable selective code coverage\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"
" -q: suppress all messages (quiet mode)\n"
" -Qn: quit after n errors\n"
" -r: disable RAW encoder/decoder functions\n"
" -t: generate Test Port skeleton\n"
" -u: duplicate underscores in file names\n"
" -U none|type: select code splitting mode for the generated C++ code\n"
+ " -V verb_level: set verbosity level bitmask (decimal)\n"
" -w: suppress warnings\n"
" -x: disable TEXT encoder/decoder functions\n"
" -X: disable XER encoder/decoder functions\n"
- " -j: disable JSON encoder/decoder functions\n"
" -y: disable subtype checking\n"
- " -V verb_level: set verbosity level bitmask (decimal)\n"
- " -o dir: output files will be placed into dir\n"
" -Y: Enforces legacy behaviour of the \"out\" function parameters (see refguide)\n"
- " -P pduname: define top-level pdu\n"
+ //" -z: enable profiling and code coverage for TTCN-3 files\n" - not open to the public yet
" -T file: force interpretation of file as TTCN-3 module\n"
" -A file: force interpretation of file as ASN.1 module\n"
" -v: show version\n"
- " --ttcn2json: generate JSON schema from input modules\n", argv0, argv0, argv0);
+ " --ttcn2json: generate JSON schema from input modules\n"
+ "JSON schema generator options:\n"
+ " -j: only include types with JSON encoding\n"
+ " -f: only generate references to types with JSON encoding/decoding functions\n", argv0, argv0, argv0);
}
#define SET_FLAG(x) if (x##flag) {\
tflag = false, uflag = false, vflag = false, wflag = false, xflag = false,
dflag = false, Xflag = false, Rflag = false, gflag = false, aflag = false,
s0flag = false, Cflag = false, yflag = false, Uflag = false, Qflag = false,
- Sflag = false, Kflag = false, jflag = false,
+ Sflag = false, Kflag = false, jflag = false, zflag = false,
errflag = false, print_usage = false, ttcn2json = false;
CodeGenHelper cgh;
if (0 == strcmp(argv[1], "--ttcn2json")) {
ttcn2json = true;
display_up_to_date = TRUE;
+ implicit_json_encoding = TRUE;
for (int i = 2; i < argc; ++i) {
// A dash (-) is used to separate the schema file name from the input files
if (0 == strcmp(argv[i], "-")) {
}
add_module(n_modules, module_list, argv[i], Module::MOD_TTCN);
}
+ else if (0 == strcmp(argv[i], "-j")) {
+ implicit_json_encoding = FALSE;
+ }
+ else if (0 == strcmp(argv[i], "-f")) {
+ json_refs_for_all_types = FALSE;
+ }
+ else if (0 == strcmp(argv[i], "-fj") || 0 == strcmp(argv[i], "-jf")) {
+ implicit_json_encoding = FALSE;
+ json_refs_for_all_types = FALSE;
+ }
else if (argv[i][0] == '-') {
ERROR("Invalid option `%s' after option `--ttcn2json'", argv[i]);
print_usage = true;
if (!ttcn2json) {
for ( ; ; ) {
- int c = getopt(argc, argv, "aA:C:K:LP:T:V:bcdfgilo:YpqQ:rRs0StuU:vwxXjy-");
+ int c = getopt(argc, argv, "aA:C:K:LP:T:V:bcdfgilo:YpqQ:rRs0StuU:vwxXjyz-");
if (c == -1) break;
switch (c) {
case 'a':
SET_FLAG(y);
check_subtype = FALSE;
break;
+ case 'z':
+ SET_FLAG(z);
+ profiler_enabled = TRUE;
+ break;
case 'Q': {
long max_errs;
case '-':
if (!strcmp(argv[optind], "--ttcn2json")) {
- ERROR("Option `--ttcn2json' does not allow the use of other options");
+ ERROR("Option `--ttcn2json' is only allowed as the first option");
} else {
ERROR("Invalid option: `%s'", argv[optind]);
}
if (Aflag || Lflag || Pflag || Tflag || Vflag || Yflag ||
bflag || fflag || iflag || lflag || oflag || pflag || qflag ||
rflag || sflag || tflag || uflag || wflag || xflag || Xflag || Rflag ||
- Uflag || yflag || Kflag || jflag) {
+ Uflag || yflag || Kflag || jflag || zflag) {
errflag = true;
print_usage = true;
}
ERROR("Source line information `-L' is necessary for code coverage `-K'.");
errflag = true;
}
+ if (zflag && !Lflag) {
+ ERROR("Source line information `-L' is necessary for profiling `-z'.");
+ errflag = true;
+ }
if (iflag && gflag) {
WARNING("Option `-g' overrides `-i'.");
iflag = false; // -g gives more information
extern boolean generate_skeleton, force_overwrite, include_line_info,
include_location_info, duplicate_underscores, parse_only, semantic_check_only,
output_only_linenum, default_as_optional, use_runtime_2, gcc_compat, asn1_xer,
- check_subtype, suppress_context, enable_set_bound_out_param, display_up_to_date;
+ check_subtype, suppress_context, enable_set_bound_out_param, display_up_to_date,
+ implicit_json_encoding, json_refs_for_all_types, profiler_enabled;
extern const char *expected_platform;
#include <errno.h>
#include <ctype.h>
#if defined SOLARIS || defined SOLARIS8
-# include <sys/utsname.h>
+#include <sys/utsname.h>
#endif
#include "../common/memory.h"
static const char *program_name = NULL;
static unsigned int error_count = 0;
static boolean suppress_warnings = FALSE;
-
+void free_string2_list(struct string2_list* act_elem);
+void free_string_list(struct string_list* act_elem);
void ERROR(const char *fmt, ...)
{
va_list parameters;
/** data structure that describes the information needed for the Makefile */
struct makefile_struct {
+ char *project_name;
size_t nTTCN3Modules;
struct module_struct *TTCN3Modules;
boolean coverage;
char *tcov_file_name;
boolean library;
+ boolean linkingStrategy;
+ boolean hierarchical;
struct string_list* sub_project_dirs; /* not owned */
struct string_list* ttcn3_prep_includes; /* not owned */
struct string_list* ttcn3_prep_defines; /* not owned */
+ struct string_list* ttcn3_prep_undefines; /* not owned */
struct string_list* prep_includes; /* not owned */
struct string_list* prep_defines; /* not owned */
+ struct string_list* prep_undefines; /* not owned */
boolean codesplittpd;
boolean quietly;
boolean disablesubtypecheck;
/** Initializes structure \a makefile with empty lists and default settings. */
static void init_makefile_struct(struct makefile_struct *makefile)
{
+ makefile->project_name = NULL;
makefile->nTTCN3Modules = 0;
makefile->TTCN3Modules = NULL;
makefile->preprocess = FALSE;
makefile->coverage = FALSE;
makefile->tcov_file_name = NULL;
makefile->library = FALSE;
+ makefile->linkingStrategy = FALSE;
+ makefile->hierarchical = FALSE;
makefile->sub_project_dirs = NULL;
makefile->ttcn3_prep_includes = NULL;
makefile->prep_includes = NULL;
/** Deallocates all memory associated with structure \a makefile. */
static void free_makefile_struct(const struct makefile_struct *makefile)
{
+ Free(makefile->project_name);
size_t i;
for (i = 0; i < makefile->nTTCN3Modules; i++) {
Free(makefile->TTCN3Modules[i].dir_name);
{
size_t i;
DEBUG(level, "Data used for Makefile generation:");
+ DEBUG(level + 1, "TTCN-3 project name: %s", makefile->project_name);
DEBUG(level + 1, "TTCN-3 modules: (%u pcs.)", makefile->nTTCN3Modules);
for (i = 0; i < makefile->nTTCN3Modules; i++) {
const struct module_struct *module = makefile->TTCN3Modules + i;
if (user->header_name != NULL) {
DEBUG(level + 3, "Header file: %s", user->header_name);
DEBUG(level + 3, "Header file has .hh or .hpp suffix: %s",
- user->has_hh_suffix ? "yes" : "no");
+ user->has_hh_suffix ? "yes" : "no");
}
if (user->source_name != NULL) {
DEBUG(level + 3, "Source file: %s", user->source_name);
DEBUG(level + 3, "Source file has .cc or .cpp suffix: %s",
- user->has_cc_suffix ? "yes" : "no");
+ user->has_cc_suffix ? "yes" : "no");
DEBUG(level + 3, "Object file: %s.o", user->file_prefix);
}
}
const struct base_dir_struct *base_dir = makefile->BaseDirs + i;
DEBUG(level + 2, "Directory: %s", base_dir->dir_name);
DEBUG(level + 3, "Has TTCN-3/ASN.1 modules: %s",
- base_dir->has_modules ? "yes" : "no");
+ base_dir->has_modules ? "yes" : "no");
}
}
DEBUG(level + 1, "Working directory: %s",
for (i = 0; i < *list_size; i++) {
if (!strcmp(canonized_path_name, (*list_ptr)[i])) {
if (report_warning) WARNING("File `%s' was given more than once for the "
- "Makefile.", path_name);
+ "Makefile.", path_name);
Free(canonized_path_name);
return;
}
const char *suffix = get_suffix(path_name);
if (suffix != NULL) {
if (!strcmp(suffix, "ttcn") || !strcmp(suffix, "ttcn3") ||
- !strcmp(suffix, "3mp") || !strcmp(suffix, "ttcnpp")) {
+ !strcmp(suffix, "3mp") || !strcmp(suffix, "ttcnpp")) {
/* The file content was already checked. Since it doesn't look like
* a valid TTCN-3 file, these suffixes are suspect */
WARNING("File `%s' does not contain a valid TTCN-3 module. "
- "It will be added to the Makefile as other file.", path_name);
- } else if (!strcmp(suffix, "ttcnin")) {
+ "It will be added to the Makefile as other file.", path_name);
+ }
+ else if (!strcmp(suffix, "ttcnin")) {
/* this is a TTCN-3 include file */
if (makefile->preprocess) {
- add_path_to_list(&makefile->nTTCN3IncludeFiles,
- &makefile->TTCN3IncludeFiles, path_name, makefile->working_dir, TRUE);
- return;
- } else {
- WARNING("The suffix of file `%s' indicates that it is a TTCN-3 "
- "include file, but TTCN-3 preprocessing is not enabled. The file "
- "will be added to the Makefile as other file.", path_name);
+ add_path_to_list(&makefile->nTTCN3IncludeFiles,
+ &makefile->TTCN3IncludeFiles, path_name, makefile->working_dir, TRUE);
+ return;
+ }
+ else {
+ WARNING("The suffix of file `%s' indicates that it is a TTCN-3 "
+ "include file, but TTCN-3 preprocessing is not enabled. The file "
+ "will be added to the Makefile as other file.", path_name);
}
- } else if (!strcmp(suffix, "asn") || !strcmp(suffix, "asn1")) {
+ }
+ else if (!strcmp(suffix, "asn") || !strcmp(suffix, "asn1")) {
/* The file content was already checked. Since it doesn't look like
* a valid ASN.1 file, these suffixes are suspect */
WARNING("File `%s' does not contain a valid ASN.1 module. "
- "It will be added to the Makefile as other file.", path_name);
- } else if (!strcmp(suffix, "cc") || !strcmp(suffix, "c") || !strcmp(suffix, "cpp")) {
+ "It will be added to the Makefile as other file.", path_name);
+ }
+ else if (!strcmp(suffix, "cc") || !strcmp(suffix, "c") || !strcmp(suffix, "cpp")) {
/* this is a source file */
char *dir_name = get_dir_name(path_name, makefile->working_dir);
char *file_name = get_file_from_path(path_name);
struct user_struct *user;
size_t i;
for (i = 0; i < makefile->nUserFiles; i++) {
- user = makefile->UserFiles + i;
- if (!strcmp(file_prefix, user->file_prefix)) {
- if (user->source_name != NULL) {
- /* the source file is already present */
- if (is_same_file(dir_name, file_name,
- user->dir_name, user->source_name)) {
- WARNING("File `%s' was given more than once for the Makefile.",
- path_name);
- } else {
- char *path_name1 = compose_path_name(user->dir_name,
- user->source_name);
- char *path_name2 = compose_path_name(dir_name, file_name);
- ERROR("C/C++ source files `%s' and `%s' cannot be used together "
- "in the same Makefile.", path_name1, path_name2);
- Free(path_name1);
- Free(path_name2);
- }
- } else {
- /* a header file with the same prefix is already present */
- if (is_same_directory(dir_name, user->dir_name)) {
- user->source_name = file_name;
- file_name = NULL;
- if (!strcmp(suffix, "cc") || !strcmp(suffix, "cpp")) user->has_cc_suffix = TRUE;
- } else {
- char *path_name1 = compose_path_name(dir_name, file_name);
- char *path_name2 = compose_path_name(user->dir_name,
- user->header_name);
- ERROR("C/C++ source file `%s' cannot be used together with "
- "header file `%s' in the same Makefile.", path_name1,
- path_name2);
- Free(path_name1);
- Free(path_name2);
- }
- }
- Free(dir_name);
- Free(file_name);
- Free(file_prefix);
- return;
- }
+ user = makefile->UserFiles + i;
+ if (!strcmp(file_prefix, user->file_prefix)) {
+ if (user->source_name != NULL) {
+ /* the source file is already present */
+ if (is_same_file(dir_name, file_name,
+ user->dir_name, user->source_name)) {
+ WARNING("File `%s' was given more than once for the Makefile.", path_name);
+ }
+ else {
+ char *path_name1 = compose_path_name(user->dir_name, user->source_name);
+ char *path_name2 = compose_path_name(dir_name, file_name);
+ ERROR("C/C++ source files `%s' and `%s' cannot be used together "
+ "in the same Makefile.", path_name1, path_name2);
+ Free(path_name1);
+ Free(path_name2);
+ }
+ }
+ else {
+ /* a header file with the same prefix is already present */
+ if (is_same_directory(dir_name, user->dir_name)) {
+ user->source_name = file_name;
+ file_name = NULL;
+ if (!strcmp(suffix, "cc") || !strcmp(suffix, "cpp"))
+ user->has_cc_suffix = TRUE;
+ }
+ else {
+ char *path_name1 = compose_path_name(dir_name, file_name);
+ char *path_name2 = compose_path_name(user->dir_name, user->header_name);
+ ERROR("C/C++ source file `%s' cannot be used together with "
+ "header file `%s' in the same Makefile.", path_name1,
+ path_name2);
+ Free(path_name1);
+ Free(path_name2);
+ }
+ }
+ Free(dir_name);
+ Free(file_name);
+ Free(file_prefix);
+ return;
+ }
}
makefile->UserFiles = (struct user_struct*)Realloc(makefile->UserFiles,
- (makefile->nUserFiles + 1) * sizeof(*makefile->UserFiles));
+ (makefile->nUserFiles + 1) * sizeof(*makefile->UserFiles));
user = makefile->UserFiles + makefile->nUserFiles;
makefile->nUserFiles++;
user->dir_name = dir_name;
if (!strcmp(suffix, "cc") || !strcmp(suffix, "cpp")) user->has_cc_suffix = TRUE;
else user->has_cc_suffix = FALSE;
return;
- } else if (!strcmp(suffix, "hh") || !strcmp(suffix, "h")) {
+ }
+ else if (!strcmp(suffix, "hh") || !strcmp(suffix, "h")) {
/* this is a header file */
char *dir_name = get_dir_name(path_name, makefile->working_dir);
char *file_name = get_file_from_path(path_name);
struct user_struct *user;
size_t i;
for (i = 0; i < makefile->nUserFiles; i++) {
- user = makefile->UserFiles + i;
- if (!strcmp(file_prefix, user->file_prefix)) {
- if (user->header_name != NULL) {
- /* the header file is already present */
- if (is_same_file(dir_name, file_name,
- user->dir_name, user->header_name)) {
- WARNING("File `%s' was given more than once for the Makefile.",
- path_name);
- } else {
- char *path_name1 = compose_path_name(user->dir_name,
- user->header_name);
- char *path_name2 = compose_path_name(dir_name, file_name);
- ERROR("C/C++ header files `%s' and `%s' cannot be used together "
- "in the same Makefile.", path_name1, path_name2);
- Free(path_name1);
- Free(path_name2);
- }
- } else {
- /* a source file with the same prefix is already present */
- if (is_same_directory(dir_name, user->dir_name)) {
- user->header_name = file_name;
- file_name = NULL;
- if (!strcmp(suffix, "hh") || !strcmp(suffix, "hpp")) user->has_hh_suffix = TRUE;
- } else {
- char *path_name1 = compose_path_name(dir_name, file_name);
- char *path_name2 = compose_path_name(user->dir_name,
- user->source_name);
- ERROR("C/C++ header file `%s' cannot be used together with "
- "source file `%s' in the same Makefile.", path_name1,
- path_name2);
- Free(path_name1);
- Free(path_name2);
- }
- }
- Free(dir_name);
- Free(file_name);
- Free(file_prefix);
- return;
- }
+ user = makefile->UserFiles + i;
+ if (!strcmp(file_prefix, user->file_prefix)) {
+ if (user->header_name != NULL) {
+ /* the header file is already present */
+ if (is_same_file(dir_name, file_name, user->dir_name, user->header_name)) {
+ WARNING("File `%s' was given more than once for the Makefile.", path_name);
+ }
+ else {
+ char *path_name1 = compose_path_name(user->dir_name, user->header_name);
+ char *path_name2 = compose_path_name(dir_name, file_name);
+ ERROR("C/C++ header files `%s' and `%s' cannot be used together "
+ "in the same Makefile.", path_name1, path_name2);
+ Free(path_name1);
+ Free(path_name2);
+ }
+ }
+ else {
+ /* a source file with the same prefix is already present */
+ if (is_same_directory(dir_name, user->dir_name)) {
+ user->header_name = file_name;
+ file_name = NULL;
+ if (!strcmp(suffix, "hh") || !strcmp(suffix, "hpp"))
+ user->has_hh_suffix = TRUE;
+ }
+ else {
+ char *path_name1 = compose_path_name(dir_name, file_name);
+ char *path_name2 = compose_path_name(user->dir_name, user->source_name);
+ ERROR("C/C++ header file `%s' cannot be used together with "
+ "source file `%s' in the same Makefile.", path_name1, path_name2);
+ Free(path_name1);
+ Free(path_name2);
+ }
+ }
+ Free(dir_name);
+ Free(file_name);
+ Free(file_prefix);
+ return;
+ }
}
makefile->UserFiles = (struct user_struct*)Realloc(makefile->UserFiles,
- (makefile->nUserFiles + 1) * sizeof(*makefile->UserFiles));
+ (makefile->nUserFiles + 1) * sizeof(*makefile->UserFiles));
user = makefile->UserFiles + makefile->nUserFiles;
makefile->nUserFiles++;
user->dir_name = dir_name;
static const char * const suffix_list[] = { "hh", "h", "hpp", NULL };
const char * const *suffix_ptr;
for (suffix_ptr = suffix_list; *suffix_ptr != NULL; suffix_ptr++) {
- char *file_name = mprintf("%s.%s", user->file_prefix, *suffix_ptr);
- char *path_name = compose_path_name(user->dir_name, file_name);
- if (get_path_status(path_name) == PS_FILE) {
- Free(path_name);
- user->header_name = file_name;
- if (!strcmp(*suffix_ptr, "hh") || !strcmp(*suffix_ptr, "hpp")) user->has_hh_suffix = TRUE;
- break;
- }
- Free(file_name);
- Free(path_name);
+ char *file_name = mprintf("%s.%s", user->file_prefix, *suffix_ptr);
+ char *path_name = compose_path_name(user->dir_name, file_name);
+ if (get_path_status(path_name) == PS_FILE) {
+ Free(path_name);
+ user->header_name = file_name;
+ if (!strcmp(*suffix_ptr, "hh") || !strcmp(*suffix_ptr, "hpp"))
+ user->has_hh_suffix = TRUE;
+ break;
+ }
+ Free(file_name);
+ Free(path_name);
}
- } else if (user->source_name == NULL) {
+ }
+ else if (user->source_name == NULL) {
static const char * const suffix_list[] = { "cc", "c", "cpp", NULL };
const char * const *suffix_ptr;
for (suffix_ptr = suffix_list; *suffix_ptr != NULL; suffix_ptr++) {
- char *file_name = mprintf("%s.%s", user->file_prefix, *suffix_ptr);
- char *path_name = compose_path_name(user->dir_name, file_name);
- if (get_path_status(path_name) == PS_FILE) {
- Free(path_name);
- user->source_name = file_name;
- if (!strcmp(*suffix_ptr, "cc") || !strcmp(*suffix_ptr, "cpp")) user->has_cc_suffix = TRUE;
- break;
- }
- Free(file_name);
- Free(path_name);
+ char *file_name = mprintf("%s.%s", user->file_prefix, *suffix_ptr);
+ char *path_name = compose_path_name(user->dir_name, file_name);
+ if (get_path_status(path_name) == PS_FILE) {
+ Free(path_name);
+ user->source_name = file_name;
+ if (!strcmp(*suffix_ptr, "cc") || !strcmp(*suffix_ptr, "cpp"))
+ user->has_cc_suffix = TRUE;
+ break;
+ }
+ Free(file_name);
+ Free(path_name);
}
}
}
for (i = 0; i < makefile->nTTCN3Modules; i++) {
const struct module_struct *module = makefile->TTCN3Modules + i;
if (module->dir_name != NULL) {
- if (!module->is_regular) makefile->BaseTTCN3ModulesRegular = FALSE;
- } else {
- if (!module->is_regular) makefile->TTCN3ModulesRegular = FALSE;
+ if (!module->is_regular) makefile->BaseTTCN3ModulesRegular = FALSE;
+ }
+ else {
+ if (!module->is_regular) makefile->TTCN3ModulesRegular = FALSE;
}
if (!makefile->TTCN3ModulesRegular && !makefile->BaseTTCN3ModulesRegular)
- break;
+ break;
}
/* ttcnpp files are ttcn files */
if ((makefile->TTCN3ModulesRegular || makefile->BaseTTCN3ModulesRegular) &&
- makefile->preprocess) {
+ makefile->preprocess) {
for (i = 0; i < makefile->nTTCN3PPModules; i++) {
const struct module_struct *module = makefile->TTCN3PPModules + i;
if (module->dir_name != NULL) {
for (i = 0; i < makefile->nASN1Modules; i++) {
const struct module_struct *module = makefile->ASN1Modules + i;
if (module->dir_name != NULL) {
- if (!module->is_regular) makefile->BaseASN1ModulesRegular = FALSE;
- } else {
- if (!module->is_regular) makefile->ASN1ModulesRegular = FALSE;
+ if (!module->is_regular) makefile->BaseASN1ModulesRegular = FALSE;
+ }
+ else {
+ if (!module->is_regular) makefile->ASN1ModulesRegular = FALSE;
}
if (!makefile->ASN1ModulesRegular && !makefile->BaseASN1ModulesRegular)
- break;
+ break;
}
for (i = 0; i < makefile->nUserFiles; i++) {
const struct user_struct *user = makefile->UserFiles + i;
if (user->dir_name != NULL) {
- if (!user->has_cc_suffix)
- makefile->BaseUserSourcesRegular = FALSE;
- if (!user->has_cc_suffix || !user->has_hh_suffix)
- makefile->BaseUserHeadersRegular = FALSE;
- } else {
- if (!user->has_cc_suffix)
- makefile->UserSourcesRegular = FALSE;
- if (!user->has_cc_suffix || !user->has_hh_suffix)
- makefile->UserHeadersRegular = FALSE;
+ if (!user->has_cc_suffix)
+ makefile->BaseUserSourcesRegular = FALSE;
+ if (!user->has_cc_suffix || !user->has_hh_suffix)
+ makefile->BaseUserHeadersRegular = FALSE;
+ }
+ else {
+ if (!user->has_cc_suffix)
+ makefile->UserSourcesRegular = FALSE;
+ if (!user->has_cc_suffix || !user->has_hh_suffix)
+ makefile->UserHeadersRegular = FALSE;
}
if (!makefile->UserHeadersRegular && !makefile->UserSourcesRegular &&
- !makefile->BaseUserHeadersRegular &&
- !makefile->BaseUserSourcesRegular) break;
+ !makefile->BaseUserHeadersRegular &&
+ !makefile->BaseUserSourcesRegular) break;
}
} else {
/* this project (Makefile) will-be stand-alone */
for (i = 0; i < makefile->nTTCN3Modules; i++) {
const struct module_struct *module = makefile->TTCN3Modules + i;
if (!module->is_regular || module->dir_name != NULL) {
- makefile->TTCN3ModulesRegular = FALSE;
- break;
+ makefile->TTCN3ModulesRegular = FALSE;
+ break;
}
}
if (makefile->TTCN3ModulesRegular && makefile->preprocess) {
for (i = 0; i < makefile->nASN1Modules; i++) {
const struct module_struct *module = makefile->ASN1Modules + i;
if (!module->is_regular || module->dir_name != NULL) {
- makefile->ASN1ModulesRegular = FALSE;
- break;
+ makefile->ASN1ModulesRegular = FALSE;
+ break;
}
}
for (i = 0; i < makefile->nUserFiles; i++) {
const struct user_struct *user = makefile->UserFiles + i;
if (!user->has_cc_suffix)
- makefile->UserSourcesRegular = FALSE;
+ makefile->UserSourcesRegular = FALSE;
if (!user->has_cc_suffix || !user->has_hh_suffix)
- makefile->UserHeadersRegular = FALSE;
+ makefile->UserHeadersRegular = FALSE;
if (!makefile->UserHeadersRegular && !makefile->UserSourcesRegular)
- break;
+ break;
}
}
}
/** Prints the Makefile based on structure \a makefile. */
static void print_makefile(struct makefile_struct *makefile)
{
- boolean add_refd_prjs = makefile->sub_project_dirs && makefile->sub_project_dirs->str;
-
+ boolean add_refd_prjs = FALSE;
+ if (makefile->linkingStrategy && makefile->hierarchical) {
+ add_refd_prjs = hasSubProject(makefile->project_name);
+ }
+ else {
+ add_refd_prjs = makefile->sub_project_dirs && makefile->sub_project_dirs->str;
+ }
NOTIFY("Generating Makefile skeleton...");
if (makefile->force_overwrite ||
fp = fopen(makefile->output_file, "w");
if (fp == NULL){
ERROR("Cannot open output file `%s' for writing: %s",
- makefile->output_file, strerror(errno));
+ makefile->output_file, strerror(errno));
return;
}
user_info = get_user_info();
"# - make, make all Builds the %s.\n"
"# - make archive Archives all source files.\n"
"# - make check Checks the semantics of TTCN-3 and ASN.1 "
- "modules.\n"
- "# - make clean Removes all generated files.\n"
+ "modules.\n"
+ "%s" // clean:
+ "%s" //clean-all
"# - make compile Translates TTCN-3 and ASN.1 modules to C++.\n"
"# - make dep Creates/updates dependency list.\n"
"# - make executable Builds the executable test suite.\n"
"# - make library Builds the library archive.\n"
"# - make objects Builds the object files without linking the "
"executable.\n", user_info,
- makefile->library ? "library archive." : "executable test suite");
+ makefile->library ? "library archive." : "executable test suite",
+ (makefile->linkingStrategy && makefile->hierarchical) ?
+ "# - make clean Removes generated files from project.\n" :
+ "# - make clean Removes all generated files.\n",
+ (makefile->linkingStrategy && makefile->hierarchical) ?
+ "# - make clean-all Removes all generated files from the project hierarchy.\n" : "");
Free(user_info);
if (makefile->dynamic)
fprintf(fp, "# - make shared_objects Builds the shared object files "
fputs("# - make preprocess Preprocess TTCN-3 files.\n", fp);
if (makefile->central_storage) {
fputs("# WARNING! This Makefile uses pre-compiled files from the "
- "following directories:\n", fp);
+ "following directories:\n", fp);
for (i = 0; i < makefile->nBaseDirs; i++)
fprintf(fp, "# %s\n", makefile->BaseDirs[i].dir_name);
fputs("# The executable tests will be consistent only if all directories "
- "use\n"
- "# the same platform and the same version of TTCN-3 Test Executor "
- "and\n"
- "# C++ compiler with the same command line switches.\n\n", fp);
+ "use\n"
+ "# the same platform and the same version of TTCN-3 Test Executor "
+ "and\n"
+ "# C++ compiler with the same command line switches.\n\n", fp);
}
if (makefile->gnu_make) {
fputs("# WARNING! This Makefile can be used with GNU make only.\n"
".PHONY: all shared_objects executable library objects check clean dep archive", fp);
if (makefile->preprocess) fputs(" preprocess", fp);
if (add_refd_prjs) {
- fputs("\\\n referenced-all referenced-shared_objects referenced-executable referenced-library referenced-objects referenced-check"
- "\\\n referenced-clean referenced-archive", fp);
+ fprintf(fp, "\\\n referenced-all referenced-shared_objects referenced-executable referenced-library referenced-objects referenced-check"
+ "\\\n referenced-clean%s",
+ (makefile->linkingStrategy && makefile->hierarchical) ?
+ "-all" : "");
}
fprint_extra_targets(fp, makefile->target_placement_list, "PHONY");
fputs("\n\n", fp);
}
+ if (makefile->linkingStrategy) {
+ const char* tpd_name = getTPDFileName(makefile->project_name);
+ if (tpd_name) {
+ fputs("# Titan Project Descriptor file what this Makefile is generated from.\n", fp);
+ fprintf(fp, "TPD = %s\n\n", tpd_name);
+ }
+ const char* root_dir = getPathToRootDir(makefile->project_name);
+ if (root_dir) {
+ fputs("# Relative path to top directory at OS level.\n", fp);
+ fprintf(fp, "ROOT_DIR = %s\n\n", root_dir);
+ }
+ }
+
if (add_refd_prjs) {
- struct string_list* act_elem = makefile->sub_project_dirs;
- fputs("# This is the top level makefile of a Makefile hierarchy generated from\n"
- "# a Titan Project Descriptor hierarchy. List of referenced project\n"
+ struct string_list* act_elem = NULL;
+ struct string_list* head = NULL;
+ if (makefile->linkingStrategy && makefile->hierarchical) {// pair with free_string_list
+ head = act_elem = getRefWorkingDirs(makefile->project_name);
+ }
+ else {
+ act_elem = makefile->sub_project_dirs;
+ }
+ if (!makefile->linkingStrategy)
+ fputs("# This is the top level makefile of a Makefile hierarchy generated from\n", fp);
+ fputs("# Titan Project Descriptor hierarchy. List of referenced project\n"
"# working directories (ordered by dependencies):\n", fp);
while (act_elem) {
if (act_elem->str) {
}
act_elem = act_elem->next;
}
+ if (makefile->linkingStrategy && makefile->hierarchical) { // pair with getRefWorkingDirs
+ free_string_list(head);
+ }
fputs("REFERENCED_PROJECT_DIRS = ", fp);
- act_elem = makefile->sub_project_dirs;
+ if (makefile->linkingStrategy && makefile->hierarchical) {
+ head = act_elem = getRefWorkingDirs(makefile->project_name); // pair with free_string_list
+ }
+ else {
+ act_elem = makefile->sub_project_dirs;
+ }
while (act_elem) {
if (act_elem->str) {
fprintf(fp, "%s ", act_elem->str);
act_elem = act_elem->next;
}
fputs("\n\n", fp);
+ if (makefile->linkingStrategy && makefile->hierarchical) {// pair with getRefWorkingDirs
+ free_string_list(head);
+ }
}
fprintf(fp, "#\n"
}
}
+ if (makefile->prep_undefines) {
+ struct string_list* act_elem = makefile->prep_undefines;
+ while (act_elem) {
+ if (act_elem->str) {
+ fprintf(fp, " -U%s", act_elem->str);
+ }
+ act_elem = act_elem->next;
+ }
+ }
+
fputs("\n\n", fp);
if (makefile->gcc_dep) {
act_elem = act_elem->next;
}
}
+ if (makefile->ttcn3_prep_undefines) {
+ struct string_list* act_elem = makefile->ttcn3_prep_undefines;
+ while (act_elem) {
+ if (act_elem->str) {
+ fprintf(fp, " -U%s", act_elem->str);
+ }
+ act_elem = act_elem->next;
+ }
+ }
fputs("\n\n", fp);
}
fprint_extra_targets(fp, makefile->target_placement_list, "TTCN3_MODULES");
if (makefile->preprocess) {
fputs("\n\n"
- "# TTCN-3 modules to preprocess:\n"
+ "# TTCN-3 modules to preprocess:\n"
"TTCN3_PP_MODULES =", fp);
for (i = 0; i < makefile->nTTCN3PPModules; i++) {
const struct module_struct *module = makefile->TTCN3PPModules + i;
}
if (makefile->central_storage) {
fputs("\n\n"
- "# TTCN-3 modules used from central project(s):\n"
- "BASE_TTCN3_MODULES =", fp);
- for (i = 0; i < makefile->nTTCN3Modules; i++) {
- const struct module_struct *module = makefile->TTCN3Modules + i;
- /* Central storage used AND file is not in the current directory =>
- * it goes into BASE_TTCN3_MODULES */
- if (module->dir_name != NULL) print_file_name(fp, module);
+ "# TTCN-3 modules used from central project(s):\n"
+ "BASE_TTCN3_MODULES =", fp);
+ if (!makefile->linkingStrategy) {
+ for (i = 0; i < makefile->nTTCN3Modules; i++) {
+ const struct module_struct *module = makefile->TTCN3Modules + i;
+ /* Central storage used AND file is not in the current directory => it goes into BASE_TTCN3_MODULES */
+ if (module->dir_name != NULL) print_file_name(fp, module);
+ }
+ if (makefile->preprocess) {
+ fputs("\n\n"
+ "# TTCN-3 modules to preprocess used from central project(s):\n"
+ "BASE_TTCN3_PP_MODULES =", fp);
+ for (i = 0; i < makefile->nTTCN3PPModules; i++) {
+ const struct module_struct *module = makefile->TTCN3PPModules + i;
+ if (module->dir_name != NULL && !isTtcnPPFileInLibrary(module->file_name))
+ print_file_name(fp, module);
+ }
+ }
}
- if (makefile->preprocess) {
+ else { // new linking strategy
+ for (i = 0; i < makefile->nTTCN3Modules; i++) {
+ const struct module_struct *module = makefile->TTCN3Modules + i;
+ /* Central storage used AND file is not in the current directory => it goes into BASE_TTCN3_MODULES */
+ if (module->dir_name != NULL && !isTtcn3ModuleInLibrary(module->module_name))
+ print_file_name(fp, module);
+ }
fputs("\n\n"
- "# TTCN-3 modules to preprocess used from central project(s):\n"
- "BASE_TTCN3_PP_MODULES =", fp);
- for (i = 0; i < makefile->nTTCN3PPModules; i++) {
- const struct module_struct *module = makefile->TTCN3PPModules + i;
- if (module->dir_name != NULL) print_file_name(fp, module);
+ "# TTCN-3 library linked modules used from central project(s):\n"
+ "BASE2_TTCN3_MODULES =", fp);
+ for (i = 0; i < makefile->nTTCN3Modules; i++) {
+ const struct module_struct *module = makefile->TTCN3Modules + i;
+ /* Central storage used AND file is not in the current directory => it goes into BASE_TTCN3_MODULES */
+ if (module->dir_name != NULL && isTtcn3ModuleInLibrary(module->module_name))
+ print_file_name(fp, module);
+ }
+ if (makefile->preprocess) {
+ fputs("\n\n"
+ "# TTCN-3 modules to preprocess used from central project(s):\n"
+ "BASE_TTCN3_PP_MODULES =", fp);
+ for (i = 0; i < makefile->nTTCN3PPModules; i++) {
+ const struct module_struct *module = makefile->TTCN3PPModules + i;
+ if (module->dir_name != NULL && !isTtcnPPFileInLibrary(module->file_name))
+ print_file_name(fp, module);
+ }
+ fputs("\n\n"
+ "# TTCN-3 library linked modules to preprocess used from central project(s):\n"
+ "BASE2_TTCN3_PP_MODULES =", fp);
+ for (i = 0; i < makefile->nTTCN3PPModules; i++) {
+ const struct module_struct *module = makefile->TTCN3PPModules + i;
+ if (module->dir_name != NULL && isTtcnPPFileInLibrary(module->file_name))
+ print_file_name(fp, module);
+ }
}
}
}
"# Files to include in TTCN-3 preprocessed modules:\n"
"TTCN3_INCLUDES =", fp);
for (i = 0; i < makefile->nTTCN3IncludeFiles; i++)
- fprintf(fp, " %s", makefile->TTCN3IncludeFiles[i]);
+ fprintf(fp, " %s", makefile->TTCN3IncludeFiles[i]);
fprint_extra_targets(fp, makefile->target_placement_list, "TTCN3_INCLUDES");
}
fputs("\n\n"
for (i = 0; i < makefile->nASN1Modules; i++) {
const struct module_struct *module = makefile->ASN1Modules + i;
if (module->dir_name == NULL || !makefile->central_storage)
- print_file_name(fp, module);
+ print_file_name(fp, module);
}
fprint_extra_targets(fp, makefile->target_placement_list, "ASN1_MODULES");
if (makefile->central_storage) {
fputs("\n\n"
- "# ASN.1 modules used from central project(s):\n"
- "BASE_ASN1_MODULES =", fp);
- for (i = 0; i < makefile->nASN1Modules; i++) {
- const struct module_struct *module = makefile->ASN1Modules + i;
- if (module->dir_name != NULL) print_file_name(fp, module);
+ "# ASN.1 modules used from central project(s):\n"
+ "BASE_ASN1_MODULES =", fp);
+ if (!makefile->linkingStrategy) {
+ for (i = 0; i < makefile->nASN1Modules; i++) {
+ const struct module_struct *module = makefile->ASN1Modules + i;
+ if (module->dir_name != NULL) print_file_name(fp, module);
+ }
+ }
+ else {
+ for (i = 0; i < makefile->nASN1Modules; i++) {
+ const struct module_struct *module = makefile->ASN1Modules + i;
+ if (module->dir_name != NULL && !isAsn1ModuleInLibrary(module->module_name))
+ print_file_name(fp, module);
+ }
+ fputs("\n\n"
+ "# ASN.1 library linked modules used from central project(s):\n"
+ "BASE2_ASN1_MODULES =", fp);
+ for (i = 0; i < makefile->nASN1Modules; i++) {
+ const struct module_struct *module = makefile->ASN1Modules + i;
+ if (module->dir_name != NULL && isAsn1ModuleInLibrary(module->module_name))
+ print_file_name(fp, module);
+ }
}
}
if (makefile->preprocess) {
"PREPROCESSED_TTCN3_MODULES =", fp);
for (i = 0; i < makefile->nTTCN3PPModules; i++) {
const struct module_struct *module = makefile->TTCN3PPModules + i;
- if (module->dir_name == NULL || !makefile->central_storage)
- print_preprocessed_file_name(fp, module);
+ if (module->dir_name == NULL || !makefile->central_storage)
+ print_preprocessed_file_name(fp, module);
}
if (makefile->central_storage) {
fputs("\n\n"
"# TTCN-3 files generated by the CPP used from central project(s):\n"
"BASE_PREPROCESSED_TTCN3_MODULES =", fp);
- for (i = 0; i < makefile->nTTCN3PPModules; i++) {
- const struct module_struct *module = makefile->TTCN3PPModules + i;
- if (module->dir_name != NULL)
- print_preprocessed_file_name(fp, module);
+ if (!makefile->linkingStrategy) {
+ for (i = 0; i < makefile->nTTCN3PPModules; i++) {
+ const struct module_struct *module = makefile->TTCN3PPModules + i;
+ if (module->dir_name != NULL)
+ print_preprocessed_file_name(fp, module);
+ }
+ }
+ else { // new linking strategy
+ for (i = 0; i < makefile->nTTCN3PPModules; i++) {
+ const struct module_struct *module = makefile->TTCN3PPModules + i;
+ if (module->dir_name != NULL && !isTtcnPPFileInLibrary(module->file_name))
+ print_preprocessed_file_name(fp, module);
+ }
+ fputs("\n\n"
+ "# TTCN-3 library linked files generated by the CPP used from central project(s):\n"
+ "BASE2_PREPROCESSED_TTCN3_MODULES =", fp);
+ for (i = 0; i < makefile->nTTCN3PPModules; i++) {
+ const struct module_struct *module = makefile->TTCN3PPModules + i;
+ if (module->dir_name != NULL && isTtcnPPFileInLibrary(module->file_name))
+ print_preprocessed_file_name(fp, module);
+ }
}
}
}
fputs("\nGENERATED_HEADERS =", fp);
if (makefile->gnu_make) {
fputs(" $(GENERATED_SOURCES:.cc=.hh)", fp);
- } else {
+ }
+ else {
for (i = 0; i < makefile->nTTCN3Modules; i++) {
- const struct module_struct *module = makefile->TTCN3Modules + i;
- if (module->dir_name == NULL || !makefile->central_storage)
- print_generated_file_name(fp, module, FALSE, ".hh");
+ const struct module_struct *module = makefile->TTCN3Modules + i;
+ if (module->dir_name == NULL || !makefile->central_storage)
+ print_generated_file_name(fp, module, FALSE, ".hh");
}
if (makefile->preprocess) {
for (i = 0; i < makefile->nTTCN3PPModules; i++) {
}
}
for (i = 0; i < makefile->nASN1Modules; i++) {
- const struct module_struct *module = makefile->ASN1Modules + i;
- if (module->dir_name == NULL || !makefile->central_storage)
- print_generated_file_name(fp, module, FALSE, ".hh");
+ const struct module_struct *module = makefile->ASN1Modules + i;
+ if (module->dir_name == NULL || !makefile->central_storage)
+ print_generated_file_name(fp, module, FALSE, ".hh");
}
}
if (makefile->central_storage) {
}
fputs("\nBASE_GENERATED_HEADERS =", fp);
if (makefile->gnu_make) {
- fputs(" $(BASE_GENERATED_SOURCES:.cc=.hh)", fp);
+ fputs(" $(BASE_GENERATED_SOURCES:.cc=.hh)", fp);
} else {
- for (i = 0; i < makefile->nTTCN3Modules; i++) {
- const struct module_struct *module = makefile->TTCN3Modules + i;
- if (module->dir_name != NULL)
- print_generated_file_name(fp, module, TRUE, ".hh");
- }
- if (makefile->preprocess) {
- for (i = 0; i < makefile->nTTCN3PPModules; i++) {
- const struct module_struct *module = makefile->TTCN3PPModules + i;
- if (module->dir_name != NULL)
- print_generated_file_name(fp, module, TRUE, ".hh");
- }
- }
- for (i = 0; i < makefile->nASN1Modules; i++) {
- const struct module_struct *module = makefile->ASN1Modules + i;
- if (module->dir_name != NULL)
- print_generated_file_name(fp, module, TRUE, ".hh");
- }
+ for (i = 0; i < makefile->nTTCN3Modules; i++) {
+ const struct module_struct *module = makefile->TTCN3Modules + i;
+ if (module->dir_name != NULL)
+ print_generated_file_name(fp, module, TRUE, ".hh");
+ }
+ if (makefile->preprocess) {
+ for (i = 0; i < makefile->nTTCN3PPModules; i++) {
+ const struct module_struct *module = makefile->TTCN3PPModules + i;
+ if (module->dir_name != NULL)
+ print_generated_file_name(fp, module, TRUE, ".hh");
+ }
+ }
+ for (i = 0; i < makefile->nASN1Modules; i++) {
+ const struct module_struct *module = makefile->ASN1Modules + i;
+ if (module->dir_name != NULL)
+ print_generated_file_name(fp, module, TRUE, ".hh");
+ }
+ }
+ }
+
+ if (makefile->linkingStrategy) {
+ fputs("\n\n"
+ "# C++ source & header files generated from the TTCN-3 "
+ " library linked modules of\n"
+ "# central project(s):\n"
+ "BASE2_GENERATED_SOURCES =", fp);
+ if (makefile->gnu_make && makefile->BaseTTCN3ModulesRegular) {
+ fputs(" $(BASE2_TTCN3_MODULES:.ttcn=.cc)", fp);
+ fputs(" $(BASE2_ASN1_MODULES:.asn=.cc)", fp);
+ if (makefile->preprocess)
+ fputs(" $(BASE2_TTCN3_PP_MODULES:.ttcnpp=.cc)", fp);
+ }
+ else {
+ for (i = 0; i < makefile->nTTCN3Modules; i++) {
+ const struct module_struct *module = makefile->TTCN3Modules + i;
+ if (module->dir_name != NULL && isTtcn3ModuleInLibrary(module->module_name)) {
+ print_generated_file_name(fp, module, TRUE, ".cc");
+ }
+ }
+ if (makefile->preprocess) {
+ for (i = 0; i < makefile->nTTCN3PPModules; i++) {
+ const struct module_struct *module = makefile->TTCN3PPModules + i;
+ if (module->dir_name != NULL && isTtcnPPFileInLibrary(module->file_name)) {
+ print_generated_file_name(fp, module, TRUE, ".cc");
+ }
+ }
+ }
}
+
+ fputs("\nBASE2_GENERATED_HEADERS =", fp);
+ if (makefile->gnu_make) {
+ fputs(" $(BASE2_GENERATED_SOURCES:.cc=.hh)", fp);
+ }
+ else
+ ERROR("the usage of 'Z' flag requires GNU make");
}
+
fputs("\n\n"
"# C/C++ Source & header files of Test Ports, external functions "
- "and\n"
- "# other modules:\n"
+ "and\n"
+ "# other modules:\n"
"USER_SOURCES =", fp);
for (i = 0; i < makefile->nUserFiles; i++) {
const struct user_struct *user = makefile->UserFiles + i;
if (user->dir_name == NULL || !makefile->central_storage)
- print_source_name(fp, user);
+ print_source_name(fp, user);
}
fprint_extra_targets(fp, makefile->target_placement_list, "USER_SOURCES");
fputs("\nUSER_HEADERS =", fp);
fputs(" $(USER_SOURCES:.cc=.hh)", fp);
} else {
for (i = 0; i < makefile->nUserFiles; i++) {
- const struct user_struct *user = makefile->UserFiles + i;
- if (user->dir_name == NULL || !makefile->central_storage)
- print_header_name(fp, user);
+ const struct user_struct *user = makefile->UserFiles + i;
+ if (user->dir_name == NULL || !makefile->central_storage)
+ print_header_name(fp, user);
}
}
fprint_extra_targets(fp, makefile->target_placement_list, "USER_HEADERS");
if (makefile->central_storage) {
fputs("\n\n"
"# C/C++ Source & header files of Test Ports, external functions "
- "and\n"
- "# other modules used from central project(s):\n"
+ "and\n"
+ "# other modules used from central project(s):\n"
"BASE_USER_SOURCES =", fp);
- for (i = 0; i < makefile->nUserFiles; i++) {
- const struct user_struct *user = makefile->UserFiles + i;
- if (user->dir_name != NULL)
- print_source_name(fp, user);
+ if (!makefile->linkingStrategy) {
+ for (i = 0; i < makefile->nUserFiles; i++) {
+ const struct user_struct *user = makefile->UserFiles + i;
+ if (user->dir_name != NULL) {
+ print_source_name(fp, user);
+ }
+ }
+ fputs("\nBASE_USER_HEADERS =", fp);
+ if (makefile->gnu_make && makefile->BaseUserHeadersRegular) {
+ fputs(" $(BASE_USER_SOURCES:.cc=.hh)", fp);
+ }
+ else {
+ for (i = 0; i < makefile->nUserFiles; i++) {
+ const struct user_struct *user = makefile->UserFiles + i;
+ if (user->dir_name != NULL)
+ print_header_name(fp, user);
+ }
+ }
}
- fputs("\nBASE_USER_HEADERS =", fp);
- if (makefile->gnu_make && makefile->BaseUserHeadersRegular) {
- fputs(" $(BASE_USER_SOURCES:.cc=.hh)", fp);
- } else {
- for (i = 0; i < makefile->nUserFiles; i++) {
- const struct user_struct *user = makefile->UserFiles + i;
- if (user->dir_name != NULL)
- print_header_name(fp, user);
- }
+ else {
+ for (i = 0; i < makefile->nUserFiles; i++) {
+ const struct user_struct *user = makefile->UserFiles + i;
+ if (user->dir_name != NULL && !isSourceFileInLibrary(user->source_name)) {
+ print_source_name(fp, user);
+ }
+ }
+ fputs("\nBASE_USER_HEADERS =", fp);
+ if (makefile->gnu_make && makefile->BaseUserHeadersRegular) {
+ fputs(" $(BASE_USER_SOURCES:.cc=.hh)", fp);
+ }
+ else {
+ for (i = 0; i < makefile->nUserFiles; i++) {
+ const struct user_struct *user = makefile->UserFiles + i;
+ if (user->dir_name != NULL && !isHeaderFileInLibrary(user->header_name))
+ print_header_name(fp, user);
+ }
+ }
+
+ fputs("\n\n"
+ "# C/C++ Source & header files of Test Ports, external functions "
+ "and\n"
+ "# other modules used from library linked central project(s):\n"
+ "BASE2_USER_SOURCES =", fp);
+ for (i = 0; i < makefile->nUserFiles; i++) {
+ const struct user_struct *user = makefile->UserFiles + i;
+ if (user->dir_name != NULL && isSourceFileInLibrary(user->source_name)) {
+ print_source_name(fp, user);
+ }
+ }
+ fputs("\nBASE2_USER_HEADERS =", fp);
+ if (makefile->gnu_make && makefile->BaseUserHeadersRegular) {
+ fputs(" $(BASE2_USER_SOURCES:.cc=.hh)", fp);
+ }
+ else {
+ for (i = 0; i < makefile->nUserFiles; i++) {
+ const struct user_struct *user = makefile->UserFiles + i;
+ if (user->dir_name != NULL && isHeaderFileInLibrary(user->header_name))
+ print_header_name(fp, user);
+ }
+ }
}
}
-
if (makefile->dynamic) {
fputs("\n\n"
"# Shared object files of this project:\n"
fputs("\n\n"
"# Object files of this project that are needed for the executable "
- "test suite:\n"
+ "test suite:\n"
"OBJECTS = $(GENERATED_OBJECTS) $(USER_OBJECTS)\n\n" /* never := */
"GENERATED_OBJECTS =", fp);
if (makefile->gnu_make) {
fputs("\n\n"
"# Shared object files of central project(s):\n"
"BASE_SHARED_OBJECTS =", fp);
+ if (!makefile->linkingStrategy) {
+ if (makefile->gnu_make) {
+ fputs(" $(BASE_GENERATED_SOURCES:.cc=.so)", fp);
+ }
+ else {
+ for (i = 0; i < makefile->nTTCN3Modules; i++) {
+ const struct module_struct *module = makefile->TTCN3Modules + i;
+ if (module->dir_name != NULL)
+ print_generated_file_name(fp, module, TRUE, ".so");
+ }
+ if (makefile->preprocess) {
+ for (i = 0; i < makefile->nTTCN3PPModules; i++) {
+ const struct module_struct *module =
+ makefile->TTCN3PPModules + i;
+ if (module->dir_name != NULL)
+ print_generated_file_name(fp, module, TRUE, ".so");
+ }
+ }
+ for (i = 0; i < makefile->nASN1Modules; i++) {
+ const struct module_struct *module = makefile->ASN1Modules + i;
+ if (module->dir_name != NULL)
+ print_generated_file_name(fp, module, TRUE, ".so");
+ }
+ }
+ if (makefile->gnu_make && makefile->BaseUserSourcesRegular) {
+ fputs(" $(BASE_USER_SOURCES:.cc=.so)", fp);
+ }
+ else {
+ for (i = 0; i < makefile->nUserFiles; i++) {
+ const struct user_struct *user = makefile->UserFiles + i;
+ if (user->dir_name != NULL)
+ print_shared_object_name(fp, user);
+ }
+ }
+ }
+ else { // new linkingStrategy
+ if (makefile->gnu_make) {
+ fputs(" $(BASE_GENERATED_SOURCES:.cc=.so)", fp);
+ }
+ else
+ ERROR("the usage of 'Z' flag requires GNU make");
+
+ if (makefile->gnu_make && makefile->BaseUserSourcesRegular) {
+ fputs(" $(BASE_USER_SOURCES:.cc=.so)", fp);
+ }
+ else {
+ for (i = 0; i < makefile->nUserFiles; i++) {
+ const struct user_struct *user = makefile->UserFiles + i;
+ if (user->dir_name != NULL && !isSourceFileInLibrary(user->source_name))
+ print_shared_object_name(fp, user);
+ }
+ }
+ }
+ } /* if dynamic */
+ fputs("\n\n"
+ "# Object files of central project(s) that are needed for the "
+ "executable test suite:\n"
+ "BASE_OBJECTS =", fp);
+ if (!makefile->linkingStrategy) {
if (makefile->gnu_make) {
- fputs(" $(BASE_GENERATED_SOURCES:.cc=.so)", fp);
- } else {
+ fputs(" $(BASE_GENERATED_SOURCES:.cc=.o)", fp);
+ }
+ else {
for (i = 0; i < makefile->nTTCN3Modules; i++) {
const struct module_struct *module = makefile->TTCN3Modules + i;
if (module->dir_name != NULL)
- print_generated_file_name(fp, module, TRUE, ".so");
+ print_generated_file_name(fp, module, TRUE, ".o");
}
if (makefile->preprocess) {
for (i = 0; i < makefile->nTTCN3PPModules; i++) {
- const struct module_struct *module =
- makefile->TTCN3PPModules + i;
+ const struct module_struct *module = makefile->TTCN3PPModules + i;
if (module->dir_name != NULL)
- print_generated_file_name(fp, module, TRUE, ".so");
+ print_generated_file_name(fp, module, TRUE, ".o");
}
}
for (i = 0; i < makefile->nASN1Modules; i++) {
const struct module_struct *module = makefile->ASN1Modules + i;
if (module->dir_name != NULL)
- print_generated_file_name(fp, module, TRUE, ".so");
+ print_generated_file_name(fp, module, TRUE, ".o");
}
}
if (makefile->gnu_make && makefile->BaseUserSourcesRegular) {
- fputs(" $(BASE_USER_SOURCES:.cc=.so)", fp);
- } else {
+ fputs(" $(BASE_USER_SOURCES:.cc=.o)", fp);
+ }
+ else {
for (i = 0; i < makefile->nUserFiles; i++) {
const struct user_struct *user = makefile->UserFiles + i;
if (user->dir_name != NULL)
- print_shared_object_name(fp, user);
+ print_object_name(fp, user);
}
}
- } /* if dynamic */
- fputs("\n\n"
- "# Object files of central project(s) that are needed for the "
- "executable test suite:\n"
- "BASE_OBJECTS =", fp);
- if (makefile->gnu_make) {
- fputs(" $(BASE_GENERATED_SOURCES:.cc=.o)", fp);
- } else {
- for (i = 0; i < makefile->nTTCN3Modules; i++) {
- const struct module_struct *module = makefile->TTCN3Modules + i;
- if (module->dir_name != NULL)
- print_generated_file_name(fp, module, TRUE, ".o");
+ }
+ else { // new linkingStrategy
+ if (makefile->gnu_make) {
+ fputs(" $(BASE_GENERATED_SOURCES:.cc=.o)", fp);
}
- if (makefile->preprocess) {
- for (i = 0; i < makefile->nTTCN3PPModules; i++) {
- const struct module_struct *module = makefile->TTCN3PPModules + i;
- if (module->dir_name != NULL)
- print_generated_file_name(fp, module, TRUE, ".o");
- }
+ else
+ ERROR("the usage of 'Z' flag requires GNU make");
+
+ if (makefile->gnu_make && makefile->BaseUserSourcesRegular) {
+ fputs(" $(BASE_USER_SOURCES:.cc=.o)", fp);
}
- for (i = 0; i < makefile->nASN1Modules; i++) {
- const struct module_struct *module = makefile->ASN1Modules + i;
- if (module->dir_name != NULL)
- print_generated_file_name(fp, module, TRUE, ".o");
+ else {
+ for (i = 0; i < makefile->nUserFiles; i++) {
+ const struct user_struct *user = makefile->UserFiles + i;
+ if (user->dir_name != NULL && !isSourceFileInLibrary(user->source_name))
+ print_object_name(fp, user);
+ }
}
}
+ }
+ if (makefile->linkingStrategy) {
+ fputs("\n\n"
+ "# Object files of library linked central project(s) that are needed for the "
+ "executable test suite:\n"
+ "BASE2_OBJECTS =", fp);
+ if (makefile->gnu_make) {
+ if (makefile->dynamic)
+ fputs(" $(BASE2_GENERATED_SOURCES:.cc=.so)", fp);
+ else
+ fputs(" $(BASE2_GENERATED_SOURCES:.cc=.o)", fp);
+ }
+ else ERROR("the usage of 'Z' flag requires GNU make");
+
if (makefile->gnu_make && makefile->BaseUserSourcesRegular) {
- fputs(" $(BASE_USER_SOURCES:.cc=.o)", fp);
- } else {
+ if (makefile->dynamic)
+ fputs(" $(BASE2_USER_SOURCES:.cc=.so)", fp);
+ else
+ fputs(" $(BASE2_USER_SOURCES:.cc=.o)", fp);
+ }
+ else {
for (i = 0; i < makefile->nUserFiles; i++) {
const struct user_struct *user = makefile->UserFiles + i;
- if (user->dir_name != NULL)
- print_object_name(fp, user);
+ if (user->dir_name != NULL && isSourceFileInLibrary(user->source_name)) {
+ if (makefile->dynamic)
+ print_shared_object_name(fp, user);
+ else
+ print_object_name(fp, user);
+ }
+ }
+ }
+ if (makefile->hierarchical) {
+ fputs("\n\n"
+ "#Libraries of referenced project(s) that are needed for the "
+ "executable or library target:\n"
+ "BASE2_LIBRARY =", fp);
+ struct string2_list* head = getLinkerLibs(makefile->project_name);
+ struct string2_list* act_elem = head;
+ while (act_elem) {
+ if (act_elem->str2) {
+ fputs(" ", fp);
+ fprintf(fp, "%s/lib%s.%s", act_elem->str1, act_elem->str2,
+ isDynamicLibrary(act_elem->str2) ? "so" : "a");
+ }
+ act_elem = act_elem->next;
}
+ free_string2_list(head);
}
}
+
fputs("\n\n"
- "# Other files of the project (Makefile, configuration files, etc.)\n"
- "# that will be added to the archived source files:\n"
- "OTHER_FILES =", fp);
+ "# Other files of the project (Makefile, configuration files, etc.)\n"
+ "# that will be added to the archived source files:\n"
+ "OTHER_FILES =", fp);
for (i = 0; i < makefile->nOtherFiles; i++)
fprintf(fp, " %s", makefile->OtherFiles[i]);
fprint_extra_targets(fp, makefile->target_placement_list, "OTHER_FILES");
fputs(".exe", fp);
}
#endif
- fputs("\n", fp);
-
+ fputs("\n\n", fp);
+ if (makefile->linkingStrategy) {
+#ifndef WIN32
+ fputs("DYNAMIC_LIBRARY = lib$(EXECUTABLE).so\n", fp);
+ fputs("STATIC_LIBRARY = lib$(EXECUTABLE).a\n", fp);
+#else
+ char* name_prefix = cut_suffix(makefile->ets_name);
+ fprintf(fp, "DYNAMIC_LIBRARY = lib%s.so\n", name_prefix);
+ fprintf(fp, "STATIC_LIBRARY = lib%s.a\n", name_prefix);
+ Free(name_prefix);
+#endif
+ }
/* LIBRARY variable */
ets_suffix = get_suffix(makefile->ets_name);
if (ets_suffix != NULL && !strcmp(ets_suffix, "exe")) {
char* name_prefix = cut_suffix(makefile->ets_name);
- fprintf(fp, "\n\nLIBRARY = %s%s\n", name_prefix ? name_prefix : "library",
- makefile->dynamic ? "_lib.so" : ".a");
- Free(name_prefix);
- } else {
- fprintf(fp, "\n\nLIBRARY = %s%s\n", makefile->ets_name,
- makefile->dynamic ? "_lib.so" : ".a");
+ fprintf(fp, "\n\nLIBRARY = %s%s%s\n", "lib", name_prefix ? name_prefix : "library",
+ makefile->dynamic ? ".so" : ".a");
+ Free(name_prefix);
}
+ else {
+#ifndef WIN32
+ fprintf(fp, "\n\nLIBRARY = lib$(EXECUTABLE)%s\n",
+ makefile->dynamic ? ".so" : ".a");
+#else
+ fprintf(fp, "\n\nLIBRARY = lib%s%s\n",
+ makefile->ets_name, makefile->dynamic ? ".so" : ".a");
+#endif
+ }
} else {
fputs("\n\n"
"EXECUTABLE =\n"
"LIBRARY =\n", fp);
}
-
- fprintf(fp, "\n"
+ if (!makefile->linkingStrategy || !buildObjects(makefile->project_name, add_refd_prjs)) {
+ fprintf(fp, "\n"
"TARGET = $(%s)", makefile->library ? "LIBRARY" : "EXECUTABLE");
-
+ }
+ else {
+ if (makefile->dynamic) {
+ fputs("\n"
+ "TARGET = $(SHARED_OBJECTS)", fp);
+ }
+ else {
+ fputs("\n"
+ "TARGET = $(OBJECTS)", fp);
+ }
+ }
fputs("\n\n"
"#\n"
"# Do not modify these unless you know what you are doing...\n"
/* There is no need to create the .so for all the source files */
fputs("$(EXECUTABLE): $(LIBRARY)\n"
"\tif $(CXX) $(LDFLAGS) -o $@ $(LIBRARY)", fp);
- } else {
- fprintf(fp, "$(EXECUTABLE): %s", makefile->dynamic ? "$(SHARED_OBJECTS)" : "$(OBJECTS)");
+ }
+ else {
+ fprintf(fp, "$(EXECUTABLE): %s", makefile->dynamic ? "$(SHARED_OBJECTS)" : "$(OBJECTS)");
+ if (!makefile->linkingStrategy) { // use the old linking method
if (makefile->central_storage) {
if (makefile->dynamic) {
fputs(" $(BASE_SHARED_OBJECTS)", fp);
fputs(" $(BASE_OBJECTS)", fp);
}
}
- fputs("\n"
- "\tif $(CXX) $(LDFLAGS) -o $@ ", fp); /* start writing the link step */
- if (makefile->gnu_make) fputs("$^", fp);
- else {
+ }
+ else {
+ if (!makefile->library) {
if (makefile->dynamic) {
- fputs("$(SHARED_OBJECTS)", fp);
+ fputs(" $(BASE_SHARED_OBJECTS)", fp);
+ }
+ else {
+ fputs(" $(BASE_OBJECTS)", fp);
+ }
+ if (makefile->hierarchical) {
+ fputs(" $(BASE2_LIBRARY)", fp);
+ }
+ }
+ }
+ fprintf(fp, "\n"
+ "\tif $(CXX) $(LDFLAGS) -o $@ %s",
+#if defined (SOLARIS) || defined (SOLARIS8)
+ "");
+#else
+ makefile->dynamic ? "-Wl,--no-as-needed " : ""); /* start writing the link step */
+#endif
+ if (makefile->gnu_make) fputs("$^", fp);
+ else {
+ if (makefile->dynamic) {
+ fputs("$(SHARED_OBJECTS)", fp);
if (makefile->central_storage)
- fputs(" $(BASE_SHARED_OBJECTS)", fp);
- } else {
- fputs("$(OBJECTS)", fp);
+ fputs(" $(BASE_SHARED_OBJECTS)", fp);
+ }
+ else {
+ fputs("$(OBJECTS)", fp);
if (makefile->central_storage)
- fputs(" $(BASE_OBJECTS)", fp);
- }
+ fputs(" $(BASE_OBJECTS)", fp);
+ }
}
}
"\t-L$(TTCN3_DIR)/lib -l$(TTCN3_LIB)"
" \\\n"
"\t-L$(OPENSSL_DIR)/lib -lcrypto");
- if (makefile->linkerlibraries) {
- struct string_list* act_elem = makefile->linkerlibraries;
- while (act_elem) {
- if (act_elem->str) {
- fprintf(fp, " -l%s", act_elem->str);
+ if (!makefile->linkingStrategy) {
+ if (makefile->linkerlibraries) {
+ struct string_list* act_elem = makefile->linkerlibraries;
+ while (act_elem) {
+ if (act_elem->str) {
+ fprintf(fp, " -l%s", act_elem->str);
+ }
+ act_elem = act_elem->next;
}
- act_elem = act_elem->next;
}
- }
- if (makefile->linkerlibsearchpath) {
- struct string_list* act_elem = makefile->linkerlibsearchpath;
- while (act_elem) {
- if (act_elem->str) {
- fprintf(fp, " -L%s", act_elem->str);
+ if (makefile->linkerlibsearchpath) {
+ struct string_list* act_elem = makefile->linkerlibsearchpath;
+ while (act_elem) {
+ if (act_elem->str) {
+ fprintf(fp, " -L%s", act_elem->str);
+ }
+ act_elem = act_elem->next;
}
- act_elem = act_elem->next;
}
+ fprintf(fp, " \\\n"
+ "\t-L$(XMLDIR)/lib $($(PLATFORM)_LIBS); \\\n"
+ "\tthen : ; else $(TTCN3_DIR)/bin/titanver $(OBJECTS); exit 1; fi\n");
+ }
+ else { // new linking strategy
+ fputs (" \\\n", fp);
+ if (makefile->linkerlibraries && !makefile->library) {
+ struct string2_list* head = getLinkerLibs(makefile->project_name);
+ struct string2_list* act_elem = head;
+ while (act_elem) {
+ if (act_elem->str1 && act_elem->str2) {
+ fprintf(fp, "\t-L%s -Wl,-rpath=%s -l%s \\\n", act_elem->str1, act_elem->str1, act_elem->str2);
+ }
+ act_elem = act_elem->next;
+ }
+ free_string2_list(head);
+
+ struct string_list* act_head = getExternalLibPathes(makefile->project_name);
+ struct string_list* act_ext_elem = act_head;
+ while (act_ext_elem) {
+ if (act_ext_elem->str) {
+ fprintf(fp, "\t-L%s \\\n", act_ext_elem->str);
+ }
+ act_ext_elem = act_ext_elem->next;
+ }
+ free_string_list(act_head);
+ act_head = getExternalLibs(makefile->project_name);
+ act_ext_elem = act_head;
+ while (act_ext_elem) {
+ if (act_ext_elem->str) {
+ fprintf(fp, "\t-l%s \\\n", act_ext_elem->str);
+ }
+ act_ext_elem = act_ext_elem->next;
+ }
+ free_string_list(act_head);
+ }
+ fprintf(fp,
+ "\t-L$(XMLDIR)/lib $($(PLATFORM)_LIBS); \\\n"
+ "\tthen : ; else $(TTCN3_DIR)/bin/titanver $(OBJECTS); exit 1; fi\n");
}
- fprintf(fp, " \\\n"
- "\t-L$(XMLDIR)/lib $($(PLATFORM)_LIBS); \\\n"
- "\tthen : ; else $(TTCN3_DIR)/bin/titanver $(OBJECTS); exit 1; fi\n");
/* If the compiler will not be run because there are no TTCN(PP) or ASN.1
* files, create the "compile" marker file which is checked by the
* superior makefile if using this project as central storage */
/* target $(LIBRARY) */
if (makefile->dynamic) {
- fputs("\n"
- "$(LIBRARY): $(OBJECTS)\n"
- "\t$(CXX) -shared -o $@ $(OBJECTS)", fp);
- if (makefile->central_storage) {
- fputs(" $(BASE_SHARED_OBJECTS)", fp);
+ fprintf(fp, "\n"
+ "$(LIBRARY): $(OBJECTS)%s\n"
+ "\t$(CXX) -shared -o $@ $(OBJECTS)",
+ makefile->hierarchical ? " $(BASE2_LIBRARY)" : "");
+ if (makefile->central_storage && !makefile->linkingStrategy) {
+ fputs(" $(BASE_SHARED_OBJECTS) ;\n"
+ "\tln -s $@ $(subst lib, ,$@) > /dev/null 2>&1 ;", fp);
}
- } else {
- fputs("\n"
- "$(LIBRARY): $(OBJECTS)\n"
- "\t$(AR) -r $(ARFLAGS) $(LIBRARY) $(OBJECTS)", fp);
- if (makefile->central_storage) {
+ if (makefile->linkingStrategy) {
+ struct string2_list* head = getLinkerLibs(makefile->project_name);
+ struct string2_list* act_elem = head;
+ // If the project is Executable on Top Level the linker can link the *.a and *.so together
+ while (act_elem && !isTopLevelExecutable(makefile->project_name)) {
+ if (act_elem->str1 && act_elem->str2 && isDynamicLibrary(act_elem->str2)) {
+ fputs(" \\\n", fp);
+ fprintf(fp, "\t-L%s -Wl,-rpath=%s -l%s", act_elem->str1, act_elem->str1, act_elem->str2);
+ }
+ else {
+ const char* mainLibName = getLibFromProject(makefile->project_name);
+ ERROR("Library archive 'lib%s.a' cannot be linked to dynamic library 'lib%s.so' "
+ "in project '%s' ",
+ act_elem->str2, mainLibName ? mainLibName : "", makefile->project_name);
+ free_string2_list(head);
+ exit(EXIT_FAILURE);
+ }
+ act_elem = act_elem->next;
+ }
+ free_string2_list(head);
+ struct string_list* act_head = getExternalLibPathes(makefile->project_name);
+ struct string_list* act_ext_elem = act_head;
+ while (act_ext_elem) {
+ if (act_ext_elem->str) {
+ fputs(" \\\n", fp);
+ fprintf(fp, "\t-L%s", act_ext_elem->str);
+ }
+ act_ext_elem = act_ext_elem->next;
+ }
+ free_string_list(act_head);
+ act_head = getExternalLibs(makefile->project_name);
+ act_ext_elem = act_head;
+ while (act_ext_elem) {
+ if (act_ext_elem->str) {
+ fputs(" \\\n", fp);
+ fprintf(fp, "\t-l%s", act_ext_elem->str);
+ }
+ act_ext_elem = act_ext_elem->next;
+ }
+ free_string_list(act_head);
+ }
+ }
+ else { // static linking
+ fprintf(fp, "\n"
+ "$(LIBRARY): $(OBJECTS)%s\n"
+ "\t$(AR) -r%s $(ARFLAGS) $(LIBRARY) $(OBJECTS)",
+ makefile->hierarchical ? " $(BASE2_LIBRARY)" : "",
+ makefile->linkingStrategy ? "cT" : "");
+ if (makefile->central_storage && !makefile->linkingStrategy) {
fputs(" $(BASE_OBJECTS)", fp);
}
+ if (makefile->linkingStrategy) {
+ if ( makefile->library) {
+ struct string2_list* head = getLinkerLibs(makefile->project_name);
+ struct string2_list* act_elem = head;
+ while (act_elem) {
+ if (act_elem->str2 && !isDynamicLibrary(act_elem->str2)) {
+ fputs(" \\\n", fp);
+ fprintf(fp, "\t%s/lib%s.a", act_elem->str1, act_elem->str2);
+ }
+ else {
+ const char* mainLibName = getLibFromProject(makefile->project_name);
+ if (act_elem->str2) {
+ ERROR("Dynamic library 'lib%s.so' cannot be linked to static library 'lib%s.a' "
+ "in project '%s' ",
+ act_elem->str2, mainLibName ? mainLibName : "", makefile->project_name);
+ exit(EXIT_FAILURE);
+ }
+ else {
+ struct string_list* ext_libs = getExternalLibs(makefile->project_name);
+ if (ext_libs && ext_libs->str) {
+ ERROR("Third party dynamic library '%s' cannot be linked to static library 'lib%s.a' "
+ "in project '%s' ", ext_libs->str,
+ mainLibName ? mainLibName : "", makefile->project_name);
+ free_string_list(ext_libs);
+ exit(EXIT_FAILURE);
+ }
+ free_string_list(ext_libs);
+ }
+ }
+ act_elem = act_elem->next;
+ }
+ free_string2_list(head);
+
+ struct string_list* act_head = getExternalLibs(makefile->project_name);
+ struct string_list* act_ext_elem = act_head;
+ while (act_ext_elem) {
+ if (act_ext_elem->str && hasExternalLibrary(act_ext_elem->str, makefile->project_name)) {
+ fputs(" \\\n", fp);
+ fprintf(fp, "\tlib%s.a", act_ext_elem->str);
+ ERROR("linking static 3d party or sytem library 'lib%s.a' to "
+ "project library 'lib%s.a' is not supported ",
+ act_ext_elem->str, makefile->ets_name);
+ exit(EXIT_FAILURE);
+ }
+ act_ext_elem = act_ext_elem->next;
+ }
+ free_string_list(act_head);
+ }
+ }
}
-
fputs("\n\n.cc.o .c.o:\n"
"\t$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) -o $@ $<\n\n", fp);
if (makefile->central_storage) {
boolean is_first = TRUE;
- fputs("$(GENERATED_SOURCES) $(GENERATED_HEADERS): compile-all compile ", fp);
+ fprintf(fp, "$(GENERATED_SOURCES) $(GENERATED_HEADERS):%s compile-all compile ",
+ makefile->hierarchical ? " update" : "");
+
if (add_refd_prjs) fputs("referenced-dep", fp);
/* These extra compile dependencies for the generated .cc are here to
* check if all the referenced projects are up to date.
*/
if (!add_refd_prjs) for (i = 0; i < makefile->nBaseDirs; i++) {
const struct base_dir_struct *base_dir = makefile->BaseDirs + i;
- if (base_dir->has_modules) {
- if (is_first) {
- fputs(" \\\n", fp);
- is_first = FALSE;
- } else putc(' ', fp);
- fprintf(fp, "%s/compile", base_dir->dir_name);
- }
+ if (base_dir->has_modules) {
+ if (is_first) {
+ fputs(" \\\n", fp);
+ is_first = FALSE;
+ }
+ else putc(' ', fp);
+ fprintf(fp, "%s/compile", base_dir->dir_name);
+ }
}
-
if (makefile->preprocess) {
- fprintf(fp, "\n"
- "\t@if [ ! -f $@ ]; then %s compile-all; $(MAKE) compile-all; fi\n"
- "\n"
- "check:%s $(TTCN3_MODULES) $(BASE_TTCN3_MODULES) \\\n"
- "\t$(PREPROCESSED_TTCN3_MODULES) $(BASE_PREPROCESSED_TTCN3_MODULES) "
- "\\\n"
- "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES)\n"
- "\t$(TTCN3_DIR)/bin/compiler -s $(COMPILER_FLAGS) ", rm_command, add_refd_prjs?" referenced-check":"");
- if (makefile->gnu_make) {
- if (add_refd_prjs) // referenced-check cannot be compiled it is not a ttcn modul
- fputs("$(TTCN3_MODULES) $(BASE_TTCN3_MODULES) \\\n"
- "\t$(PREPROCESSED_TTCN3_MODULES) $(BASE_PREPROCESSED_TTCN3_MODULES) "
- "\\\n"
- "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES)\n", fp);
- else
- fputs("$^", fp);
- }
- else {
- fputs("\\\n"
- "\t$(TTCN3_MODULES) $(BASE_TTCN3_MODULES) \\\n"
- "\t$(PREPROCESSED_TTCN3_MODULES) "
- "$(BASE_PREPROCESSED_TTCN3_MODULES) \\\n"
- "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES)", fp);
- }
- fputs("\n\n"
- "compile: $(TTCN3_MODULES) $(PREPROCESSED_TTCN3_MODULES) "
- "$(ASN1_MODULES)\n"
- "\t$(TTCN3_DIR)/bin/compiler $(COMPILER_FLAGS) \\\n"
- "\t$(TTCN3_MODULES) $(BASE_TTCN3_MODULES) \\\n"
- "\t$(PREPROCESSED_TTCN3_MODULES) "
- "$(BASE_PREPROCESSED_TTCN3_MODULES) \\\n"
- "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES) - $?\n"
- "\ttouch $@\n"
- "\n"
- "compile-all: $(BASE_TTCN3_MODULES) "
- "$(BASE_PREPROCESSED_TTCN3_MODULES) \\\n"
- "$(BASE_ASN1_MODULES)\n"
- "\t$(MAKE) preprocess\n"
- "\t$(TTCN3_DIR)/bin/compiler $(COMPILER_FLAGS) \\\n"
- "\t$(TTCN3_MODULES) $(BASE_TTCN3_MODULES) \\\n"
- "\t$(PREPROCESSED_TTCN3_MODULES) $(BASE_PREPROCESSED_TTCN3_MODULES) "
- "\\\n"
- "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES) \\\n"
- "\t- $(TTCN3_MODULES) $(PREPROCESSED_TTCN3_MODULES) $(ASN1_MODULES)\n"
- "\ttouch $@ compile\n\n", fp);
- } else {
- fprintf(fp, "\n"
- "\t@if [ ! -f $@ ]; then %s compile-all; $(MAKE) compile-all; fi\n"
- "\n"
- "check:%s $(TTCN3_MODULES) $(BASE_TTCN3_MODULES) \\\n"
- "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES)\n"
- "\t$(TTCN3_DIR)/bin/compiler -s $(COMPILER_FLAGS) ", rm_command, add_refd_prjs?" referenced-check":"");
- if (makefile->gnu_make) {
- if (add_refd_prjs) // referenced-check cannot be compiled it is not a ttcn modul
- fputs("$(TTCN3_MODULES) $(BASE_TTCN3_MODULES) \\\n"
- "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES)\n", fp);
- else
- fputs("$^", fp);
- }
- else {
- fputs("\\\n"
- "\t$(TTCN3_MODULES) $(BASE_TTCN3_MODULES) \\\n"
- "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES)", fp);
- }
- fputs("\n\n"
- "compile: $(TTCN3_MODULES) $(ASN1_MODULES)\n"
- "\t$(TTCN3_DIR)/bin/compiler $(COMPILER_FLAGS) \\\n"
- "\t$(TTCN3_MODULES) $(BASE_TTCN3_MODULES) \\\n"
- "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES) \\\n"
- "\t- $?\n"
- "\ttouch $@\n"
- "\n"
- "compile-all: $(BASE_TTCN3_MODULES) $(BASE_ASN1_MODULES)\n"
- "\t$(TTCN3_DIR)/bin/compiler $(COMPILER_FLAGS) \\\n"
- "\t$(TTCN3_MODULES) $(BASE_TTCN3_MODULES) \\\n"
- "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES) \\\n"
- "\t- $(TTCN3_MODULES) $(ASN1_MODULES)\n"
- "\ttouch $@ compile\n\n", fp);
- }
- for (i = 0; i < makefile->nBaseDirs; i++) {
- const struct base_dir_struct *base_dir = makefile->BaseDirs + i;
- if (base_dir->has_modules) {
- size_t j;
- fprintf(fp, "%s/compile:", base_dir->dir_name);
- for (j = 0; j < makefile->nTTCN3Modules; j++) {
- const struct module_struct *module = makefile->TTCN3Modules + j;
- if (module->dir_name != NULL &&
- !strcmp(base_dir->dir_name, module->dir_name))
- print_file_name(fp, module);
- }
- for (j = 0; j < makefile->nTTCN3PPModules; j++) {
- const struct module_struct *module = makefile->TTCN3PPModules + j;
- if (module->dir_name != NULL &&
- !strcmp(base_dir->dir_name, module->dir_name))
- print_file_name(fp, module);
- }
- for (j = 0; j < makefile->nASN1Modules; j++) {
- const struct module_struct *module = makefile->ASN1Modules + j;
- if (module->dir_name != NULL &&
- !strcmp(base_dir->dir_name, module->dir_name))
- print_file_name(fp, module);
- }
- fprintf(fp, "\n"
- "\t@echo 'Central directory %s is not up-to-date!'\n"
- "\t@exit 2\n\n", base_dir->dir_name);
- }
+ fprintf(fp, "\n"
+ "\t@if [ ! -f $@ ]; then %s compile-all; $(MAKE) compile-all; fi\n"
+ "\n"
+ "check:%s $(TTCN3_MODULES) $(BASE_TTCN3_MODULES) %s\\\n"
+ "\t$(PREPROCESSED_TTCN3_MODULES) $(BASE_PREPROCESSED_TTCN3_MODULES) "
+ "%s\\\n"
+ "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES) %s\n"
+ "\t$(TTCN3_DIR)/bin/compiler -s $(COMPILER_FLAGS) ",
+ rm_command, add_refd_prjs?" referenced-check":"",
+ makefile->linkingStrategy ? "$(BASE2_TTCN3_MODULES) ":"",
+ makefile->linkingStrategy ? "$(BASE2_PREPROCESSED_TTCN3_MODULES) ":"",
+ makefile->linkingStrategy ? "$(BASE2_ASN1_MODULES) ":"");
+ if (makefile->gnu_make) {
+ if (add_refd_prjs) // referenced-check cannot be compiled it is not a ttcn modul
+ fprintf(fp, "$(TTCN3_MODULES) $(BASE_TTCN3_MODULES) %s\\\n"
+ "\t$(PREPROCESSED_TTCN3_MODULES) $(BASE_PREPROCESSED_TTCN3_MODULES) "
+ "%s\\\n"
+ "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES) %s\n",
+ makefile->linkingStrategy ? "$(BASE2_TTCN3_MODULES) ":"",
+ makefile->linkingStrategy ? "$(BASE2_PREPROCESSED_TTCN3_MODULES) ":"",
+ makefile->linkingStrategy ? "$(BASE2_ASN1_MODULES) ":"");
+ else
+ fputs("$^", fp);
+ }
+ else {
+ fputs("\\\n"
+ "\t$(TTCN3_MODULES) $(BASE_TTCN3_MODULES) \\\n"
+ "\t$(PREPROCESSED_TTCN3_MODULES) "
+ "$(BASE_PREPROCESSED_TTCN3_MODULES) \\\n"
+ "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES)", fp);
+ }
+ if (makefile->linkingStrategy && makefile->hierarchical) {
+ fputs("\n\n"
+ "update: $(BASE_TTCN3_MODULES) $(BASE_ASN1_MODULES) $(BASE_PREPROCESSED_TTCN3_MODULES) \\\n"
+ "\t$(BASE2_TTCN3_MODULES) $(BASE2_ASN1_MODULES) $(BASE2_PREPROCESSED_TTCN3_MODULES)\n"
+ "ifneq ($(wildcard $(GENERATED_SOURCES)), ) \n"
+ "ifeq ($(wildcard $?), ) \n"
+ "\ttouch compile-all; \n"
+ "\ttouch update; \n"
+ "endif\n"
+ "endif",fp);
+ }
+ fprintf(fp, "\n\n"
+ "compile: $(TTCN3_MODULES) $(PREPROCESSED_TTCN3_MODULES) "
+ "$(ASN1_MODULES)\n"
+ "\t@echo \"compiling \"'$(patsubst %%.tpd, %%, $(TPD))';\n"
+ "\t$(TTCN3_DIR)/bin/compiler $(COMPILER_FLAGS) \\\n"
+ "\t$(TTCN3_MODULES) $(BASE_TTCN3_MODULES) %s\\\n"
+ "\t$(PREPROCESSED_TTCN3_MODULES) $(BASE_PREPROCESSED_TTCN3_MODULES) %s\\\n"
+ "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES) %s - $?\n"
+ "\ttouch $@\n\n",
+ makefile->linkingStrategy ? "$(BASE2_TTCN3_MODULES) ":"",
+ makefile->linkingStrategy ? "$(BASE2_PREPROCESSED_TTCN3_MODULES) ":"",
+ makefile->linkingStrategy ? "$(BASE2_ASN1_MODULES)":"");
+ fprintf (fp,
+ "compile-all: $(BASE_TTCN3_MODULES) $(BASE_ASN1_MODULES) $(BASE_PREPROCESSED_TTCN3_MODULES) "
+ "%s"
+ "\t$(MAKE) preprocess\n"
+ "\t@echo \"compiling all \"'$(patsubst %%.tpd, %%, $(TPD))';\n"
+ "\t$(TTCN3_DIR)/bin/compiler $(COMPILER_FLAGS) \\\n"
+ "\t$(TTCN3_MODULES) $(BASE_TTCN3_MODULES) %s\\\n"
+ "\t$(PREPROCESSED_TTCN3_MODULES) $(BASE_PREPROCESSED_TTCN3_MODULES) %s"
+ "\\\n"
+ "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES) %s\\\n"
+ "\t- $(TTCN3_MODULES) $(PREPROCESSED_TTCN3_MODULES) $(ASN1_MODULES)\n"
+ "\ttouch $@ compile\n\n",
+ makefile->linkingStrategy ? "\\\n\t$(BASE2_TTCN3_MODULES) $(BASE2_ASN1_MODULES) "
+ "$(BASE2_PREPROCESSED_TTCN3_MODULES) \n":"\n",
+ makefile->linkingStrategy ? "$(BASE2_TTCN3_MODULES) ":"",
+ makefile->linkingStrategy ? "$(BASE2_PREPROCESSED_TTCN3_MODULES) ":"",
+ makefile->linkingStrategy ? "$(BASE2_ASN1_MODULES) ":"");
+ }
+ else {
+ fprintf(fp, "\n"
+ "\t@if [ ! -f $@ ]; then %s compile-all; $(MAKE) compile-all; fi\n", rm_command);
+ fprintf(fp, "\n"
+ "check:%s $(TTCN3_MODULES) $(BASE_TTCN3_MODULES) %s\\\n"
+ "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES) %s\n"
+ "\t$(TTCN3_DIR)/bin/compiler -s $(COMPILER_FLAGS) ",
+ add_refd_prjs?" referenced-check":"",
+ makefile->linkingStrategy ? "$(BASE2_TTCN3_MODULES) ":"",
+ makefile->linkingStrategy ? "$(BASE2_ASN1_MODULES) ":"");
+ if (makefile->gnu_make) {
+ if (add_refd_prjs) // referenced-check cannot be compiled it is not a ttcn modul
+ fprintf(fp, "$(TTCN3_MODULES) $(BASE_TTCN3_MODULES) %s\\\n"
+ "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES) %s\n",
+ makefile->linkingStrategy ? "$(BASE2_TTCN3_MODULES) ":"",
+ makefile->linkingStrategy ? "$(BASE2_ASN1_MODULES) ":"");
+ else
+ fputs("$^", fp);
}
- } else { /* not central storage */
+ else {
+ fputs("\\\n"
+ "\t$(TTCN3_MODULES) $(BASE_TTCN3_MODULES) \\\n"
+ "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES)", fp);
+ }
+
+ if (makefile->linkingStrategy && makefile->hierarchical) {
+ fputs("\n\n"
+ "update: $(BASE_TTCN3_MODULES) $(BASE_ASN1_MODULES) $(BASE_PREPROCESSED_TTCN3_MODULES) \\\n"
+ "\t$(BASE2_TTCN3_MODULES) $(BASE2_ASN1_MODULES) $(BASE2_PREPROCESSED_TTCN3_MODULES)\n"
+ "ifneq ($(wildcard $(GENERATED_SOURCES)), ) \n"
+ "ifeq ($(wildcard $?), ) \n"
+ "\ttouch compile-all; \n"
+ "\ttouch update; \n"
+ "endif\n"
+ "endif",fp);
+ }
+
+ fprintf(fp, "\n\n"
+ "compile: $(TTCN3_MODULES) $(ASN1_MODULES)\n"
+ "\t@echo \"compiling \"'$(patsubst %%.tpd, %%, $(TPD))';\n"
+ "\t$(TTCN3_DIR)/bin/compiler $(COMPILER_FLAGS) \\\n"
+ "\t$(TTCN3_MODULES) $(BASE_TTCN3_MODULES) %s\\\n"
+ "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES) %s\\\n"
+ "\t- $?\n"
+ "\ttouch $@\n\n",
+ makefile->linkingStrategy ? "$(BASE2_TTCN3_MODULES) " : "",
+ makefile->linkingStrategy ? "$(BASE2_ASN1_MODULES) " : "");
+ fprintf(fp,
+ "compile-all: $(BASE_TTCN3_MODULES) $(BASE_ASN1_MODULES) %s\n",
+ makefile->linkingStrategy ? "$(BASE2_TTCN3_MODULES) $(BASE2_ASN1_MODULES)" : "");
+ fputs("\t@echo \"compiling all \"'$(patsubst %.tpd, %, $(TPD))';\n", fp);
+ fprintf(fp,"\t$(TTCN3_DIR)/bin/compiler $(COMPILER_FLAGS) \\\n"
+ "\t$(TTCN3_MODULES) $(BASE_TTCN3_MODULES) %s\\\n"
+ "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES) %s\\\n"
+ "\t- $(TTCN3_MODULES) $(ASN1_MODULES)\n"
+ "\ttouch $@ compile\n\n",
+ makefile->linkingStrategy ? "$(BASE2_TTCN3_MODULES) " : "",
+ makefile->linkingStrategy ? "$(BASE2_ASN1_MODULES) " : "");
+ }
+ if (!makefile->hierarchical)
+ for (i = 0; i < makefile->nBaseDirs; i++) {
+ const struct base_dir_struct *base_dir = makefile->BaseDirs + i;
+ if (base_dir->has_modules) {
+ size_t j;
+ fprintf(fp, "%s/compile:", base_dir->dir_name);
+ for (j = 0; j < makefile->nTTCN3Modules; j++) {
+ const struct module_struct *module = makefile->TTCN3Modules + j;
+ if (module->dir_name != NULL &&
+ !strcmp(base_dir->dir_name, module->dir_name))
+ print_file_name(fp, module);
+ }
+ for (j = 0; j < makefile->nTTCN3PPModules; j++) {
+ const struct module_struct *module = makefile->TTCN3PPModules + j;
+ if (module->dir_name != NULL &&
+ !strcmp(base_dir->dir_name, module->dir_name))
+ print_file_name(fp, module);
+ }
+ for (j = 0; j < makefile->nASN1Modules; j++) {
+ const struct module_struct *module = makefile->ASN1Modules + j;
+ if (module->dir_name != NULL &&
+ !strcmp(base_dir->dir_name, module->dir_name))
+ print_file_name(fp, module);
+ }
+ fprintf(fp, "\n"
+ "\t@echo 'Central directory %s is not up-to-date!'\n"
+ "\t@exit 2\n\n", base_dir->dir_name);
+ }
+ }
+ }
+ else { /* not central storage */
fprintf(fp, "$(GENERATED_SOURCES) $(GENERATED_HEADERS): compile\n"
- "\t@if [ ! -f $@ ]; then %s compile; $(MAKE) compile; fi\n\n"
- "check: $(TTCN3_MODULES) ", rm_command);
+ "\t@if [ ! -f $@ ]; then %s compile; $(MAKE) compile; fi\n\n"
+ "check: $(TTCN3_MODULES) ", rm_command);
if (makefile->preprocess) fputs("$(PREPROCESSED_TTCN3_MODULES) ", fp);
fputs("$(ASN1_MODULES)\n"
- "\t$(TTCN3_DIR)/bin/compiler -s $(COMPILER_FLAGS) ", fp);
+ "\t$(TTCN3_DIR)/bin/compiler -s $(COMPILER_FLAGS) ", fp);
if (makefile->gnu_make) fputs("$^", fp);
else {
- fputs("\\\n"
- "\t$(TTCN3_MODULES) $(PREPROCESSED_TTCN3_MODULES) $(ASN1_MODULES)",
- fp);
+ fputs("\\\n"
+ "\t$(TTCN3_MODULES) $(PREPROCESSED_TTCN3_MODULES) $(ASN1_MODULES)",
+ fp);
}
fputs("\n\n"
- "compile: $(TTCN3_MODULES) ", fp);
+ "compile: $(TTCN3_MODULES) ", fp);
if (makefile->preprocess) fputs("$(PREPROCESSED_TTCN3_MODULES) ", fp);
fputs("$(ASN1_MODULES)\n"
- "\t$(TTCN3_DIR)/bin/compiler $(COMPILER_FLAGS) ", fp);
+ "\t$(TTCN3_DIR)/bin/compiler $(COMPILER_FLAGS) ", fp);
if (makefile->gnu_make) fputs("$^", fp);
else {
- fputs("\\\n"
- "\t$(TTCN3_MODULES) ", fp);
- if (makefile->preprocess) fputs("$(PREPROCESSED_TTCN3_MODULES) ", fp);
- fputs("$(ASN1_MODULES)", fp);
+ fputs("\\\n"
+ "\t$(TTCN3_MODULES) ", fp);
+ if (makefile->preprocess) fputs("$(PREPROCESSED_TTCN3_MODULES) ", fp);
+ fputs("$(ASN1_MODULES)", fp);
}
fputs(" - $?\n"
- "\ttouch $@\n"
- "\n", fp);
- }
- fprintf(fp, "clean:%s\n"
- "\t-%s $(EXECUTABLE) $(LIBRARY) $(OBJECTS) $(GENERATED_HEADERS) \\\n"
- "\t$(GENERATED_SOURCES) ", add_refd_prjs?" referenced-clean":"", rm_command);
- if (makefile->dynamic) fputs("$(SHARED_OBJECTS) ", fp);
- if (makefile->preprocess) fputs("$(PREPROCESSED_TTCN3_MODULES) ", fp);
- fputs("compile", fp);
- if (makefile->central_storage) fputs(" compile-all", fp);
- if (makefile->gcc_dep) fputs(" $(DEPFILES)", fp);
- fprintf(fp, " \\\n"
- "\ttags *.log%s",
- add_refd_prjs?" referenced*":"");
-
+ "\ttouch $@\n"
+ "\n", fp);
+ }
+// clean:
+ if (makefile->linkingStrategy) {
+ fprintf(fp, "clean:%s\n", (add_refd_prjs && !makefile->hierarchical) ?
+ " referenced-clean" : "");
+ if (makefile->dynamic && (makefile->central_storage || makefile->linkingStrategy)) {
+ fprintf(fp,"\tfind . -type l -name \"*.so\" -exec unlink {} \\;\n");
+ }
+ fprintf(fp, "\t%s $(EXECUTABLE) $(DYNAMIC_LIBRARY) $(STATIC_LIBRARY) "
+ "$(OBJECTS) $(GENERATED_HEADERS) \\\n"
+ "\t$(GENERATED_SOURCES) ", rm_command);
+ if (makefile->dynamic) fputs("$(SHARED_OBJECTS) ", fp);
+ if (makefile->preprocess) fputs("$(PREPROCESSED_TTCN3_MODULES) ", fp);
+ fputs("compile", fp);
+ if (makefile->central_storage) fputs(" compile-all", fp);
+ if (makefile->gcc_dep) fputs(" $(DEPFILES)", fp);
+ fprintf(fp, " \\\n"
+ "\ttags *.log%s%s\n\n",
+ add_refd_prjs?" referenced*":"",
+ makefile->hierarchical ? " update":"");
+ }
+ else {
+ fprintf(fp, "clean:%s\n"
+ "\t-%s $(EXECUTABLE) $(LIBRARY) $(OBJECTS) $(GENERATED_HEADERS) \\\n"
+ "\t$(GENERATED_SOURCES) ", add_refd_prjs?" referenced-clean":"", rm_command);
+ if (makefile->dynamic) fputs("$(SHARED_OBJECTS) ", fp);
+ if (makefile->preprocess) fputs("$(PREPROCESSED_TTCN3_MODULES) ", fp);
+ fputs("compile", fp);
+ if (makefile->central_storage) fputs(" compile-all", fp);
+ if (makefile->gcc_dep) fputs(" $(DEPFILES)", fp);
+ fprintf(fp, " \\\n"
+ "\ttags *.log%s",
+ add_refd_prjs?" referenced*":"");
+ }
+
+// clean-all:
+ if (makefile->linkingStrategy && makefile->hierarchical)
+ fprintf(fp, "clean-all: %s clean\n", add_refd_prjs ? "referenced-clean-all":"");
+
+// dep:
fputs("\n\ndep: $(GENERATED_SOURCES) $(USER_SOURCES)",fp);
- if (add_refd_prjs) fprintf(fp, "\n\t%s referenced-dep", rm_command);
+ if (add_refd_prjs) {
+ fprintf(fp, "\n\t%s referenced-dep", rm_command);
+ }
else fputs(" ;",fp);
-
+
if (makefile->gcc_dep) {
fprintf(fp, " \n\n"
"ifeq ($(findstring n,$(MAKEFLAGS)),)\n"
- "ifeq ($(filter clean check compile archive diag%s,$(MAKECMDGOALS)),)\n"
+ "ifeq ($(filter clean%s check compile archive diag%s,$(MAKECMDGOALS)),)\n"
"-include $(DEPFILES)\n"
"endif\n"
- "endif", (makefile->preprocess ? " preprocess" : ""));
+ "endif",
+ (makefile->linkingStrategy && makefile->hierarchical) ? " clean-all" : "",
+ (makefile->preprocess ? " preprocess" : ""));
/* Don't include .d files when cleaning etc.; make will try to build them
* and this involves running the Titan compiler. Same for preprocess.
* The check target would be pointless if running the compiler
if (makefile->gnu_make) fputs("$^", fp);
else fputs("$(GENERATED_SOURCES) $(USER_SOURCES)", fp);
}
- fprintf(fp, "\n\n"
- "archive:%s\n"
- "\tmkdir -p $(ARCHIVE_DIR)\n"
- "\ttar -cvhf - ", add_refd_prjs?" referenced-archive":"");
- if (makefile->central_storage) {
- fputs("$(TTCN3_MODULES) $(BASE_TTCN3_MODULES) \\\n", fp);
- if (makefile->preprocess) {
- fputs("\t$(TTCN3_PP_MODULES) $(BASE_TTCN3_PP_MODULES) "
- "$(TTCN3_INCLUDES)\\\n", fp);
+
+ if (makefile->linkingStrategy) {
+ fputs("\n\n"
+ "archive:\n"
+ "\t@perl $(TTCN3_DIR)/bin/ttcn3_archive.pl\n\n", fp);
+ }
+ else {
+ fputs("\n\n"
+ "archive:\n"
+ "\tmkdir -p $(ARCHIVE_DIR)\n"
+ "\ttar -cvhf - ", fp);
+ if (makefile->central_storage) {
+ fprintf(fp, "$(TTCN3_MODULES) $(BASE_TTCN3_MODULES) %s\\\n",
+ makefile->linkingStrategy ? "$(BASE2_TTCN3_MODULES) " : "");
+ if (makefile->preprocess) {
+ fprintf(fp, "\t$(TTCN3_PP_MODULES) $(BASE_TTCN3_PP_MODULES) "
+ "%s $(TTCN3_INCLUDES) \\\n",
+ makefile->linkingStrategy ? "$(BASE2_TTCN3_PP_MODULES)" : "");
+ }
+ fprintf(fp, "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES) %s\\\n"
+ "\t$(USER_HEADERS) $(BASE_USER_HEADERS) %s\\\n"
+ "\t$(USER_SOURCES) $(BASE_USER_SOURCES) %s",
+ makefile->linkingStrategy ? "$(BASE2_ASN1_MODULES) " : "",
+ makefile->linkingStrategy ? "$(BASE2_USER_HEADERS) " : "",
+ makefile->linkingStrategy ? "$(BASE2_USER_SOURCES)" : "");
}
- fputs("\t$(ASN1_MODULES) $(BASE_ASN1_MODULES) \\\n"
- "\t$(USER_HEADERS) $(BASE_USER_HEADERS) \\\n"
- "\t$(USER_SOURCES) $(BASE_USER_SOURCES)", fp);
- } else {
- fputs("$(TTCN3_MODULES) ", fp);
- if (makefile->preprocess) {
- fputs("$(TTCN3_PP_MODULES) \\\n"
- "\t$(TTCN3_INCLUDES) ", fp);
+ else {
+ fputs("$(TTCN3_MODULES) ", fp);
+ if (makefile->preprocess) {
+ fputs("$(TTCN3_PP_MODULES) \\\n"
+ "\t$(TTCN3_INCLUDES) ", fp);
+ }
+ fputs("$(ASN1_MODULES) \\\n"
+ "\t$(USER_HEADERS) $(USER_SOURCES)", fp);
}
- fputs("$(ASN1_MODULES) \\\n"
- "\t$(USER_HEADERS) $(USER_SOURCES)", fp);
+ fputs(" $(OTHER_FILES) \\\n"
+ "\t| gzip >$(ARCHIVE_DIR)/`basename $(TARGET) .exe`-"
+ "`date '+%y%m%d-%H%M'`.tgz\n\n", fp);
}
- fputs(" $(OTHER_FILES) \\\n"
- "\t| gzip >$(ARCHIVE_DIR)/`basename $(TARGET) .exe`-"
- "`date '+%y%m%d-%H%M'`.tgz\n\n", fp);
fprintf(fp, "diag:\n"
- "\t$(TTCN3_DIR)/bin/compiler -v 2>&1\n"
- "\t$(TTCN3_DIR)/bin/mctr_cli -v 2>&1\n"
- "\t$(CXX) -v 2>&1\n"
+ "\t$(TTCN3_DIR)/bin/compiler -v 2>&1\n"
+ "\t$(TTCN3_DIR)/bin/mctr_cli -v 2>&1\n"
+ "\t$(CXX) -v 2>&1\n"
"%s"
"\t@echo TTCN3_DIR=$(TTCN3_DIR)\n"
"\t@echo OPENSSL_DIR=$(OPENSSL_DIR)\n"
makefile->dynamic ? "" : "\t$(AR) -V 2>&1\n");
if (add_refd_prjs) {
- fputs("referenced-all referenced-shared_objects referenced-executable referenced-library \\\n"
- "referenced-objects referenced-check \\\n"
- "referenced-clean referenced-archive:\n"
- "\t@for dir in $(REFERENCED_PROJECT_DIRS); do \\\n"
- "\t $(MAKE) -C $$dir $(subst referenced-,,$@) || exit; \\\n"
- "\tdone; \n\n", fp);
+ fprintf(fp, "referenced-all referenced-shared_objects referenced-executable referenced-library \\\n"
+ "referenced-objects referenced-check \\\n"
+ "referenced-clean%s:\n"
+ "\t@for dir in $(REFERENCED_PROJECT_DIRS); do \\\n"
+ "\t $(MAKE) -C $$dir $(subst referenced-,,$@) || exit; \\\n"
+ "\tdone; \n\n",
+ (makefile->linkingStrategy && makefile->hierarchical) ? "-all" : "");
fputs("referenced-dep:\n"
"\t@for dir in $(REFERENCED_PROJECT_DIRS); do \\\n"
"\t $(MAKE) -C $$dir $(subst referenced-,,$@) || exit; \\\n"
} else {
NOTIFY("Makefile skeleton was generated.");
}
- } else {
- ERROR("Output file `%s' already exists. Use switch `-f' to force "
- "overwrite.", makefile->output_file);
+ }
+ else {
+ ERROR("Output file `%s' already exists. Use switch `%s' to force "
+ "overwrite.",
+ makefile->output_file,
+ makefile->linkingStrategy ? "-F" : "-f");
}
}
rv = set_working_dir(sub_proj_effective_work_dir);
if (rv) ERROR("Could not set working dir to `%s'", sub_proj_effective_work_dir);
else {
- printf("Executing `%s' in working directory `%s'...\n", command, sub_proj_effective_work_dir);
+ fprintf(stderr, "Executing `%s' in working directory `%s'...\n",
+ command, sub_proj_effective_work_dir);
rv = system(command);
if (rv) ERROR("Execution failed with error code %d", rv); // TODO: it's not clear what system()'s return codes can be in different situations and platforms
}
* command line switches. */
static void generate_makefile(size_t n_arguments, char *arguments[],
size_t n_other_files, const char *other_files[], const char *output_file,
- const char *ets_name, boolean gnu_make, boolean single_mode,
+ const char *ets_name, char *project_name, boolean gnu_make, boolean single_mode,
boolean central_storage, boolean absolute_paths, boolean preprocess,
boolean dump_makefile_data, boolean force_overwrite, boolean use_runtime_2,
boolean dynamic, boolean makedepend, boolean coverage,
const char *code_splitting_mode, const char *tcov_file_name,
- boolean Lflag, struct string_list* sub_project_dirs, struct string_list* ttcn3_prep_includes,
- struct string_list* ttcn3_prep_defines, struct string_list* prep_includes, struct string_list* prep_defines,
- boolean codesplittpd, boolean quietly, boolean disablesubtypecheck, const char* cxxcompiler,
- const char* optlevel, const char* optflags, boolean disableber, boolean disableraw, boolean disabletext,
+ boolean Lflag, boolean Zflag, boolean Hflag, struct string_list* sub_project_dirs, struct string_list* ttcn3_prep_includes,
+ struct string_list* ttcn3_prep_defines, struct string_list* ttcn3_prep_undefines, struct string_list* prep_includes,
+ struct string_list* prep_defines, struct string_list* prep_undefines, boolean codesplittpd, boolean quietly, boolean disablesubtypecheck,
+ 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, struct string_list* solspeclibraries, struct string_list* sol8speclibraries,
struct makefile_struct makefile;
init_makefile_struct(&makefile);
+ makefile.project_name = project_name;
makefile.central_storage = central_storage;
makefile.gnu_make = gnu_make;
makefile.preprocess = preprocess;
makefile.gcc_dep = gnu_make && !makedepend;
makefile.coverage = coverage;
makefile.library = Lflag;
+ makefile.linkingStrategy = Zflag;
+ makefile.hierarchical = Hflag;
makefile.sub_project_dirs = sub_project_dirs;
makefile.ttcn3_prep_includes = ttcn3_prep_includes;
makefile.ttcn3_prep_defines = ttcn3_prep_defines;
+ makefile.ttcn3_prep_undefines = ttcn3_prep_undefines;
makefile.prep_includes = prep_includes;
makefile.prep_defines = prep_defines;
+ makefile.prep_undefines = prep_undefines;
makefile.codesplittpd = codesplittpd;
makefile.quietly = quietly;
makefile.disablesubtypecheck = disablesubtypecheck;
}
if (tcov_file_name != NULL) {
- makefile.tcov_file_name = mputprintf(makefile.tcov_file_name, "-K %s", tcov_file_name);
+ makefile.tcov_file_name = mputprintf(makefile.tcov_file_name, "-K %s", tcov_file_name);
}
if (makefile.nTTCN3Modules >= 1) {
if (dump_makefile_data) dump_makefile_struct(&makefile, 0);
if (error_count == 0) print_makefile(&makefile);
-
free_makefile_struct(&makefile);
}
static void usage(void)
{
fprintf(stderr, "\n"
- "usage: %s [-abc" C_flag "dDfFglLmprRstTVwWX] [-K file] [-P dir]"
+ "usage: %s [-abc" C_flag "dDfFglLmprRstTVwWXZ] [-K 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"
" -P dir: prints out a file list found in a given TPD relative to the given directory\n"
" -X: generate XML file that describes the TPD hierarchy, use with -r\n"
" -W: prefix working directories with project name\n"
+ " -Z: recursive Makefile generation from TPD using object files and dynamic libraries too\n"
+ " -H: hierachical Makefile generation from TPD use with -Z\n"
, program_name, program_name);
}
dxflag = FALSE, fxflag = FALSE, doflag = FALSE,
gfflag = FALSE, lnflag = FALSE, isflag = FALSE, asflag = FALSE,
swflag = FALSE, Vflag = FALSE, Dflag = FALSE, Wflag = FALSE,
- djflag = FALSE;
+ djflag = FALSE, Zflag = FALSE, Hflag = FALSE;
boolean error_flag = FALSE;
char *output_file = NULL;
char *ets_name = NULL;
+ char *project_name = NULL;
size_t n_other_files = 0;
const char **other_files = NULL;
const char *code_splitting_mode = NULL;
struct string2_list* create_symlink_list = NULL;
struct string_list* ttcn3_prep_includes = NULL;
struct string_list* ttcn3_prep_defines = NULL;
+ struct string_list* ttcn3_prep_undefines = NULL;
struct string_list* prep_includes = NULL;
struct string_list* prep_defines = NULL;
+ struct string_list* prep_undefines = NULL;
char *cxxcompiler = NULL;
char *optlevel = NULL;
char *optflags = NULL;
char* generatorCommandOutput = NULL;
struct string2_list* target_placement_list = NULL;
struct string2_list* run_command_list = NULL;
+ struct string2_list* required_configs = NULL;
#ifdef LICENSE
license_struct lstr;
}
for ( ; ; ) {
- int c = getopt(argc, argv, "O:ab:c" C_flag "dDe:fFgK:o:lLmpP:rRst:TU:vVwWXY");
+ int c = getopt(argc, argv, "O:ab:c" C_flag "dDe:fFgK:o:lLmpP:rRst:TU:vVwWXYZH");
if (c == -1) break;
switch (c) {
case 'O':
case 'g':
SET_FLAG(g);
break;
+ case 'H':
+ SET_FLAG(H);
+ break;
case 'o':
SET_FLAG(o);
output_file = optarg;
SET_FLAG(P);
/* Optional arguments with `::' are GNU specific... */
if (get_path_status(optarg) == PS_DIRECTORY) {
- file_list_path = optarg;
+ file_list_path = optarg;
} else {
- ERROR("The -P flag requires a valid directory as its argument "
- "instead of `%s'", optarg);
- error_flag = TRUE;
+ ERROR("The -P flag requires a valid directory as its argument "
+ "instead of `%s'", optarg);
+ error_flag = TRUE;
}
break;
case 'r':
case 'X':
SET_FLAG(X);
break;
+ case 'Z':
+ SET_FLAG(Z);
+ break;
default:
error_flag = TRUE;
break;
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
- || n_other_files > 0)
- error_flag = TRUE;
+ || Zflag || Hflag || n_other_files > 0)
+ error_flag = TRUE;
+ }
+
+ if (Zflag) {
+ if (!gflag) gflag = TRUE; // GNU make
+ if (!cflag) cflag = TRUE; // central sorage
}
- if ((bflag || Dflag || Pflag || Vflag || rflag || Wflag) && !tflag) {
- ERROR("Using the '-b', '-D', '-P', '-V', '-r' or '-W' option requires the use of the -t' option.");
+ if ((bflag || Dflag || Pflag || Vflag || rflag || Wflag || Zflag) && !tflag) {
+ ERROR("Using the '-b', '-D', '-P', '-V', '-r' 'Z' or '-W' option requires the use of the -t' option.");
error_flag = TRUE;
}
error_flag = TRUE;
}
+ if (!Zflag && Hflag) {
+ ERROR("Using the '-H' option requires use of the '-Z' option.");
+ error_flag = TRUE;
+ }
+
+ if (Zflag && !Fflag && !fflag) {
+ ERROR("Using the '-Z' option requires use of the '-F' option.");
+ error_flag = TRUE;
+ }
+
if (lflag && !strncmp(get_platform_string(), "WIN32", 5)) {
ERROR("Generating Makefile with dynamic linking enabled is not supported "
"on Windows platform");
ttcn3_prep_defines = (struct string_list*)Malloc(sizeof(struct string_list));
ttcn3_prep_defines->str = NULL;
ttcn3_prep_defines->next = NULL;
+ ttcn3_prep_undefines = (struct string_list*)Malloc(sizeof(struct string_list));
+ ttcn3_prep_undefines->str = NULL;
+ ttcn3_prep_undefines->next = NULL;
prep_includes = (struct string_list*)Malloc(sizeof(struct string_list));
prep_includes->str = NULL;
prep_includes->next = NULL;
prep_defines = (struct string_list*)Malloc(sizeof(struct string_list));
prep_defines->str = NULL;
prep_defines->next = NULL;
+ prep_undefines = (struct string_list*)Malloc(sizeof(struct string_list));
+ prep_undefines->str = NULL;
+ prep_undefines->next = NULL;
solspeclibraries = (struct string_list*)Malloc(sizeof(struct string_list));
solspeclibraries->str = NULL;
solspeclibraries->next = NULL;
run_command_list->str1 = NULL;
run_command_list->str2 = NULL;
run_command_list->next = NULL;
+ required_configs = (struct string2_list*)Malloc(sizeof(struct string2_list));
+ required_configs->str1 = NULL;
+ required_configs->str2 = NULL;
+ required_configs->next = NULL;
+
tpd_processed = process_tpd(tpd_file_name, tpd_build_config, file_list_path,
- &argc, &argv, &optind, &ets_name,
+ &argc, &argv, &optind, &ets_name, &project_name,
&gflag, &sflag, &cflag, &aflag, &pflag,
&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, prep_includes, prep_defines, &csflag, &quflag, &dsflag, &cxxcompiler,
- &optlevel, &optflags, &dbflag, &drflag, &dtflag, &dxflag, &djflag, &fxflag, &doflag, &gfflag, &lnflag, &isflag,
+ 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, solspeclibraries, sol8speclibraries, linuxspeclibraries, freebsdspeclibraries, win32speclibraries, &ttcn3prep,
- linkerlibraries, additionalObjects, linkerlibsearchpath, Vflag, Dflag, &generatorCommandOutput, target_placement_list, Wflag, run_command_list);
+ linkerlibraries, additionalObjects, linkerlibsearchpath, Vflag, Dflag, &Zflag, &Hflag,
+ &generatorCommandOutput, target_placement_list, Wflag, run_command_list, required_configs);
+
Free(abs_work_dir);
if (prj_graph_fp) {
fprintf(prj_graph_fp, "</project_hierarchy_graph>\n");
fclose(prj_graph_fp);
}
- if (tpd_processed == TPD_FAILED) ERROR("Failed to process %s", tpd_file_name);
+ if (tpd_processed == TPD_FAILED) {
+ ERROR("Failed to process %s", tpd_file_name);
+ exit(EXIT_FAILURE);
+ }
}
if (!Pflag) {
run_makefilegen_commands(run_command_list);
generate_symlinks(create_symlink_list);
+ if (Zflag) {
+ if (Fflag)
+ NOTIFY("Makefile generation from top-level TPD: %s", tpd_file_name);
+ if (!Fflag && fflag)
+ NOTIFY("Makefile generation from lower level TPD: %s", tpd_file_name);
+ }
generate_makefile(argc - optind, argv + optind, n_other_files, other_files,
- output_file, ets_name, gflag, sflag, cflag, aflag, pflag, dflag, fflag||Fflag,
- Rflag, lflag, mflag, Cflag, code_splitting_mode, tcov_file_name, Lflag, rflag ? sub_project_dirs : NULL, ttcn3_prep_includes,
- ttcn3_prep_defines, prep_includes, prep_defines, csflag, quflag, dsflag, cxxcompiler, optlevel, optflags, dbflag,
+ output_file, ets_name, project_name, gflag, sflag, cflag, aflag, pflag, dflag, fflag||Fflag,
+ Rflag, lflag, mflag, Cflag, code_splitting_mode, tcov_file_name, 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, solspeclibraries,
sol8speclibraries, linuxspeclibraries, freebsdspeclibraries, win32speclibraries, ttcn3prep, linkerlibraries, additionalObjects,
linkerlibsearchpath, generatorCommandOutput, target_placement_list);
free_string_list(sub_project_dirs);
free_string_list(ttcn3_prep_includes);
free_string_list(ttcn3_prep_defines);
+ free_string_list(ttcn3_prep_undefines);
free_string_list(prep_includes);
free_string_list(prep_defines);
+ free_string_list(prep_undefines);
free_string_list(solspeclibraries);
free_string_list(sol8speclibraries);
free_string_list(linuxspeclibraries);
Free(generatorCommandOutput);
free_string2_list(target_placement_list);
+ free_string2_list(required_configs);
Free(other_files);
if (tpd_processed == TPD_SUCCESS) {
for (E = 0; E < argc; ++E) Free(argv[E]);
Free(argv);
}
- /* check_mem_leak(program_name); not needed when linked to new.cc */
+ /* check_mem_leak(program_name); not needed when linked to new.cc */
return error_count > 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
-
/* start_at is the index of the first "real" member of the record */
size_t start_at = uo + (sdef->xerUseOrderPossible != 0);
- /* Max. number of EMBED-VALUES strings. The actual number may change
- * at runtime: omitted optional (non-attribute) members decrease the
- * number of embed strings needed, and xsi:nil=true sets it to zero.*/
- size_t max_embed;
-
/* Number of optional non-attributes */
size_t n_opt_elements = 0;
++n_opt_elements;
}
}
- max_embed = sdef->nElements - start_at - num_attributes + 1;
/* Write some helper functions */
def = mputstr(def,
/* * * * * * * * * * XER_encode * * * * * * * * * * * * * * */
src = mputprintf(src,
"int %s::XER_encode(const XERdescriptor_t& p_td, "
- "TTCN_Buffer& p_buf, unsigned int p_flavor, int p_indent) const\n"
+ "TTCN_Buffer& p_buf, unsigned int p_flavor, int p_indent, embed_values_enc_struct_t*) const\n"
"{\n"
" if (!is_bound()) TTCN_EncDec_ErrorContext::error"
"(TTCN_EncDec::ET_UNBOUND, \"Encoding an unbound value.\");\n"
" if (e_xer && (p_td.xer_bits & USE_QNAME)) {\n"
" if (field_%s.is_value()) {\n"
" p_buf.put_s(11, (cbyte*)\" xmlns:b0='\");\n"
- " field_%s.XER_encode(%s_xer_, p_buf, p_flavor | XER_LIST, p_indent+1);\n"
+ " field_%s.XER_encode(%s_xer_, p_buf, p_flavor | XER_LIST, p_indent+1, 0);\n"
" p_buf.put_c('\\'');\n"
" }\n"
" if (p_td.xer_bits & XER_ATTRIBUTE) begin_attribute(p_td, p_buf);\n"
" p_buf.put_s(3, (cbyte*)\"b0:\");\n"
" sub_len += 3;\n"
" }\n"
- " sub_len += field_%s.XER_encode(%s_xer_, p_buf, p_flavor | XER_LIST, p_indent+1);\n"
+ " sub_len += field_%s.XER_encode(%s_xer_, p_buf, p_flavor | XER_LIST, p_indent+1, 0);\n"
" if (p_td.xer_bits & XER_ATTRIBUTE) p_buf.put_c('\\'');\n"
" } else" /* no newline */
, sdef->elements[0].name
/* First, the EMBED-VALUES member as an ordinary member if not doing EXER */
if (sdef->xerEmbedValuesPossible) {
src = mputprintf(src,
- " int exp_emb = %u;\n"
" if (!e_xer && (p_td.xer_bits & EMBED_VALUES)) {\n"
" ec_1.set_msg(\"%s': \");\n"
- " sub_len += field_%s.XER_encode(%s_xer_, p_buf, p_flavor, p_indent+1);\n"
+ " sub_len += field_%s.XER_encode(%s_xer_, p_buf, p_flavor, p_indent+1, 0);\n"
" }\n"
- , (unsigned int)max_embed
, sdef->elements[0].dispname
, sdef->elements[0].name, sdef->elements[0].typegen
);
if (sdef->xerUseOrderPossible) {
src = mputprintf(src,
" if (!e_xer && (p_td.xer_bits & USE_ORDER)) {\n"
- " sub_len += field_%s.XER_encode(%s_xer_, p_buf, p_flavor, p_indent+1);\n"
+ " sub_len += field_%s.XER_encode(%s_xer_, p_buf, p_flavor, p_indent+1, 0);\n"
" }\n"
, sdef->elements[uo].name, sdef->elements[uo].typegen
);
if (i==0 && sdef->xerEmbedValuesPossible && (sdef->elements[i].xerAnyKind & ANY_ATTRIB_BIT)) continue ;
src = mputprintf(src,
" ec_1.set_msg(\"%s': \");\n"
- " tmp_len = field_%s.XER_encode(%s_xer_, p_buf, p_flavor, p_indent+1);\n"
+ " tmp_len = field_%s.XER_encode(%s_xer_, p_buf, p_flavor, p_indent+1, 0);\n"
" %ssub_len += tmp_len;\n" /* do not add if attribute and EXER */
, sdef->elements[i].dispname
, sdef->elements[i].name, sdef->elements[i].typegen
}
if (sdef->xerEmbedValuesPossible) {
- size_t op;
src = mputprintf(src,
" ec_1.set_msg(\"%s': \");\n"
" if (e_xer && (p_td.xer_bits & EMBED_VALUES)) {\n"
- , sdef->elements[0].dispname
- );
-
- if (sdef->xerUseNilPossible) {
- src = mputstr(src, /* 25.2.6 a */
- " if ((p_td.xer_bits & USE_NIL) && nil_attribute) exp_emb = 0;\n"
- " else {\n");
- }
-
- for (op = 0; op < sdef->nElements; ++op) {
- if (sdef->elements[op].isOptional && !sdef->elements[op].xerAttribute) {
- src = mputprintf(src,
- " if (!field_%s.ispresent()) --exp_emb;\n"
- , sdef->elements[op].name
- );
- }
- }
-
- if (sdef->xerUseNilPossible) src = mputstr(src, " }\n");
-
- src = mputprintf(src,
- " if (field_%s.size_of()!=exp_emb) "
- "TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT, "
- "\"Wrong number %%d of EMBED-VALUEs, expected %%d\", field_%s.size_of(), exp_emb);\n"
- , sdef->elements[0].name
- , sdef->elements[0].name);
/* write the first string (must come AFTER the attributes) */
- src = mputprintf(src,
- " %ssub_len += field_%s[0].XER_encode(UNIVERSAL_CHARSTRING_xer_, p_buf, p_flavor | EMBED_VALUES, p_indent+1);\n"
+ " if (field_%s.size_of() > 0) {\n"
+ " sub_len += field_%s[0].XER_encode(UNIVERSAL_CHARSTRING_xer_, p_buf, p_flavor | EMBED_VALUES, p_indent+1, 0);\n"
+ " }\n"
" }\n"
- , (sdef->xerUseNilPossible ? "if (exp_emb > 0) " : "")
- , sdef->elements[0].name);
+ , sdef->elements[0].dispname, sdef->elements[0].name, sdef->elements[0].name);
if (want_namespaces) { /* here's another chance */
src = mputprintf(src,
" else if ( !(p_td.xer_bits & EMBED_VALUES)) {\n"
- " %sfield_%s.XER_encode(%s_xer_, p_buf, p_flavor, p_indent+1);\n"
+ " %sfield_%s.XER_encode(%s_xer_, p_buf, p_flavor, p_indent+1, 0);\n"
" }\n"
, ((sdef->elements[0].xerAnyKind & ANY_ATTRIB_BIT) ? "" : "sub_len += " )
, sdef->elements[0].name, sdef->elements[0].typegen
/* Then, all the non-attributes. Structuring the code like this depends on
* all attributes appearing before all non-attributes (excluding
* special members for EMBED-VALUES, USE-ORDER, etc.) */
+ if (sdef->xerEmbedValuesPossible) {
+ src = mputprintf(src,
+ " embed_values_enc_struct_t* emb_val = 0;\n"
+ " if (e_xer && (p_td.xer_bits & EMBED_VALUES) && field_%s.size_of() > 1) {\n"
+ " emb_val = new embed_values_enc_struct_t;\n"
+ " emb_val->embval_array = &field_%s;\n"
+ " emb_val->embval_index = 1;\n"
+ " emb_val->embval_size = field_%s.size_of();\n"
+ " }\n", sdef->elements[0].name, sdef->elements[0].name, sdef->elements[0].name);
+ }
+
if (sdef->xerUseOrderPossible) {
int max_ordered = sdef->nElements - start_at - num_attributes;
int min_ordered = max_ordered - n_opt_elements;
src = mputprintf(src,
" if (!nil_attribute) {\n"
"%s"
- " if (!e_xer) sub_len += field_%s.XER_encode(%s_xer_, p_buf, p_flavor, p_indent+!omit_tag);\n"
+ " if (!e_xer) sub_len += field_%s.XER_encode(%s_xer_, p_buf, p_flavor, p_indent+!omit_tag, 0);\n"
" else" /* no newline */
, (sdef->xerUseNilPossible ? " if (!(p_td.xer_bits & USE_ORDER)) p_flavor |= (p_td.xer_bits & USE_NIL);\n" : "")
/* If USE-ORDER is on, the tag-removing effect of USE-NIL has been
src = mputprintf(src,
" case %lu:\n"
" ec_1.set_msg(\"%s': \");\n"
- " sub_len += field_%s%s%s%s.XER_encode(%s_xer_, p_buf, p_flavor, p_indent+!omit_tag);\n"
+ " sub_len += field_%s%s%s%s.XER_encode(%s_xer_, p_buf, p_flavor, p_indent+!omit_tag, %s);\n"
, (unsigned long)offset++
, sdef->elements[i].dispname
, (sdef->xerUseNilPossible ? sdef->elements[i].name : "")
, (sdef->xerUseNilPossible ? "()" : "")
, sdef->elements[i].typegen
-
+ , sdef->xerEmbedValuesPossible ? "emb_val" : "0"
);
src = mputstr(src, " break;\n");
if (sdef->xerEmbedValuesPossible) {
src = mputprintf(src,
- " if (e_xer && i+1 < exp_emb && (p_td.xer_bits & EMBED_VALUES)) { // embed-val\n"
- " field_%s[i+1].XER_encode(UNIVERSAL_CHARSTRING_xer_, p_buf, p_flavor | EMBED_VALUES, p_indent+1);\n"
+ " if (e_xer && (p_td.xer_bits & EMBED_VALUES) && 0 != emb_val &&\n"
+ " emb_val->embval_index < emb_val->embval_size) { // embed-val\n"
+ " field_%s[emb_val->embval_index].XER_encode(\n"
+ " UNIVERSAL_CHARSTRING_xer_, p_buf, p_flavor | EMBED_VALUES, p_indent+1, 0);\n"
+ " ++emb_val->embval_index;\n"
" }\n"
, sdef->elements[0].name);
}
, sdef->elements[i].dispname
);
src = mputprintf(src,
- " sub_len += field_%s.XER_encode(%s_xer_, p_buf, p_flavor%s, p_indent+!omit_tag);\n"
+ " sub_len += field_%s.XER_encode(%s_xer_, p_buf, p_flavor%s, p_indent+!omit_tag, %s);\n"
, sdef->elements[i].name, sdef->elements[i].typegen
, sdef->xerUseNilPossible ? "| (p_td.xer_bits & USE_NIL)" : ""
+ , sdef->xerEmbedValuesPossible ? "emb_val" : "0"
);
if (sdef->xerEmbedValuesPossible) {
- unsigned long idx = i - start_at - num_attributes + 1;
src = mputprintf(src,
- " if (e_xer && exp_emb > %lu && (p_td.xer_bits & EMBED_VALUES)) {\n"
- " field_%s[%lu].XER_encode(UNIVERSAL_CHARSTRING_xer_, p_buf, p_flavor | EMBED_VALUES, p_indent+1);\n"
+ " if (e_xer && (p_td.xer_bits & EMBED_VALUES) && 0 != emb_val &&\n"
+ " emb_val->embval_index < emb_val->embval_size) {\n"
+ " field_%s[emb_val->embval_index].XER_encode(\n"
+ " UNIVERSAL_CHARSTRING_xer_, p_buf, p_flavor | EMBED_VALUES, p_indent+1, 0);\n"
+ " ++emb_val->embval_index;\n"
" }\n"
- , idx
- , sdef->elements[0].name, idx);
+ , sdef->elements[0].name);
}
} /* next field when not USE-ORDER */
+ if (sdef->xerEmbedValuesPossible) {
+ src = mputprintf(src,
+ " if (0 != emb_val) {\n"
+ " if (emb_val->embval_index < emb_val->embval_size) {\n"
+ " ec_1.set_msg(\"%s': \");\n"
+ " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT,\n"
+ " \"Too many EMBED-VALUEs specified: %%d (expected %%d or less)\",\n"
+ " emb_val->embval_size, emb_val->embval_index);\n"
+ " }\n"
+ " delete emb_val;\n"
+ " }\n"
+ , sdef->elements[0].name);
+ }
+
src = mputstr(src, " } // QN?\n");
{
src = mputprintf(src, /* XERSTUFF decodegen for record/SEQUENCE*/
"int %s::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& p_reader,"
- " unsigned int p_flavor)\n"
+ " unsigned int p_flavor, embed_values_dec_struct_t*)\n"
"{\n"
" bound_flag = TRUE;\n"
/* Remove XER_LIST, XER_RECOF from p_flavor. This is not required
}
else { /* must be the ANY-ATTRIBUTES */
src = mputprintf(src,
- " field_%s.set_size(0);\n",
- sdef->elements[aaa].name);
+ " field_%s%s;\n"
+ , sdef->elements[aaa].name
+ , sdef->elements[aaa].isOptional ? " = OMIT_VALUE" : ".set_size(0)");
}
}
src = mputprintf(src,
" if (check_name(attr_name, %s_xer_, 1) && check_namespace(ns_uri, %s_xer_)) {\n"
" ec_1.set_msg(\"%s': \");\n"
- " field_%s.XER_decode(%s_xer_, p_reader, p_flavor | (p_td.xer_bits & USE_NIL));\n"
+ " field_%s.XER_decode(%s_xer_, p_reader, p_flavor | (p_td.xer_bits & USE_NIL), 0);\n"
" } else"
, sdef->elements[i].typegen, sdef->elements[i].typegen
, sdef->elements[i].dispname /* set_msg */
/* we are at a dangling else */
src = mputprintf(src,
" {\n"
- " TTCN_EncDec_ErrorContext ec_0(\"Attribute %%d: \", (int)num_aa);"
- " UNIVERSAL_CHARSTRING& new_elem = field_%s[num_aa++];\n"
+ " TTCN_EncDec_ErrorContext ec_0(\"Attribute %%d: \", (int)num_aa);\n"
+ " UNIVERSAL_CHARSTRING& new_elem = field_%s%s[num_aa++];\n"
/* Construct the AnyAttributeFormat (X.693amd1, 18.2.6) */
" TTCN_Buffer aabuf;\n"
" const xmlChar *x_name = p_reader.LocalName();\n"
" new_elem.decode_utf8(aabuf.get_len(), aabuf.get_data());\n"
" } \n"
, sdef->elements[aa_index].name
+ , sdef->elements[aa_index].isOptional ? "()" : ""
, sdef->elements[aa_index].typegen, sdef->elements[aa_index].typegen
);
}
" if (!(p_td.xer_bits & EMBED_VALUES)) {\n"
" ec_1.set_msg(\"%s': \");\n"
" field_%s.XER_decode(%s_xer_, p_reader, "
- "p_flavor | (p_td.xer_bits & USE_NIL)| (tag_closed ? PARENT_CLOSED : 0));\n"
+ "p_flavor | (p_td.xer_bits & USE_NIL)| (tag_closed ? PARENT_CLOSED : 0), 0);\n"
" }\n"
, sdef->elements[0].dispname
, sdef->elements[0].name, sdef->elements[0].typegen
src = mputprintf(src,
" {\n"
" ec_1.set_msg(\"%s': \");\n"
- " field_%s.XER_decode(%s_xer_, p_reader, p_flavor | (p_td.xer_bits & USE_NIL));\n"
+ " field_%s.XER_decode(%s_xer_, p_reader, p_flavor | (p_td.xer_bits & USE_NIL), 0);\n"
" }\n"
, sdef->elements[i].dispname
, sdef->elements[i].name, sdef->elements[i].typegen
if (num_attributes || sdef->xerEmbedValuesPossible || sdef->xerUseOrderPossible) {
src = mputstr(src, "}\n");
}
+
+ if (sdef->xerEmbedValuesPossible) {
+ src = mputprintf(src,
+ " embed_values_dec_struct_t* emb_val = 0;\n"
+ " if (e_xer && (p_td.xer_bits & EMBED_VALUES)) {\n"
+ " emb_val = new embed_values_dec_struct_t;\n"
+ " emb_val->embval_array = &field_%s;\n"
+ " emb_val->embval_index = 0;\n"
+ " field_%s.set_size(0);\n"
+ " }\n", sdef->elements[0].name, sdef->elements[0].name);
+ }
if (sdef->xerUseOrderPossible) {
size_t begin = start_at + num_attributes; /* first non-attribute */
}
}
- if (sdef->xerEmbedValuesPossible) { /* EMBED-VALUES with USE-ORDER */
- src = mputprintf(src,
- " if (p_td.xer_bits & EMBED_VALUES) {\n"
- " field_%s.set_size(%lu);\n"
- " %s::of_type empty_string(\"\");\n"
- " for (int j_j=0; j_j<%lu; ++j_j) {\n"
- " field_%s[j_j] = empty_string;\n"
- " }\n"
- " }\n"
- , sdef->elements[0].name
- , (unsigned long)(n_embed + 1)
- , sdef->elements[0].type
- , (unsigned long)(n_embed + 1)
- , sdef->elements[0].name
- );
- }
-
if (sdef->xerUseNilPossible) { /* USE-NIL and USE-ORDER */
src = mputprintf(src,
" if (nil_attribute) field_%s.set_size(0);\n else"
" {\n"
" field_%s.set_size(0);\n"
" int e_val, num_seen = 0, *seen_f = new int[%lu];\n"
- " for (int i=0; i < %lu; ++i) {\n"
- " for (rd_ok=p_reader.Ok(); rd_ok==1; rd_ok=p_reader.Read()) {\n"
, sdef->elements[uo].name
, (unsigned long)(n_embed)
+ );
+ if (sdef->xerEmbedValuesPossible) {
+ // The index of the latest embedded value can change outside of this function
+ // (if the field is a untagged record of), in this case the next value should
+ // be ignored, as it's already been handled by the record of
+ src = mputstr(src, " int last_embval_index = 0;\n");
+ }
+ src = mputprintf(src,
+ " for (int i=0; i < %lu; ++i) {\n"
+ " for (rd_ok=p_reader.Ok(); rd_ok==1; rd_ok=p_reader.Read()) {\n"
, (unsigned long)(n_embed));
if (sdef->xerEmbedValuesPossible) {
/* read and store embedValues text if present */
src = mputprintf(src,
- " if ((p_td.xer_bits & EMBED_VALUES) && (p_reader.NodeType()==XML_READER_TYPE_TEXT)) {\n"
+ " if (0 != emb_val && p_reader.NodeType()==XML_READER_TYPE_TEXT) {\n"
" UNIVERSAL_CHARSTRING emb_ustr((const char*)p_reader.Value());\n"
- " field_%s[i] = emb_ustr;\n"
+ " field_%s[emb_val->embval_index] = emb_ustr;\n"
" }\n"
, sdef->elements[0].name);
}
" }\n"
" if (rd_ok != 1) break;\n"
" const char * x_name = (const char*)p_reader.LocalName();\n" /* Name or LocalName ? */);
-
+
+ if (sdef->xerEmbedValuesPossible) {
+ src = mputstr(src,
+ " if (0 != emb_val) {\n"
+ " if (last_embval_index == emb_val->embval_index) {\n"
+ " ++emb_val->embval_index;\n"
+ " }\n"
+ " last_embval_index = emb_val->embval_index;\n"
+ " }\n");
+ }
/* * * * * code for USE-ORDER * * * * */
src = mputprintf(src,
" if (check_name(x_name, %s_xer_, 1)) {\n"
" ec_1.set_msg(\"%s': \");\n"
- " field_%s%s%s%s.XER_decode(%s_xer_, p_reader, p_flavor);\n"
+ " field_%s%s%s%s.XER_decode(%s_xer_, p_reader, p_flavor, %s);\n"
, sdef->elements[i].typegen
, sdef->elements[i].dispname
-
, (sdef->xerUseNilPossible ? sdef->elements[sdef->nElements-1].name: sdef->elements[i].name)
, (sdef->xerUseNilPossible ? "()." : "")
, (sdef->xerUseNilPossible ? sdef->elements[i].name : "")
, (sdef->xerUseNilPossible ? "()" : "")
, sdef->elements[i].typegen
+ , sdef->xerEmbedValuesPossible ? "emb_val" : "0"
);
src = mputprintf(src,
- " field_%s[i] = e_val = %s::of_type::%s;\n"
- , sdef->elements[uo].name
- , sdef->elements[uo].typegen, sdef->elements[i].name);
+ " field_%s[i] = e_val = %s::of_type::%s;\n"
+ , sdef->elements[uo].name
+ , sdef->elements[uo].typegen, sdef->elements[i].name);
src = mputstr(src, " }\n else");
}
}
" }\n"
" if (!next_any) {\n"
" ec_1.set_msg(\"%s': \");\n"
- " field_%s%s%s%s.XER_decode(%s_xer_, p_reader, p_flavor);\n"
+ " field_%s%s%s%s.XER_decode(%s_xer_, p_reader, p_flavor, 0);\n"
" field_%s[i] = e_val;\n"
" any_found = true;\n"
" }\n"
if (sdef->xerEmbedValuesPossible) {
/* read and store embedValues text if present */
src = mputprintf(src,
- " if ((p_td.xer_bits & EMBED_VALUES) && (p_reader.NodeType()==XML_READER_TYPE_TEXT)) {\n"
- " UNIVERSAL_CHARSTRING emb_ustr((const char*)p_reader.Value());\n"
- " field_%s[%lu] = emb_ustr;\n"
+ " if (0 != emb_val) {\n"
+ " if (p_reader.NodeType()==XML_READER_TYPE_TEXT) {\n"
+ " UNIVERSAL_CHARSTRING emb_ustr((const char*)p_reader.Value());\n"
+ " field_%s[emb_val->embval_index] = emb_ustr;\n"
+ " }\n"
+ " if (last_embval_index == emb_val->embval_index) {\n"
+ " ++emb_val->embval_index;\n"
+ " }\n"
" }\n"
- , sdef->elements[0].name, (unsigned long)(n_embed));
+ , sdef->elements[0].name);
}
src = mputprintf(src,
" p_reader.MoveToElement();\n"
" } else {\n");
}
+ if (sdef->xerEmbedValuesPossible) {
+ // The index of the latest embedded value can change outside of this function
+ // (if the field is a untagged record of), in this case the next value should
+ // be ignored, as it's already been handled by the record of
+ // Omitted fields can also reset this value
+ src = mputstr(src, " int last_embval_index = 0;\n");
+ }
/* for all the non-attribute fields... */
for (i = start_at + num_attributes; i < sdef->nElements; ++i) {
if (sdef->xerEmbedValuesPossible) {
/* read and store embedValues text if present */
src = mputprintf(src,
- " if ((p_td.xer_bits & EMBED_VALUES) && (p_reader.NodeType()==XML_READER_TYPE_TEXT)) {\n"
- " UNIVERSAL_CHARSTRING emb_ustr((const char*)p_reader.Value());\n"
- " field_%s[%lu] = emb_ustr;\n"
+ " if (0 != emb_val) {\n"
+ " if (p_reader.NodeType()==XML_READER_TYPE_TEXT) {\n"
+ " UNIVERSAL_CHARSTRING emb_ustr((const char*)p_reader.Value());\n"
+ " field_%s[emb_val->embval_index] = emb_ustr;\n"
+ " }\n"
+ " if (last_embval_index == emb_val->embval_index) {\n"
+ " ++emb_val->embval_index;\n"
+ " }\n"
+ " last_embval_index = emb_val->embval_index;\n"
" }\n"
- , sdef->elements[0].name, (unsigned long)(i-(start_at+num_attributes)));
+ , sdef->elements[0].name);
}
/* The DEFAULT-FOR-EMPTY member can not be involved with EMBED-VALUES,
* so we can use the same pattern: optional "if(...) else" before {}
src = mputprintf(src,
" field_%s.XER_decode(%s_xer_, p_reader, p_flavor"
- " | (p_td.xer_bits & USE_NIL)| (tag_closed ? PARENT_CLOSED : 0));\n"
+ " | (p_td.xer_bits & USE_NIL)| (tag_closed ? PARENT_CLOSED : 0), %s);\n"
" }\n"
- , sdef->elements[i].name, sdef->elements[i].typegen);
+ , sdef->elements[i].name, sdef->elements[i].typegen
+ , sdef->xerEmbedValuesPossible ? "emb_val" : "0");
+ if (sdef->xerEmbedValuesPossible) {
+ src = mputprintf(src,
+ " if (!field_%s.is_present()) {\n"
+ // there was no new element, the last embedded value is for the next field
+ // (or the end of the record if this is the last field)
+ " last_embval_index = -1;\n"
+ " }\n"
+ , sdef->elements[i].name);
+ }
} /* next field */
- if (sdef->xerUseNilPossible) {
- src = mputstr(src, " } // use_nil\n");
- }
-
if (sdef->xerEmbedValuesPossible) {
/* read and store embedValues text if present */
src = mputprintf(src,
- " if ((p_td.xer_bits & EMBED_VALUES) && (p_reader.NodeType()==XML_READER_TYPE_TEXT)) {\n"
- " UNIVERSAL_CHARSTRING emb_ustr((const char*)p_reader.Value());\n"
- " field_%s[%lu] = emb_ustr;\n"
+ " if (0 != emb_val) {\n"
+ " if (p_reader.NodeType()==XML_READER_TYPE_TEXT) {\n"
+ " UNIVERSAL_CHARSTRING emb_ustr((const char*)p_reader.Value());\n"
+ " field_%s[emb_val->embval_index] = emb_ustr;\n"
+ " }\n"
+ " if (last_embval_index == emb_val->embval_index) {\n"
+ " ++emb_val->embval_index;\n"
+ " }\n"
" }\n"
- , sdef->elements[0].name, (unsigned long)(i-(start_at+num_attributes)));
+ , sdef->elements[0].name);
+ }
+
+ if (sdef->xerUseNilPossible) {
+ src = mputstr(src, " } // use_nil\n");
}
+ if (sdef->xerUseOrderPossible) {
+ src = mputstr(src, " } // uo\n");
+ }
+
if (sdef->xerEmbedValuesPossible) {
- size_t op;
src = mputprintf(src,
- /* Set the embed-values member to the correct nr of strings */
- " if (e_xer && (p_td.xer_bits & EMBED_VALUES)) {\n"
- " int exp_embed = %lu;\n"
- , (unsigned long)max_embed
- );
-
- if (sdef->xerUseNilPossible) {
- src = mputstr(src,
- " if (nil_attribute) exp_embed = 0;\n"
- " else {");
- }
-
- for (op = 0; op < sdef->nElements; ++op) {
- if (sdef->elements[op].isOptional && !sdef->elements[op].xerAttribute) {
- src = mputprintf(src,
- " if (!field_%s.ispresent()) --exp_embed;\n"
- , sdef->elements[op].name
- );
- }
- }
-
- if (sdef->xerUseNilPossible) src = mputstr(src, " }\n");
-
- src = mputprintf(src,
- " field_%s.set_size(exp_embed);//normal\n"
+ " if (0 != emb_val) {\n"
" %s::of_type empty_string(\"\");\n"
- " for (int j_j=0; j_j<exp_embed; ++j_j) {\n"
+ " for (int j_j = 0; j_j < emb_val->embval_index; ++j_j) {\n"
" if (!field_%s[j_j].is_bound()) field_%s[j_j] = empty_string;\n"
" }\n"
- " }"
- , sdef->elements[0].name
+ " delete emb_val;\n"
+ " }\n"
, sdef->elements[0].type
, sdef->elements[0].name
, sdef->elements[0].name
);
}
- if (sdef->xerUseOrderPossible) {
- src = mputstr(src, " } // uo\n");
- }
-
if (sdef->xerUseQName) {
src = mputstr(src, " } // qn\n");
}
);
src = mputprintf(src,
- "int %s::XER_encode(const XERdescriptor_t& p_td,"
- " TTCN_Buffer& p_buf, unsigned int p_flavor, int p_indent) const{\n"
+ "int %s::XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, "
+ "unsigned int p_flavor, int p_indent, embed_values_enc_struct_t*) const{\n"
" int encoded_length=(int)p_buf.get_len();\n"
" int is_indented = !is_canonical(p_flavor);\n"
" int e_xer = is_exer(p_flavor);\n"
"// written by %s in " __FILE__ " at %d\n"
#endif
"int %s::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& p_reader, "
- "unsigned int p_flavor)\n"
+ "unsigned int p_flavor, embed_values_dec_struct_t*)\n"
"{\n"
" int e_xer = is_exer(p_flavor);\n"
" bound_flag = true;\n"
"int n_elements;\n"
"%s **value_elements;\n"
"} *val_ptr;\n"
- "Vector<int> refd_indices;\n"
- "int max_refd_index;\n"
#ifndef NDEBUG
, __FUNCTION__, __LINE__
#endif
"}\n"
"}\n\n", name, name, dispname, name, dispname, name, name, name, name, name);
}
-
- /* function that returns the actual number of elements */
- def = mputstr(def, "int get_nof_elements() const;\n");
- src = mputprintf(src,
- "int %s::get_nof_elements() const\n"
- "{\n"
- " int nof_elements = (val_ptr != NULL) ? val_ptr->n_elements : 0;\n"
- " if (!refd_indices.empty()) {\n"
- " while (nof_elements > 0) {\n"
- " if (is_elem_bound(nof_elements - 1)) {\n"
- " break;\n"
- " }\n"
- " --nof_elements;\n"
- " }\n"
- " }\n"
- " return nof_elements;\n"
- "}\n\n", name);
-
- /* element boundness check function */
- def = mputstr(def, "bool is_elem_bound(int index) const;\n");
- src = mputprintf(src,
- "bool %s::is_elem_bound(int index) const\n"
- "{\n"
- " return val_ptr->value_elements[index] != NULL &&\n"
- " val_ptr->value_elements[index]->is_bound();\n"
- "}\n\n", name);
-
- /* function that calculates and caches the maximum referenced index */
- def = mputstr(def, "int get_max_refd_index();\n");
- src = mputprintf(src,
- "int %s::get_max_refd_index()\n"
- "{\n"
- " if (refd_indices.empty()) {\n"
- " return -1;\n"
- " }\n"
- " if (-1 == max_refd_index) {\n"
- " for (size_t i = 0; i < refd_indices.size(); ++i) {\n"
- " if (refd_indices[i] > max_refd_index) {\n"
- " max_refd_index = refd_indices[i];\n"
- " }\n"
- " }\n"
- " }\n"
- " return max_refd_index;\n"
- "}\n\n", name);
-
- /* referenced index check function */
- def = mputstr(def, "bool is_index_refd(int index);\n");
- src = mputprintf(src,
- "bool %s::is_index_refd(int index)\n"
- "{\n"
- " for (size_t i = 0; i < refd_indices.size(); ++i) {\n"
- " if (index == refd_indices[i]) {\n"
- " return true;\n"
- " }\n"
- " }\n"
- " return false;\n"
- "}\n\n", name);
/* public member functions */
def = mputstr(def, "\npublic:\n");
"%s::%s()\n"
"{\n"
"val_ptr = NULL;\n"
- "max_refd_index = -1;\n"
"}\n\n", name, name);
def = mputprintf(def, "%s(null_type other_value);\n", name);
"val_ptr->ref_count = 1;\n"
"val_ptr->n_elements = 0;\n"
"val_ptr->value_elements = NULL;\n"
- "max_refd_index = -1;\n"
"}\n\n", name, name);
/* copy constructor */
"{\n"
"if (!other_value.is_bound()) "
"TTCN_error(\"Copying an unbound value of type %s.\");\n"
- "if (other_value.refd_indices.empty()) {\n"
"val_ptr = other_value.val_ptr;\n"
"val_ptr->ref_count++;\n"
- "}\n"
- "else {\n"
- // there are references to at least one element => the array must be copied
- "val_ptr = NULL;\n"
- "int nof_elements = other_value.get_nof_elements();\n"
- "set_size(nof_elements);\n"
- "for (int i = 0; i < nof_elements; ++i) {\n"
- "if (other_value.is_elem_bound(i)) {\n"
- "val_ptr->value_elements[i] = new %s(*(other_value.val_ptr->value_elements[i]));\n"
- "}\n"
- "}\n"
- "}\n"
- "max_refd_index = -1;\n"
- "}\n\n", name, name, name, dispname, type);
+ "}\n\n", name, name, name, dispname);
/* destructor */
def = mputprintf(def, "~%s();\n\n", name);
"val_ptr = NULL;\n"
"}\n"
"else if (val_ptr->ref_count == 1) {\n"
- "if (refd_indices.empty()) {\n"
"for (int elem_count = 0; elem_count < val_ptr->n_elements;\n"
"elem_count++)\n"
"if (val_ptr->value_elements[elem_count] != NULL)\n"
"delete val_ptr;\n"
"val_ptr = NULL;\n"
"}\n"
- "else {\n"
- "set_size(0);\n"
- "}\n"
- "}\n"
"else\n"
"TTCN_error(\"Internal error: Invalid reference counter in a record "
"of/set of value.\");\n"
src = mputprintf(src,
"%s& %s::operator=(null_type)\n"
"{\n"
- "set_size(0);\n"
+ "clean_up();\n"
+ "val_ptr = new recordof_setof_struct;\n"
+ "val_ptr->ref_count = 1;\n"
+ "val_ptr->n_elements = 0;\n"
+ "val_ptr->value_elements = NULL;\n"
"return *this;\n"
"}\n\n", name, name);
src = mputprintf(src,
"%s& %s::operator=(const %s& other_value)\n"
"{\n"
- "if (!other_value.is_bound()) "
+ "if (other_value.val_ptr == NULL) "
"TTCN_error(\"Assigning an unbound value of type %s.\");\n"
"if (this != &other_value) {\n"
- "if (refd_indices.empty() && other_value.refd_indices.empty()) {\n"
"clean_up();\n"
"val_ptr = other_value.val_ptr;\n"
"val_ptr->ref_count++;\n"
"}\n"
- "else {\n"
- // there are references to at least one element => the array must be copied
- "int nof_elements = other_value.get_nof_elements();\n"
- "set_size(nof_elements);\n"
- "for (int i = 0; i < nof_elements; ++i) {\n"
- "if (other_value.is_elem_bound(i)) {\n"
- "if (val_ptr->value_elements[i] == NULL) {\n"
- "val_ptr->value_elements[i] = new %s;\n"
- "}\n"
- "*val_ptr->value_elements[i] = *other_value.val_ptr->value_elements[i];\n"
- "}\n"
- "else if (val_ptr->value_elements[i] != NULL) {\n"
- "if (is_index_refd(i)) {\n"
- "val_ptr->value_elements[i]->clean_up();\n"
- "}\n"
- "else {\n"
- "delete val_ptr->value_elements[i];\n"
- "val_ptr->value_elements[i] = NULL;\n"
- "}\n"
- "}\n"
- "}\n"
- "}\n"
- "}\n"
"return *this;\n"
- "}\n\n", name, name, name, dispname, type);
+ "}\n\n", name, name, name, dispname);
/* comparison operators */
def = mputstr(def, "boolean operator==(null_type other_value) const;\n");
"if (val_ptr == NULL)\n"
"TTCN_error(\"The left operand of comparison is an unbound value of "
"type %s.\");\n"
- "return get_nof_elements() == 0 ;\n"
+ "return val_ptr->n_elements == 0 ;\n"
"}\n\n", name, dispname);
def = mputprintf(def, "boolean operator==(const %s& other_value) const;\n",
dispname, dispname);
if (sdef->kind == SET_OF) {
src = mputstr(src,
- "return compare_set_of(this, get_nof_elements(), &other_value, "
- "other_value.get_nof_elements(), compare_function);\n");
+ "return compare_set_of(this, val_ptr->n_elements, &other_value, "
+ "(other_value.val_ptr)->n_elements, compare_function);\n");
} else {
src = mputstr
(src,
- "if (get_nof_elements() != other_value.get_nof_elements())\n"
+ "if (val_ptr->n_elements != (other_value.val_ptr)->n_elements)\n"
"return FALSE;\n"
- "for (int elem_count = 0; elem_count < get_nof_elements(); elem_count++){\n"
- "if (is_elem_bound(elem_count)){\n"
- "if (other_value.is_elem_bound(elem_count)){\n"
+ "for (int elem_count = 0; elem_count < val_ptr->n_elements; elem_count++){\n"
+ "if (val_ptr->value_elements[elem_count] != NULL){\n"
+ "if ((other_value.val_ptr)->value_elements[elem_count] != NULL){\n"
" if (*val_ptr->value_elements[elem_count] != "
"*(other_value.val_ptr)->value_elements[elem_count]) "
"return FALSE;\n"
"} else return FALSE;\n"
"} else {\n"
- "if (other_value.is_elem_bound(elem_count)) return FALSE;\n"
+ "if ((other_value.val_ptr)->value_elements[elem_count] != NULL) "
+ "return FALSE;\n"
"}\n"
"}\n"
"return TRUE;\n");
"TTCN_error(\"Accessing an element in an unbound value of type %s.\");\n"
"if (index_value < 0) TTCN_error(\"Accessing an element of type %s "
"using a negative index: %%d.\", index_value);\n"
- "if (index_value >= get_nof_elements()) TTCN_error(\"Index overflow in "
+ "if (index_value >= val_ptr->n_elements) TTCN_error(\"Index overflow in "
"a value of type %s: The index is %%d, but the value has only %%d "
- "elements.\", index_value, get_nof_elements());\n"
+ "elements.\", index_value, val_ptr->n_elements);\n"
"return (val_ptr->value_elements[index_value] != NULL) ?\n"
"*val_ptr->value_elements[index_value] : UNBOUND_ELEM;\n"
"}\n\n", type, name, dispname, dispname, dispname);
"if (val_ptr == NULL) "
"TTCN_error(\"Performing rotation operation on an unbound value of type "
"%s.\");\n"
- "int nof_elements = get_nof_elements();\n"
- "if (nof_elements == 0) return *this;\n"
+ "if (val_ptr->n_elements == 0) return *this;\n"
"int rc;\n"
- "if (rotate_count>=0) rc = rotate_count %% nof_elements;\n"
- "else rc = nof_elements - ((-rotate_count) %% nof_elements);\n"
+ "if (rotate_count>=0) rc = rotate_count %% val_ptr->n_elements;\n"
+ "else rc = val_ptr->n_elements - ((-rotate_count) %% val_ptr->n_elements);\n"
"if (rc == 0) return *this;\n"
"%s ret_val;\n"
- "ret_val.set_size(nof_elements);\n"
- "for (int i=0; i<nof_elements; i++) {\n"
- "if (is_elem_bound(i)) {\n"
- "ret_val.val_ptr->value_elements[(i+rc)%%nof_elements] ="
+ "ret_val.set_size(val_ptr->n_elements);\n"
+ "for (int i=0; i<val_ptr->n_elements; i++) {\n"
+ "if (val_ptr->value_elements[i] != NULL) {\n"
+ "ret_val.val_ptr->value_elements[(i+rc)%%val_ptr->n_elements] ="
"new %s(*val_ptr->value_elements[i]);\n"
"}\n"
"}\n"
"{\n"
"if (val_ptr == NULL || other_value.val_ptr == NULL) "
"TTCN_error(\"Unbound operand of %s concatenation.\");\n"
- "int nof_elements = get_nof_elements();\n"
- "if (nof_elements == 0) return other_value;\n"
- "int other_value_nof_elements = other_value.get_nof_elements();"
- "if (other_value_nof_elements == 0) return *this;\n"
+ "if (val_ptr->n_elements == 0) return other_value;\n"
+ "if (other_value.val_ptr->n_elements == 0) return *this;\n"
"%s ret_val;\n"
- "ret_val.set_size(nof_elements + other_value_nof_elements);\n"
- "for (int i=0; i<nof_elements; i++) {\n"
- "if (is_elem_bound(i)) {\n"
+ "ret_val.set_size(val_ptr->n_elements+other_value.val_ptr->n_elements);\n"
+ "for (int i=0; i<val_ptr->n_elements; i++) {\n"
+ "if (val_ptr->value_elements[i] != NULL) {\n"
"ret_val.val_ptr->value_elements[i] = new %s(*val_ptr->value_elements[i]);\n"
"}\n"
"}\n"
- "for (int i=0; i<other_value_nof_elements; i++) {\n"
- "if (other_value.is_elem_bound(i)) {\n"
- "ret_val.val_ptr->value_elements[i + nof_elements] = "
+ "for (int i=0; i<other_value.val_ptr->n_elements; i++) {\n"
+ "if (other_value.val_ptr->value_elements[i] != NULL) {\n"
+ "ret_val.val_ptr->value_elements[i+val_ptr->n_elements] = "
"new %s(*other_value.val_ptr->value_elements[i]);\n"
"}\n"
"}\n"
"if (val_ptr == NULL) "
"TTCN_error(\"The first argument of substr() is an unbound value of "
"type %s.\");\n"
- "check_substr_arguments(get_nof_elements(), index, returncount, "
+ "check_substr_arguments(val_ptr->n_elements, index, returncount, "
"\"%s\",\"element\");\n"
"%s ret_val;\n"
"ret_val.set_size(returncount);\n"
"for (int i=0; i<returncount; i++) {\n"
- "if (is_elem_bound(i+index)) {\n"
+ "if (val_ptr->value_elements[i+index] != NULL) {\n"
"ret_val.val_ptr->value_elements[i] = "
"new %s(*val_ptr->value_elements[i+index]);\n"
"}\n"
"if (repl.val_ptr == NULL) "
"TTCN_error(\"The fourth argument of replace() is an unbound value of "
"type %s.\");\n"
- "int nof_elements = get_nof_elements();\n"
- "check_replace_arguments(nof_elements, index, len, "
+ "check_replace_arguments(val_ptr->n_elements, index, len, "
"\"%s\",\"element\");\n"
"%s ret_val;\n"
- "int repl_nof_elements = repl.get_nof_elements();\n"
- "ret_val.set_size(nof_elements + repl_nof_elements - len);\n"
+ "ret_val.set_size(val_ptr->n_elements + repl.val_ptr->n_elements - len);\n"
"for (int i = 0; i < index; i++) {\n"
- "if (is_elem_bound(i)) {\n"
+ "if (val_ptr->value_elements[i] != NULL) {\n"
"ret_val.val_ptr->value_elements[i] = new %s(*val_ptr->value_elements[i]);\n"
"}\n"
"}\n"
- "for (int i = 0; i < repl_nof_elements; i++) {\n"
- "if (repl.is_elem_bound(i)) {\n"
+ "for (int i = 0; i < repl.val_ptr->n_elements; i++) {\n"
+ "if (repl.val_ptr->value_elements[i] != NULL) {\n"
"ret_val.val_ptr->value_elements[i+index] = "
"new %s(*repl.val_ptr->value_elements[i]);\n"
"}\n"
"}\n"
- "for (int i = 0; i < nof_elements - index - len; i++) {\n"
- "if (is_elem_bound(index+i+len)) {\n"
- "ret_val.val_ptr->value_elements[index+i+repl_nof_elements] = "
+ "for (int i = 0; i < val_ptr->n_elements - index - len; i++) {\n"
+ "if (val_ptr->value_elements[index+i+len] != NULL) {\n"
+ "ret_val.val_ptr->value_elements[index+i+repl.val_ptr->n_elements] = "
"new %s(*val_ptr->value_elements[index+i+len]);\n"
"}\n"
"}\n"
"val_ptr->n_elements = new_size;\n"
"} else if (new_size < val_ptr->n_elements) {\n"
"for (int elem_count = new_size; elem_count < val_ptr->n_elements; "
- "elem_count++) {\n"
- "if (val_ptr->value_elements[elem_count] != NULL) {\n"
- "if (is_index_refd(elem_count)) {\n"
- "val_ptr->value_elements[elem_count]->clean_up();\n"
- "}\n"
- "else {\n"
+ "elem_count++)\n"
+ "if (val_ptr->value_elements[elem_count] != NULL)"
"delete val_ptr->value_elements[elem_count];\n"
- "val_ptr->value_elements[elem_count] = 0;\n"
- "}\n"
- "}\n"
- "}\n"
- "if (new_size <= get_max_refd_index()) {\n"
- "new_size = get_max_refd_index() + 1;\n"
- "}\n"
- "if (new_size < val_ptr->n_elements) {\n"
"val_ptr->value_elements = (%s**)"
"reallocate_pointers((void**)val_ptr->value_elements, "
"val_ptr->n_elements, new_size);\n"
"val_ptr->n_elements = new_size;\n"
"}\n"
- "}\n"
"}\n\n", name, dispname, type, type, type, dispname, type);
/* is_bound function */
def = mputstr(def,
- "boolean is_bound() const;\n");
- src = mputprintf(src,
- "boolean %s::is_bound() const\n"
- "{\n"
- "if (refd_indices.empty()) {\n"
- "return (val_ptr != NULL);\n"
- "}\n"
- "return (get_nof_elements() != 0);\n"
- "}\n\n", name);
+ "inline boolean is_bound() const {return val_ptr != NULL; }\n");
/* is_present function */
def = mputstr(def,
"boolean %s::is_value() const\n"
"{\n"
"if (val_ptr == NULL) return false;\n"
- "for(int i = 0; i < get_nof_elements(); ++i) {\n"
- "if (!is_elem_bound(i) || "
+ "for(int i = 0; i < val_ptr->n_elements; ++i) {\n"
+ "if (val_ptr->value_elements[i] == NULL || "
"!val_ptr->value_elements[i]->is_value()) return FALSE;\n"
"}\n"
"return TRUE;\n"
"if (val_ptr == NULL) "
"TTCN_error(\"Performing sizeof operation on an unbound value of type "
"%s.\");\n"
- "return get_nof_elements();\n"
+ "return val_ptr->n_elements;\n"
"}\n\n", name, dispname);
/* lengthof operation */
"if (val_ptr == NULL) "
"TTCN_error(\"Performing lengthof operation on an unbound value of type "
"%s.\");\n"
- "for (int my_length=get_nof_elements(); my_length>0; my_length--) "
- "if (is_elem_bound(my_length-1)) return my_length;\n"
+ "for (int my_length=val_ptr->n_elements; my_length>0; my_length--) "
+ "if (val_ptr->value_elements[my_length-1] != NULL) return my_length;\n"
"return 0;\n"
"}\n\n", name, dispname);
"TTCN_Logger::log_event_unbound();\n"
"return;\n"
"}\n"
- "switch (get_nof_elements()) {\n"
+ "switch (val_ptr->n_elements) {\n"
"case 0:\n"
"TTCN_Logger::log_event_str(\"{ }\");\n"
"break;\n"
"default:\n"
"TTCN_Logger::log_event_str(\"{ \");\n"
- "for (int elem_count = 0; elem_count < get_nof_elements(); "
+ "for (int elem_count = 0; elem_count < val_ptr->n_elements; "
"elem_count++) {\n"
"if (elem_count > 0) TTCN_Logger::log_event_str(\", \");\n"
"(*this)[elem_count].log();\n"
src = mputprintf(src,
"void %s::set_implicit_omit()\n{\n"
"if (val_ptr == NULL) return;\n"
- "for (int i = 0; i < get_nof_elements(); i++) {\n"
- "if (is_elem_bound(i)) val_ptr->value_elements[i]->set_implicit_omit();\n"
+ "for (int i = 0; i < val_ptr->n_elements; i++) {\n"
+ "if (val_ptr->value_elements[i] != NULL) val_ptr->value_elements[i]->set_implicit_omit();\n"
"}\n}\n\n", name);
-
- /* functions for inserting and removing references to elements of the record of */
- def = mputstr(def, " void add_refd_index(int index);\n");
- src = mputprintf(src,
- "void %s::add_refd_index(int index)\n"
- "{\n"
- " refd_indices.push_back(index);\n"
- " if (index > get_max_refd_index()) {\n"
- " max_refd_index = index;\n"
- " }\n"
- "}\n\n", name);
-
- def = mputstr(def, " void remove_refd_index(int index);\n");
- src = mputprintf(src,
- "void %s::remove_refd_index(int index)\n"
- "{\n"
- " for (size_t i = refd_indices.size(); i > 0; --i) {\n"
- " if (refd_indices[i - 1] == index) {\n"
- " refd_indices.erase_at(i - 1);\n"
- " break;\n"
- " }\n"
- " }\n"
- " if (get_max_refd_index() == index) {\n"
- " max_refd_index = -1;\n"
- " }\n"
- "}\n\n", name);
/* encoding / decoding functions */
def = mputstr(def, "void encode_text(Text_Buf& text_buf) const;\n");
"{\n"
"if (val_ptr == NULL) "
"TTCN_error(\"Text encoder: Encoding an unbound value of type %s.\");\n"
- "text_buf.push_int(get_nof_elements());\n"
- "for (int elem_count = 0; elem_count < get_nof_elements(); "
+ "text_buf.push_int(val_ptr->n_elements);\n"
+ "for (int elem_count = 0; elem_count < val_ptr->n_elements; "
"elem_count++)\n"
"(*this)[elem_count].encode_text(text_buf);\n"
"}\n\n", name, dispname);
src = mputprintf(src,
"void %s::decode_text(Text_Buf& text_buf)\n"
"{\n"
- "int new_size = text_buf.pull_int().get_val();\n"
- "if (new_size < 0)\n TTCN_error(\"Text decoder: Negative size "
+ "clean_up();\n"
+ "val_ptr = new recordof_setof_struct;\n"
+ "val_ptr->ref_count = 1;\n"
+ "val_ptr->n_elements = text_buf.pull_int().get_val();\n"
+ "if (val_ptr->n_elements < 0) TTCN_error(\"Text decoder: Negative size "
"was received for a value of type %s.\");\n"
- "set_size(new_size);\n"
- "for (int elem_count = 0; elem_count < new_size; "
+ "val_ptr->value_elements = (%s**)allocate_pointers(val_ptr->n_elements);\n"
+ "for (int elem_count = 0; elem_count < val_ptr->n_elements; "
"elem_count++) {\n"
- "if (val_ptr->value_elements[elem_count] == NULL) {\n"
"val_ptr->value_elements[elem_count] = new %s;\n"
- "}\n"
"val_ptr->value_elements[elem_count]->decode_text(text_buf);\n"
"}\n"
- "}\n\n", name, dispname, type);
+ "}\n\n", name, dispname, type, type);
if(ber_needed || raw_needed || text_needed || xer_needed || json_needed)
def_encdec(name, &def, &src, ber_needed, raw_needed, text_needed,
" }\n"
" return encoded_length;\n"
" }\n"
- " for(int a=0;a<get_nof_elements();a++){\n"
+ " for(int a=0;a<val_ptr->n_elements;a++){\n"
" if(a!=0 && p_td.text->separator_encode){\n"
" p_buf.put_cs(*p_td.text->separator_encode);\n"
" encoded_length+=p_td.text->separator_encode->lengthof();\n"
" ml++;\n"
" }\n"
" if(first_call) {\n"
- " set_size(0);\n"
+ " clean_up();\n"
+ " val_ptr=new recordof_setof_struct;\n"
+ " val_ptr->ref_count=1;\n"
+ " val_ptr->n_elements=0;\n"
+ " val_ptr->value_elements=NULL;\n"
" }\n"
- " int more=get_nof_elements();\n"
+ " int more=val_ptr->n_elements;\n"
" while(TRUE){\n"
" %s *val=new %s;\n"
" pos=p_buf.get_pos();\n"
" break;\n"
" }\n"
" sep_found=FALSE;\n"
- " if (refd_indices.empty()) {\n"
- " val_ptr->value_elements = (%s**)reallocate_pointers"
+ " val_ptr->value_elements = (%s**)reallocate_pointers"
"((void**)val_ptr->value_elements, val_ptr->n_elements, "
"val_ptr->n_elements + 1);\n"
- " val_ptr->value_elements[val_ptr->n_elements]=val;\n"
- " val_ptr->n_elements++;\n"
- " }\n"
- " else {\n"
- " (*this)[get_nof_elements()] = *val;\n"
- " delete val;\n"
- " }\n"
+ " val_ptr->value_elements[val_ptr->n_elements]=val;\n"
+ " val_ptr->n_elements++;\n"
" decoded_length+=len;\n"
" if(p_td.text->separator_decode){\n"
" int tl;\n"
" if((tl=p_td.text->end_decode->match_begin(p_buf))<0){\n"
" if(no_err){"
" if(!first_call){\n"
- " set_size(more);\n"
+ " for(int a=more; a<val_ptr->n_elements; a++) "
+ "delete val_ptr->value_elements[a];\n"
+ " val_ptr->n_elements=more;\n"
" }\n"
" return -1;\n"
" }\n"
" decoded_length+=tl;\n"
" p_buf.increase_pos(tl);\n"
" }\n"
- " if(get_nof_elements()==0){\n"
+ " if(val_ptr->n_elements==0){\n"
" if(!(p_td.text->end_decode || p_td.text->begin_decode)) {\n"
" if(no_err)return -1;\n"
" TTCN_EncDec_ErrorContext::error"
" return decoded_length;\n"
" }\n"
" }\n"
- " if(!first_call && more==get_nof_elements() && "
+ " if(!first_call && more==val_ptr->n_elements && "
"!(p_td.text->end_decode || p_td.text->begin_decode)) return -1;\n"
" return decoded_length;\n"
"}\n"
" if(!new_tlv) {\n"
" new_tlv=ASN_BER_TLV_t::construct(NULL);\n"
" TTCN_EncDec_ErrorContext ec;\n"
- " for(int elem_i=0; elem_i<get_nof_elements(); elem_i++) {\n"
+ " for(int elem_i=0; elem_i<val_ptr->n_elements; elem_i++) {\n"
" ec.set_msg(\"Component #%%d: \", elem_i);\n"
" new_tlv->add_TLV((*this)[elem_i].BER_encode_TLV"
"(%s_descr_, p_coding));\n"
" TTCN_EncDec_ErrorContext ec_0(\"While decoding '%%s' type: \","
" p_td.name);\n"
" stripped_tlv.chk_constructed_flag(TRUE);\n"
- " set_size(0);\n"
+ " clean_up();\n"
+ " val_ptr = new recordof_setof_struct;\n"
+ " val_ptr->ref_count = 1;\n"
+ " val_ptr->n_elements = 0;\n"
+ " val_ptr->value_elements = NULL;\n"
" size_t V_pos=0;\n"
" ASN_BER_TLV_t tmp_tlv;\n"
" TTCN_EncDec_ErrorContext ec_1(\"Component #\");\n"
" TTCN_EncDec_ErrorContext ec_2(\"0: \");\n"
" while(BER_decode_constdTLV_next(stripped_tlv, V_pos, L_form, "
"tmp_tlv)) {\n"
- " (*this)[get_nof_elements()].BER_decode_TLV(%s_descr_, tmp_tlv, "
+ " val_ptr->value_elements = (%s**)reallocate_pointers("
+ "(void**)val_ptr->value_elements, val_ptr->n_elements, "
+ "val_ptr->n_elements + 1);\n"
+ " val_ptr->n_elements++;\n"
+ " val_ptr->value_elements[val_ptr->n_elements - 1] = new %s;\n"
+ " val_ptr->value_elements[val_ptr->n_elements - 1]->BER_decode_TLV(%s_descr_, tmp_tlv, "
"L_form);\n"
- " ec_2.set_msg(\"%%d: \", get_nof_elements());\n"
+ " ec_2.set_msg(\"%%d: \", val_ptr->n_elements);\n"
" }\n"
" return TRUE;\n"
"}\n"
"\n"
, name, sdef->oftypedescrname
, sdef->kind==SET_OF?" new_tlv->sort_tlvs();\n":""
- , name, sdef->oftypedescrname
+ , name, type, type, sdef->oftypedescrname
);
if(sdef->has_opentypes) {
" p_typelist.push(this);\n"
" TTCN_EncDec_ErrorContext ec_0(\"Component #\");\n"
" TTCN_EncDec_ErrorContext ec_1;\n"
- " for(int elem_i=0; elem_i<get_nof_elements(); elem_i++) {\n"
+ " for(int elem_i=0; elem_i<val_ptr->n_elements; elem_i++) {\n"
" ec_1.set_msg(\"%%d: \", elem_i);\n"
- " (*this)[elem_i].BER_decode_opentypes(p_typelist,"
+ " val_ptr->value_elements[elem_i]->BER_decode_opentypes(p_typelist,"
" L_form);\n"
" }\n"
" p_typelist.pop();\n"
" int decoded_field_length=0;\n"
" size_t start_of_field=0;\n"
" if(first_call) {\n"
- " set_size(0);\n"
+ " clean_up();\n"
+ " val_ptr=new recordof_setof_struct;\n"
+ " val_ptr->ref_count=1;\n"
+ " val_ptr->n_elements=0;\n"
+ " val_ptr->value_elements=NULL;\n"
" }\n"
- " int start_field=get_nof_elements();\n"
+ " int start_field=val_ptr->n_elements;\n"
" if(p_td.raw->fieldlength || sel_field!=-1){\n"
" int a=0;\n"
" if(sel_field==-1) sel_field=p_td.raw->fieldlength;\n"
" decoded_length+=decoded_field_length;\n"
" limit-=decoded_field_length;\n"
" }\n"
+ " if(a==0) val_ptr->n_elements=0;\n"
" } else {\n"
" int a=start_field;\n"
" if(limit==0){\n"
" if(!first_call) return -1;\n"
+ " val_ptr->n_elements=0;\n"
" return decoded_length+p_buf.increase_pos_padd(p_td.raw->padding)"
"+prepaddlength;\n"
" }\n"
" decoded_field_length=(*this)[a].RAW_decode(%s_descr_,p_buf,limit,"
"top_bit_ord,TRUE);\n"
" if(decoded_field_length < 0){\n"
- " set_size(get_nof_elements() - 1);\n"
+ " delete &(*this)[a];\n"
+ " val_ptr->n_elements--;\n"
" p_buf.set_pos_bit(start_of_field);\n"
" if(a>start_field){\n"
" return decoded_length+p_buf.increase_pos_padd(p_td.raw->padding)"
"RAW_enc_tree& myleaf) const{\n"
" int encoded_length=0;\n"
" int encoded_num_of_records=p_td.raw->fieldlength?"
- "smaller(get_nof_elements(), p_td.raw->fieldlength)"
- ":get_nof_elements();\n"
+ "smaller(val_ptr->n_elements, p_td.raw->fieldlength)"
+ ":val_ptr->n_elements;\n"
" myleaf.isleaf=FALSE;\n"
" myleaf.rec_of=TRUE;\n"
" myleaf.body.node.num_of_nodes=encoded_num_of_records;\n"
" if (val_ptr) try {\n"
" char **new_ns;\n"
" size_t num_new;\n"
- " for (int i = 0; i < get_nof_elements(); ++i) {\n"
+ " for (int i = 0; i < val_ptr->n_elements; ++i) {\n"
" bool def_ns_1 = false;"
" new_ns = (*this)[i].collect_ns(%s_xer_, num_new, def_ns_1);\n"
" merge_ns(collected_ns, num_collected, new_ns, num_new);\n"
, name, sdef->oftypedescrname);
src=mputprintf(src,
- "int %s::XER_encode(const XERdescriptor_t& p_td,"
- " TTCN_Buffer& p_buf, unsigned int p_flavor, int p_indent) const\n{\n"
+ "int %s::XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, "
+ "unsigned int p_flavor, int p_indent, embed_values_enc_struct_t* emb_val) const\n{\n"
" if (val_ptr == 0) TTCN_error(\"Attempt to XER-encode an unbound record of\");\n" /* TODO type name */
" int encoded_length=(int)p_buf.get_len();\n"
" boolean e_xer = is_exer(p_flavor);\n"
" || (p_flavor & USE_TYPE_ATTR)));\n"
" boolean indenting = !is_canonical(p_flavor) && own_tag;\n"
"%s" /* Factor out p_indent if not attribute */
- " int nof_elements = get_nof_elements();\n"
- " if (nof_elements==0) {\n" /* Empty record of */
+ " if (val_ptr->n_elements==0) {\n" /* Empty record of */
, name
, sdef->xerAttribute ? "" : " if (indenting) do_indent(p_buf, p_indent);\n"
);
" unsigned char saved[4];\n"
" memcpy(saved, buf_data + (buf_len - shorter), shorter);\n"
" p_buf.increase_length(-shorter);\n"
- " for (int i = 0; i < nof_elements; ++i) {\n"
+ " for (int i = 0; i < val_ptr->n_elements; ++i) {\n"
" TTCN_EncDec_ErrorContext ec_0(\"Attribute %d: \", i);\n"
- " if (!is_elem_bound(i)) {\n"
+ " if (val_ptr->value_elements[i] == NULL) {\n"
" TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,\n"
" \"Encoding an unbound universal charstring value.\");\n"
" continue;\n"
" p_buf.put_s(ns_len, (const unsigned char*)ns);\n"
" UNIVERSAL_CHARSTRING before(sp_at, (const universal_char*)(*val_ptr->value_elements[i]));\n"
- " before.XER_encode(UNIVERSAL_CHARSTRING_xer_, p_buf, p_flavor | ANY_ATTRIBUTES, p_indent);\n"
+ " before.XER_encode(UNIVERSAL_CHARSTRING_xer_, p_buf, p_flavor | ANY_ATTRIBUTES, p_indent, 0);\n"
// Ensure the namespace abides to its restrictions
" if (p_td.xer_bits & (ANY_FROM | ANY_EXCEPT)) {\n"
" TTCN_Buffer ns_buf;\n"
" }\n"
" UNIVERSAL_CHARSTRING after(len - j, (const universal_char*)(*val_ptr->value_elements[i]) + j);\n"
- " after.XER_encode(UNIVERSAL_CHARSTRING_xer_, p_buf, p_flavor | ANY_ATTRIBUTES, p_indent);\n"
+ " after.XER_encode(UNIVERSAL_CHARSTRING_xer_, p_buf, p_flavor | ANY_ATTRIBUTES, p_indent, 0);\n"
// Put this attribute in a dummy element and walk through it to check its validity
" TTCN_Buffer check_buf;\n"
" check_buf.put_s(2, (unsigned char*)\"<a\");\n"
" TTCN_EncDec_ErrorContext ec_1;\n"
);
src=mputprintf(src,
- " for (int i = 0; i < nof_elements; ++i) {\n"
+ " for (int i = 0; i < val_ptr->n_elements; ++i) {\n"
+ /*" if (i > 0 && !own_tag && 0 != emb_val &&\n"
+ " emb_val->embval_index < emb_val->embval_size) {\n"
+ " emb_val->embval_array->get_embedded_value(emb_val->embval_index).XER_encode(\n"
+ " UNIVERSAL_CHARSTRING_xer_, p_buf, p_flavor | EMBED_VALUES, p_indent+1, 0);\n"
+ " ++emb_val->embval_index;\n"
+ " }\n" - temporarily removed in RT1 */
" ec_1.set_msg(\"%%d: \", i);\n"
" if (e_xer && (p_td.xer_bits & XER_LIST) && i>0) p_buf.put_c(' ');\n"
- " (*this)[i].XER_encode(%s_xer_, p_buf, p_flavor, p_indent+own_tag);\n"
+ " (*this)[i].XER_encode(%s_xer_, p_buf, p_flavor, p_indent+own_tag, emb_val);\n"
" }\n"
" if (indenting && !is_exerlist(p_flavor)) {\n",
sdef->oftypedescrname
"// written by %s in " __FILE__ " at %d\n"
#endif
"int %s::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& p_reader, "
- "unsigned int p_flavor)\n{\n"
+ "unsigned int p_flavor, embed_values_dec_struct_t* emb_val)\n{\n"
" boolean e_xer = is_exer(p_flavor);\n"
" int xerbits = p_td.xer_bits;\n"
" if (p_flavor & XER_TOPLEVEL) xerbits &= ~UNTAGGED;\n"
/* not toplevel anymore and remove the flags for USE-UNION the oftype doesn't need them */
" p_flavor &= ~XER_TOPLEVEL & ~XER_LIST & ~USE_TYPE_ATTR;\n"
" int rd_ok=1, xml_depth=-1;\n"
- " set_size(0);\n" /* empty but initialized array */
+ " *this = NULL_VALUE;\n" /* empty but initialized array */
" int type = 0;\n" /* none */
" if (own_tag) for (rd_ok = p_reader.Ok(); rd_ok == 1; rd_ok = p_reader.Read()) {\n"
" type = p_reader.NodeType();\n"
/* Don't move to the #text, that's the callee's responsibility. */
/* The call to the non-const operator[] creates a new element object,
* then we call its XER_decode with the temporary XML reader. */
- " (*this)[get_nof_elements()].XER_decode(%s_xer_, reader_2, p_flavor);\n"
- " if (p_flavor & EXIT_ON_ERROR && !(*this)[get_nof_elements() - 1].is_bound()) {\n"
- " if (1 == get_nof_elements()) {\n"
+ " (*this)[val_ptr->n_elements].XER_decode(%s_xer_, reader_2, p_flavor, 0);\n"
+ " if (p_flavor & EXIT_ON_ERROR && !(*this)[val_ptr->n_elements - 1].is_bound()) {\n"
+ " if (1 == val_ptr->n_elements) {\n"
// Failed to decode even the first element
" clean_up();\n"
" } else {\n"
// Some elements were successfully decoded -> only delete the last one
- " set_size(get_nof_elements() - 1);\n"
+ " set_size(val_ptr->n_elements - 1);\n"
" }\n"
" xmlFree(x_val);\n"
" return -1;\n"
* for the element type (a string), so behave like a record-of
* (string with ANY-ELEMENT): call the non-const operator[]
* to create a new element, then read the entire XML element into it. */
- " (*this)[get_nof_elements()] = (const char*)p_reader.ReadOuterXml();\n"
+ " (*this)[val_ptr->n_elements] = (const char*)p_reader.ReadOuterXml();\n"
/* Consume the element, then move ahead */
" for (rd_ok = p_reader.Read(); rd_ok == 1 && p_reader.Depth() > xml_depth; rd_ok = p_reader.Read()) {}\n"
" if (p_reader.NodeType() != XML_READER_TYPE_ELEMENT) rd_ok = p_reader.Read();\n"
" break;\n"
" }\n"
/* The call to the non-const operator[] creates the element */
- " (*this)[get_nof_elements()].XER_decode(%s_xer_, p_reader, p_flavor);\n"
+ " (*this)[val_ptr->n_elements].XER_decode(%s_xer_, p_reader, p_flavor, emb_val);\n"
+ " if (0 != emb_val && !own_tag && val_ptr->n_elements > 1) {\n"
+ " ++emb_val->embval_index;\n"
+ " }\n"
" }\n"
" }\n"
" else if (XML_READER_TYPE_END_ELEMENT == type) {\n"
" }\n"
" break;\n"
" }\n"
+ /*" else if (XML_READER_TYPE_TEXT == type && 0 != emb_val && !own_tag && get_nof_elements() > 0) {\n"
+ " UNIVERSAL_CHARSTRING emb_ustr((const char*)p_reader.Value());\n"
+ " emb_val->embval_array->set_embedded_value(emb_val->embval_index, emb_ustr);\n"
+ " rd_ok = p_reader.Read();\n"
+ " }\n" - temporarily removed in RT1 */
" else {\n"
" rd_ok = p_reader.Read();\n"
" }\n"
" return -1;\n"
" }\n\n"
" int enc_len = p_tok.put_next_token(JSON_TOKEN_ARRAY_START, NULL);\n"
- " for(int i = 0; i < get_nof_elements(); ++i) {\n"
+ " for(int i = 0; i < val_ptr->n_elements; ++i) {\n"
" int ret_val = (*this)[i].JSON_encode(%s_descr_, p_tok);\n"
" if (0 > ret_val) break;\n"
" enc_len += ret_val;\n"
" }\n"
" return JSON_ERROR_FATAL;\n"
" }\n"
- " if (refd_indices.empty()) {\n"
- " val_ptr->value_elements = (%s**)reallocate_pointers(\n"
- " (void**)val_ptr->value_elements, val_ptr->n_elements, val_ptr->n_elements + 1);\n"
- " val_ptr->value_elements[val_ptr->n_elements] = val;\n"
- " val_ptr->n_elements++;\n"
- " dec_len += ret_val;\n"
- " }\n"
- " else {\n"
- " (*this)[get_nof_elements()] = *val;\n"
- " delete val;\n"
- " }\n"
+ " val_ptr->value_elements = (%s**)reallocate_pointers(\n"
+ " (void**)val_ptr->value_elements, val_ptr->n_elements, val_ptr->n_elements + 1);\n"
+ " val_ptr->value_elements[val_ptr->n_elements] = val;\n"
+ " val_ptr->n_elements++;\n"
+ " dec_len += ret_val;\n"
" }\n\n"
" dec_len += p_tok.get_next_token(&token, NULL, NULL);\n"
" if (JSON_TOKEN_ARRAY_END != token) {\n"
"if (other_value.val_ptr == NULL)\n"
"TTCN_error(\"The right operand of comparison is an unbound value of "
"type %s.\");\n"
- "return other_value.get_nof_elements() == 0;\n"
+ "return other_value.val_ptr->n_elements == 0;\n"
"}\n\n", name, dispname);
output->header.function_prototypes =
, name, sdef->oftypedescrname);
src=mputprintf(src,
- "int %s::XER_encode(const XERdescriptor_t& p_td,"
- " TTCN_Buffer& p_buf, unsigned int p_flavor, int p_indent) const\n{\n"
+ "int %s::XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, "
+ "unsigned int p_flavor, int p_indent, embed_values_enc_struct_t* emb_val) const\n{\n"
" if (n_elements==-1) TTCN_error(\"Attempt to XER-encode an unbound record of\");\n" /* TODO type name */
" int encoded_length=(int)p_buf.get_len();\n"
" boolean e_xer = is_exer(p_flavor);\n"
" p_buf.put_s(ns_len, (const unsigned char*)ns);\n"
" UNIVERSAL_CHARSTRING before(sp_at, (const universal_char*)(value_elements[i]));\n"
- " before.XER_encode(UNIVERSAL_CHARSTRING_xer_, p_buf, p_flavor | ANY_ATTRIBUTES, p_indent);\n"
+ " before.XER_encode(UNIVERSAL_CHARSTRING_xer_, p_buf, p_flavor | ANY_ATTRIBUTES, p_indent, 0);\n"
// Ensure the namespace abides to its restrictions
" if (p_td.xer_bits & (ANY_FROM | ANY_EXCEPT)) {\n"
" TTCN_Buffer ns_buf;\n"
" }\n"
" UNIVERSAL_CHARSTRING after(len - j, (const universal_char*)(value_elements[i]) + j);\n"
- " after.XER_encode(UNIVERSAL_CHARSTRING_xer_, p_buf, p_flavor | ANY_ATTRIBUTES, p_indent);\n"
+ " after.XER_encode(UNIVERSAL_CHARSTRING_xer_, p_buf, p_flavor | ANY_ATTRIBUTES, p_indent, 0);\n"
// Put this attribute in a dummy element and walk through it to check its validity
" TTCN_Buffer check_buf;\n"
" check_buf.put_s(2, (unsigned char*)\"<a\");\n"
);
src=mputprintf(src,
" for (int i = 0; i < n_elements; ++i) {\n"
+ /*" if (i > 0 && !own_tag && 0 != emb_val &&\n"
+ " emb_val->embval_index < emb_val->embval_size) {\n"
+ " emb_val->embval_array->get_embedded_value(emb_val->embval_index).XER_encode(\n"
+ " UNIVERSAL_CHARSTRING_xer_, p_buf, p_flavor | EMBED_VALUES, p_indent+1, 0);\n"
+ " ++emb_val->embval_index;\n"
+ " }\n" - temporarily removed in RT1 */
" ec_1.set_msg(\"%%d: \", i);\n"
" if (e_xer && (p_td.xer_bits & XER_LIST) && i>0) p_buf.put_c(' ');\n"
- " value_elements[i].XER_encode(%s_xer_, p_buf, p_flavor, p_indent+own_tag);\n"
+ " value_elements[i].XER_encode(%s_xer_, p_buf, p_flavor, p_indent+own_tag, emb_val);\n"
" }\n"
" if (indenting && !is_exerlist(p_flavor)) {\n",
sdef->oftypedescrname
"// written by %s in " __FILE__ " at %d\n"
#endif
"int %s::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& p_reader, "
- "unsigned int p_flavor)\n{\n"
+ "unsigned int p_flavor, embed_values_dec_struct_t* emb_val)\n{\n"
" boolean e_xer = is_exer(p_flavor);\n"
" int xerbits = p_td.xer_bits;\n"
" if (p_flavor & XER_TOPLEVEL) xerbits &= ~UNTAGGED;\n"
/* Don't move to the #text, that's the callee's responsibility. */
/* The call to the non-const operator[] creates a new element object,
* then we call its XER_decode with the temporary XML reader. */
- " (*this)[n_elements].XER_decode(%s_xer_, reader_2, p_flavor);\n"
+ " (*this)[n_elements].XER_decode(%s_xer_, reader_2, p_flavor, 0);\n"
" if (p_flavor & EXIT_ON_ERROR && !(*this)[n_elements - 1].is_bound()) {\n"
" if (1 == n_elements) {\n"
// Failed to decode even the first element
" break;\n"
" }\n"
/* The call to the non-const operator[] creates the element */
- " operator [](n_elements).XER_decode(%s_xer_, p_reader, p_flavor);\n"
+ " operator [](n_elements).XER_decode(%s_xer_, p_reader, p_flavor, emb_val);\n"
+ " if (0 != emb_val && !own_tag && n_elements > 1) {\n"
+ " ++emb_val->embval_index;\n"
+ " }\n"
" }\n"
" }\n"
" else if (XML_READER_TYPE_END_ELEMENT == type) {\n"
" }\n"
" break;\n"
" }\n"
+ /*" else if (XML_READER_TYPE_TEXT == type && 0 != emb_val && !own_tag && n_elements > 0) {\n"
+ " UNIVERSAL_CHARSTRING emb_ustr((const char*)p_reader.Value());\n"
+ " emb_val->embval_array->set_embedded_value(emb_val->embval_index, emb_ustr);\n"
+ " rd_ok = p_reader.Read();\n"
+ " }\n" - temporarily removed in RT1 */
" else {\n"
" rd_ok = p_reader.Read();\n"
" }\n"
"}\n\n"
, name, type, sdef->oftypedescrname);
}
-
- /* functions for keeping track of referenced indices (only implemented for regular record of class) */
- def = mputstr(def,
- "void add_refd_index(int) {}\n"
- "void remove_refd_index(int) {}\n\n");
/* end of class */
def = mputstr(def, "};\n\n");
return ((*length_restriction * *(p_st->length_restriction)).is_empty()!=TTRUE);
}
+bool SubtypeConstraint::is_upper_limit_infinity() const
+{
+ if (ST_INTEGER == subtype && integer_st) {
+ return integer_st->is_upper_limit_infinity();
+ }
+ if (ST_FLOAT == subtype && float_st) {
+ return float_st->is_upper_limit_infinity();
+ }
+ return false;
+}
+
+bool SubtypeConstraint::is_lower_limit_infinity() const
+{
+ if (ST_INTEGER == subtype && integer_st) {
+ return integer_st->is_lower_limit_infinity();
+ }
+
+ if (ST_FLOAT == subtype && float_st) {
+ return float_st->is_lower_limit_infinity();
+ }
+ return false;
+}
+
+
void SubtypeConstraint::except(const SubtypeConstraint* other)
{
if (other==NULL) FATAL_ERROR("SubtypeConstraint::except()");
bool is_compatible_with_elem() const;
// used to check compatibility of structured types
bool is_length_compatible(const SubtypeConstraint *p_st) const;
+ bool is_upper_limit_infinity() const;
+ bool is_lower_limit_infinity() const;
};
/**
return ret_val;
}
+bool RealRangeListConstraint::is_upper_limit_infinity () const
+{
+ return rlc.is_upper_limit_infinity();
+}
+
+bool RealRangeListConstraint::is_lower_limit_infinity () const
+{
+ return rlc.is_lower_limit_infinity();
+}
+
////////////////////////////////////////////////////////////////////////////////
string BooleanListConstraint::to_string() const
LIMITTYPE get_minimal() const;
LIMITTYPE get_maximal() const;
+ bool is_upper_limit_infinity() const;
+ bool is_lower_limit_infinity() const;
+
string to_string(bool add_brackets=true) const;
/** conversion from integer range to size range,
return values[values.size()-1];
}
+template <typename LIMITTYPE>
+bool RangeListConstraint<LIMITTYPE>::is_upper_limit_infinity () const
+{
+ if (0 == values.size()) return false;
+ return LIMITTYPE::maximum == values[values.size()-1];
+}
+
+template <typename LIMITTYPE>
+bool RangeListConstraint<LIMITTYPE>::is_lower_limit_infinity () const
+{
+ if (0 == values.size()) return false;
+ return LIMITTYPE::minimum == values[0];
+}
+
template <typename LIMITTYPE>
string RangeListConstraint<LIMITTYPE>::to_string(bool add_brackets) const
{
real_limit_t get_maximal() const { return rlc.get_maximal(); }
string to_string() const;
+ bool is_upper_limit_infinity() const;
+ bool is_lower_limit_infinity() const;
};
////////////////////////////////////////////////////////////////////////////////
return false;
}
- void Module::add_types_to_json_schema(JSON_Tokenizer& json)
+ void Module::generate_json_schema(JSON_Tokenizer& json, map<Type*, JSON_Tokenizer>& json_refs)
{
// add a new property for this module
- json.put_next_token(JSON_TOKEN_NAME, modid->get_dispname().c_str());
+ json.put_next_token(JSON_TOKEN_NAME, modid->get_ttcnname().c_str());
// add type definitions into an object
json.put_next_token(JSON_TOKEN_OBJECT_START);
- // pass the JSON tokenizer onto each type definition
+ // cycle through each type, generate schema segment and reference when needed
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) {
- def->generate_json_schema(json);
+ Type* t = def->get_Type();
+ if (t->has_encoding(Type::CT_JSON)) {
+ // insert type's schema segment
+ t->generate_json_schema(json, false, false);
+
+ if (json_refs_for_all_types && !json_refs.has_key(t)) {
+ // create JSON schema reference for the type
+ JSON_Tokenizer* json_ref = new JSON_Tokenizer;
+ json_refs.add(t, json_ref);
+ t->generate_json_schema_ref(*json_ref);
+ }
+ }
}
}
// end of type definitions
json.put_next_token(JSON_TOKEN_OBJECT_END);
- }
-
- void Module::add_func_to_json_schema(map<Type*, JSON_Tokenizer>& json_refs)
- {
+
+ // insert function data
for (size_t i = 0; i < asss->get_nof_asss(); ++i) {
Def_ExtFunction* def = dynamic_cast<Def_ExtFunction*>(asss->get_ass_byIndex(i));
if (def != NULL) {
}
w_attrib_path->set_parent(p_path);
}
-
- void Def_Type::generate_json_schema(JSON_Tokenizer& json)
- {
- if (type->has_encoding(Type::CT_JSON)) {
- type->generate_json_schema(json, false, false);
- }
- }
// =================================
// ===== Def_Const
// the schema segment doesn't exist yet, create it and insert the reference
json = new JSON_Tokenizer;
json_refs.add(type, json);
- json->put_next_token(JSON_TOKEN_OBJECT_START);
- json->put_next_token(JSON_TOKEN_NAME, "$ref");
- char* ref_str = mprintf("\"#/definitions/%s/%s\"",
- type->get_my_scope()->get_scope_mod()->get_modid().get_dispname().c_str(),
- type->get_dispname().c_str());
- json->put_next_token(JSON_TOKEN_STRING, ref_str);
- Free(ref_str);
+ type->generate_json_schema_ref(*json);
}
// insert a property to specify which function this is (encoding or decoding)
case AP_REF:
if (gen_restriction_check!=TR_NONE ||
gen_post_restriction_check!=TR_NONE) return false;
- if (ref->get_subrefs() != NULL) {
+ if (use_runtime_2 && ref->get_subrefs() != NULL) {
FieldOrArrayRefs* subrefs = ref->get_subrefs();
for (size_t i = 0; i < subrefs->get_nof_refs(); ++i) {
if (FieldOrArrayRef::ARRAY_REF == subrefs->get_ref(i)->get_type()) {
}
}
- if (ActualPar::AP_REF == par->get_selection()) {
+ if (use_runtime_2 && ActualPar::AP_REF == par->get_selection()) {
// if the parameter references an element of a record of/set of, then
// the record of object needs to know, so it doesn't delete the referenced
// element
// let the array object know that the index is referenced before
// calling the function, and let it know that it's now longer
// referenced after the function call
- string tmp_id = ref->get_my_scope()->get_scope_mod_gen()->get_temporary_id();
- expr->preamble = mputprintf(expr->preamble,
- "INTEGER %s = %s;\n"
+ expr->preamble = mputprintf(expr->preamble,
"%s.add_refd_index(%s);\n",
- tmp_id.c_str(), index_expr.expr, array_expr.expr, index_expr.expr);
+ array_expr.expr, index_expr.expr);
expr->postamble = mputprintf(expr->postamble,
- "%s.remove_refd_index(%s);\n"
- "if (%s >= %s.size_of()) TTCN_warning(\""
- "Warning: possibly incompatible behaviour related to TR HT24380;"
- " for details see release notes\");\n",
- array_expr.expr, index_expr.expr, tmp_id.c_str(), array_expr.expr);
+ "%s.remove_refd_index(%s);\n",
+ array_expr.expr, index_expr.expr);
// insert any postambles the array object or the index might have
if (array_expr.postamble != NULL) {
expr->preamble = mputstr(expr->preamble, array_expr.postamble);
bool is_visible(const Identifier& id, visibility_t visibility);
- /** Generates JSON schema segments for the types defined in the module
- * and adds them to the JSON schema parameter. */
- void add_types_to_json_schema(JSON_Tokenizer& json);
-
- /** Generates JSON schemas containing references to the types that have JSON
- * encoding and/or decoding functions declared in the module. Information
- * related to these functions is also inserted after the references. */
- void add_func_to_json_schema(map<Type*, JSON_Tokenizer>& json_refs);
+ /** Generates JSON schema segments for the types defined in the modules,
+ * and references to these types. Information related to the types'
+ * JSON encoding and decoding functions is also inserted after the references.
+ *
+ * @param json JSON document containing the main schema, schema segments for
+ * the types will be inserted here
+ * @param json_refs map of JSON documents containing the references and function
+ * info related to each type */
+ virtual void generate_json_schema(JSON_Tokenizer& json, map<Type*, JSON_Tokenizer>& json_refs);
};
/**
virtual void set_with_attr(MultiWithAttrib* p_attrib);
virtual WithAttribPath* get_attrib_path();
virtual void set_parent_path(WithAttribPath* p_path);
-
- /** Generates a JSON schema segment for the defined type and inserts it into
- * the JSON schema parameter. */
- void generate_json_schema(JSON_Tokenizer& json);
};
/**
else return get_parent_scope()->get_ass_bySRef(p_ref);
}
- Type *StatementBlock::get_mtc_system_comptype(bool is_system, bool is_connecting)
+ Type *StatementBlock::get_mtc_system_comptype(bool is_system)
{
// return NULL outside test cases
- if (!my_def || ((is_system || !is_connecting) &&
- my_def->get_asstype() != Common::Assignment::A_TESTCASE)) {
+ if (!my_def || my_def->get_asstype() != Common::Assignment::A_TESTCASE)
return 0;
- }
if (is_system) {
Def_Testcase *t_tc = dynamic_cast<Def_Testcase*>(my_def);
if (!t_tc) FATAL_ERROR("StatementBlock::get_mtc_system_comptype()");
}
}
- Type *Statement::chk_comp_ref(Value *p_val, bool allow_mtc, bool allow_system, bool is_connecting)
+ Type *Statement::chk_comp_ref(Value *p_val, bool allow_mtc, bool allow_system)
{
if (!my_sb->get_my_def())
error("Component operation is not allowed in the control part");
p_val->error("A component reference was expected as operand");
return 0;
}
- Type *ret_val = is_connecting ? p_val->get_component_governor() :
- p_val->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE);
+ Type *ret_val = p_val->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE);
if (!ret_val) return 0;
ret_val = ret_val->get_type_refd_last();
switch (ret_val->get_typetype()) {
Type *Statement::chk_conn_endpoint(Value *p_compref, Reference *p_portref,
bool allow_system)
{
- Type *comp_type = chk_comp_ref(p_compref, true, allow_system, true);
+ Type *comp_type = chk_comp_ref(p_compref, true, allow_system);
if (comp_type) {
ComponentTypeBody *comp_body = comp_type->get_CompBody();
p_portref->set_base_scope(comp_body);
void register_def(Definition *p_def);
virtual bool has_ass_withId(const Identifier& p_id);
virtual Common::Assignment* get_ass_bySRef(Ref_simple *p_ref);
- virtual Type *get_mtc_system_comptype(bool is_system, bool is_connecting);
+ virtual Type *get_mtc_system_comptype(bool is_system);
Definition* get_my_def() const { return my_def; }
virtual Ttcn::StatementBlock *get_statementblock_scope();
void set_my_sb(StatementBlock *p_sb, size_t p_index);
* type is a component type). Returns a pointer to the component
* type if available or NULL otherwise. Flags \a allow_mtc and \a
* allow_system indicate whether the mtc or system component
- * reference is acceptable in this context. Flag \a is_connecting
- * is set if the component is part of a 'map' or 'connect' statement. */
- Type *chk_comp_ref(Value *p_val, bool allow_mtc, bool allow_system, bool is_connecting = false);
+ * reference is acceptable in this context. */
+ Type *chk_comp_ref(Value *p_val, bool allow_mtc, bool allow_system);
/** Checks an endpoint for a port connection or mapping. Parameter
* \a p_compref is a component reference, \a p_portref refers to
* a port within the corresponding component type. A pointer to
json.put_next_token(JSON_TOKEN_NAME, "definitions");
json.put_next_token(JSON_TOKEN_OBJECT_START, NULL);
- // insert module names and schemas for types
- modules->add_types_to_json_schema(json);
+ // insert module names and schemas for types; gather references to types and
+ // JSON encoding/decoding function information
+ map<Common::Type*, JSON_Tokenizer> json_refs;
+ modules->generate_json_schema(json, json_refs);
// end of type definitions
json.put_next_token(JSON_TOKEN_OBJECT_END, NULL);
-
- // top-level "anyOf" structure containing references to the types the schema validates
- json.put_next_token(JSON_TOKEN_NAME, "anyOf");
- json.put_next_token(JSON_TOKEN_ARRAY_START, NULL);
-
- // gather type references and JSON encoding/decoding function data
- map<Common::Type*, JSON_Tokenizer> json_refs;
- modules->add_func_to_json_schema(json_refs);
-
- // close schema segments and add them to the main schema
- for (size_t i = 0; i < json_refs.size(); ++i) {
- JSON_Tokenizer* segment = json_refs.get_nth_elem(i);
- segment->put_next_token(JSON_TOKEN_OBJECT_END, NULL);
- insert_schema(json, *segment);
- delete segment;
+
+ if (!json_refs.empty()) {
+ // top-level "anyOf" structure containing references to the types the schema validates
+ // don't insert an empty "anyOf" if there are no references
+ json.put_next_token(JSON_TOKEN_NAME, "anyOf");
+ json.put_next_token(JSON_TOKEN_ARRAY_START, NULL);
+
+ // close schema segments and add them to the main schema
+ for (size_t i = 0; i < json_refs.size(); ++i) {
+ JSON_Tokenizer* segment = json_refs.get_nth_elem(i);
+ segment->put_next_token(JSON_TOKEN_OBJECT_END, NULL);
+ insert_schema(json, *segment);
+ delete segment;
+ }
+ json_refs.clear();
+
+ // end of the "anyOf" structure
+ json.put_next_token(JSON_TOKEN_ARRAY_END, NULL);
}
- json_refs.clear();
-
- // end of the "anyOf" structure
- json.put_next_token(JSON_TOKEN_ARRAY_END, NULL);
// top-level object end
json.put_next_token(JSON_TOKEN_OBJECT_END, NULL);
vs->add_v(v);
}
ret_val = new Value(Value::V_SEQOF, vs);
- if (gov) ret_val->set_my_governor(gov->get_parent_type());
+ if (gov) gov = gov->get_parent_type();
+ if (gov) ret_val->set_my_governor(gov);
break; }
case NAMED_TEMPLATE_LIST: {
NamedValues *nvs = new NamedValues;
nvs->add_nv(nv);
}
ret_val = new Value(Value::V_SEQ, nvs);
- if (gov) ret_val->set_my_governor(gov->get_parent_type());
+ if (gov) gov = gov->get_parent_type();
+ if (gov) ret_val->set_my_governor(gov);
break; }
case INDEXED_TEMPLATE_LIST: {
Values *ivs = new Values(true);
ivs->add_iv(iv);
}
ret_val = new Value(Value::V_SEQOF, ivs);
- if (gov) ret_val->set_my_governor(gov->get_parent_type());
+ if (gov) gov = gov->get_parent_type();
+ if (gov) ret_val->set_my_governor(gov);
break; }
default:
FATAL_ERROR("Template::get_Value()");
COPYRIGHT_STRING "\n\n"
"// Do not edit this file unless you know what you are doing.\n",
is_ttcn ? "TTCN-3" : "ASN.1", user_info);
+
+ if (profiler_enabled) {
+ output->source.includes = mputstr(output->source.includes, "#include \"Profiler.hh\"\n");
+ }
if (output->source.includes != NULL) {
fputs("\n/* Including header files */\n\n", fp);
src = mputprintf(src, /* XERSTUFF XER_encode for union */
"int %s::XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, "
- "unsigned int p_flavor, int p_indent) const\n"
+ "unsigned int p_flavor, int p_indent, embed_values_enc_struct_t*) const\n"
"{\n"
"%s"
" if (%s==union_selection) {\n"
" int encoded_length=(int)p_buf.get_len();\n"
, name
, (use_runtime_2 ? " if (err_descr) return XER_encode_negtest"
- "(err_descr, p_td, p_buf, p_flavor, p_indent);\n" : "")
+ "(err_descr, p_td, p_buf, p_flavor, p_indent, 0);\n" : "")
, unbound_value
);
src = mputprintf(src, " case %s_%s:\n"
" ec_1.set_msg(\"%s': \");\n"
" field_%s->XER_encode(%s_xer_, p_buf, flavor_0, "
- "p_indent + (!p_indent || !omit_tag));\n"
+ "p_indent + (!p_indent || !omit_tag), 0);\n"
" break;\n",
selection_prefix, sdef->elements[i].name,
sdef->elements[i].dispname,
def = mputstr(def,
"int XER_encode_negtest(const Erroneous_descriptor_t* p_err_descr, "
"const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, "
- "unsigned int p_flavor, int p_indent) const;\n");
+ "unsigned int p_flavor, int p_indent, embed_values_enc_struct_t*) const;\n");
src = mputprintf(src, /* XERSTUFF XER_encode for union */
"int %s::XER_encode_negtest(const Erroneous_descriptor_t* p_err_descr, "
"const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, "
- "unsigned int p_flavor, int p_indent) const\n"
+ "unsigned int p_flavor, int p_indent, embed_values_enc_struct_t*) const\n"
"{\n"
" if (%s==union_selection) {\n"
" TTCN_error(\"Attempt to XER-encode an unbound union value.\");\n"
"(\"internal error: erroneous value typedescriptor missing\");\n"
" else err_vals->value->errval->XER_encode("
"*err_vals->value->type_descr->xer, p_buf, flavor_0, "
- "p_indent + (!p_indent || !omit_tag));\n"
+ "p_indent + (!p_indent || !omit_tag), 0);\n"
" }\n"
" }\n"
" } else {\n"
" ec_1.set_msg(\"%s': \");\n"
" if (emb_descr) field_%s->XER_encode_negtest(emb_descr, "
- "%s_xer_, p_buf, flavor_0, p_indent + (!p_indent || !omit_tag));\n"
+ "%s_xer_, p_buf, flavor_0, p_indent + (!p_indent || !omit_tag), 0);\n"
" else field_%s->XER_encode(%s_xer_, p_buf, flavor_0, "
- "p_indent + (!p_indent || !omit_tag));\n"
+ "p_indent + (!p_indent || !omit_tag), 0);\n"
" }\n"
" break;\n",
selection_prefix, sdef->elements[i].name, /* case label */
#endif
src = mputprintf(src, /* XERSTUFF decoder functions for union */
"int %s::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& p_reader,"
- " unsigned int p_flavor)\n"
+ " unsigned int p_flavor, embed_values_dec_struct_t*)\n"
"{\n"
" int e_xer = is_exer(p_flavor);\n"
" int type = 0;\n" /* None */
" ec_2.set_msg(\"%s': \");\n"
" if (%s==union_selection) {\n"
" matched = %d;\n"
- " %s().XER_decode(%s_xer_, p_reader, flavor_1);\n"
+ " %s().XER_decode(%s_xer_, p_reader, flavor_1, 0);\n"
" }\n"
" if (field_%s->is_bound()) break; else clean_up();\n"
" }\n",
src = mputprintf(src,
" %sif (%s::can_start(elem_name, ns_uri, %s_xer_, flavor_1) || (%s_xer_.xer_bits & ANY_ELEMENT)) {\n"
" ec_2.set_msg(\"%s': \");\n"
- " %s%s().XER_decode(%s_xer_, p_reader, flavor_1);\n"
+ " %s%s().XER_decode(%s_xer_, p_reader, flavor_1, 0);\n"
" if (!%s%s().is_bound()) {\n"
" TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG, \"Failed to decode field.\");\n"
" }\n"
src = mputprintf(src,
" %sif ((e_xer && (type==XML_READER_TYPE_END_ELEMENT || !own_tag)) || %s::can_start(elem_name, ns_uri, %s_xer_, flavor_1) || (%s_xer_.xer_bits & ANY_ELEMENT)) {\n"
"empty_xml: ec_2.set_msg(\"%s': \");\n"
- " %s%s().XER_decode(%s_xer_, p_reader, flavor_1);\n"
+ " %s%s().XER_decode(%s_xer_, p_reader, flavor_1, 0);\n"
" if (!%s%s().is_bound()) {\n"
" TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG, \"Failed to decode field.\");\n"
" }\n"
// Do _NOT_ #include "string.hh", it drags in ustring.o, common/Quadruple.o,
// Int.o, ttcn3/PatternString.o, and then the entire AST :(
#include "map.hh"
+#include "ProjectGenHelper.hh"
#include "../common/path.h"
+#include "ttcn3/ttcn3_preparser.h"
+#include "asn1/asn1_preparser.h"
// in makefile.c
void ERROR (const char *fmt, ...);
abort();
}
+ProjectGenHelper& projGenHelper = ProjectGenHelper::Instance();
+
/// Run an XPath query and return an xmlXPathObjectPtr, which must be freed
xmlXPathObjectPtr run_xpath(xmlXPathContextPtr xpathCtx, const char *xpathExpr)
{
}
}
+extern "C" string_list* getExternalLibs(const char* projName)
+{
+ if (!projGenHelper.getZflag()) return NULL;
+ ProjectDescriptor* proj = projGenHelper.getTargetOfProject(projName);
+ if (!proj) return NULL;
+
+ std::vector<const char*> externalLibs;
+ projGenHelper.getExternalLibs(externalLibs);
+
+ if (0 == externalLibs.size()) return NULL;
+
+ struct string_list* head = (struct string_list*)Malloc(sizeof(struct string_list));
+ struct string_list* last_elem = head;
+ struct string_list* tail = head;
+
+ for (size_t i = 0; i < externalLibs.size(); ++i) {
+ tail = last_elem;
+ last_elem->str = mcopystr(externalLibs[i]);
+ last_elem->next = (struct string_list*)Malloc(sizeof(struct string_list));
+ last_elem = last_elem->next;
+ }
+ Free(last_elem);
+ tail->next = NULL;
+ return head;
+}
+
+extern "C" string_list* getExternalLibPathes(const char* projName)
+{
+ if (!projGenHelper.getZflag()) return NULL;
+ ProjectDescriptor* proj = projGenHelper.getTargetOfProject(projName);
+ if (!proj) return NULL;
+
+ std::vector<const char*> externalLibs;
+ projGenHelper.getExternalLibSearchPathes(externalLibs);
+
+ if (0 == externalLibs.size()) return NULL;
+
+ struct string_list* head = (struct string_list*)Malloc(sizeof(struct string_list));
+ struct string_list* last_elem = head;
+ struct string_list* tail = head;
+
+ for (size_t i = 0; i < externalLibs.size(); ++i) {
+ tail = last_elem;
+ last_elem->str = mcopystr(externalLibs[i]);
+ last_elem->next = (struct string_list*)Malloc(sizeof(struct string_list));
+ last_elem = last_elem->next;
+ }
+ Free(last_elem);
+ tail->next = NULL;
+ return head;
+}
+
+extern "C" string_list* getRefWorkingDirs(const char* projName)
+{
+ if (!projGenHelper.getZflag()) return NULL;
+ ProjectDescriptor* proj = projGenHelper.getTargetOfProject(projName);
+ if (!proj) FATAL_ERROR("Project \"%s\" was not found in the project list", projName);
+
+ struct string_list* head = (struct string_list*)Malloc(sizeof(struct string_list));
+ struct string_list* last_elem = head;
+ struct string_list* tail = head;
+ last_elem->str = NULL;
+ last_elem->next = NULL;
+ for (size_t i = 0; i < proj->numOfRefProjWorkingDirs(); ++i) {
+ tail = last_elem;
+ last_elem->str = mcopystr(proj->getRefProjWorkingDir(i).c_str());
+ last_elem->next = (struct string_list*)Malloc(sizeof(struct string_list));
+ last_elem = last_elem->next;
+ }
+ Free(last_elem);
+ tail->next = NULL;
+ return head;
+}
+
+extern "C" string2_list* getLinkerLibs(const char* projName)
+{
+
+ if (!projGenHelper.getZflag()) return NULL;
+ if (1 == projGenHelper.numOfProjects() || 0 == projGenHelper.numOfLibs()){
+ return NULL; //no library
+ }
+ ProjectDescriptor* projLib = projGenHelper.getTargetOfProject(projName);
+ if (!projLib) FATAL_ERROR("Project \"%s\" was not found in the project list", projName);
+
+ struct string2_list* head = (struct string2_list*)Malloc(sizeof(struct string2_list));
+ struct string2_list* last_elem = head;
+ struct string2_list* tail = head;
+ last_elem->next = NULL;
+ last_elem->str1 = NULL;
+ last_elem->str2 = NULL;
+ for (std::map<std::string, ProjectDescriptor>::const_iterator it = projGenHelper.getHead();
+ it != projGenHelper.getEnd(); ++it) {
+ if ((it->second).isLibrary()) {
+ if (!(it->second).getLinkingStrategy() &&
+ !projLib->hasLinkerLibTo((it->second).getProjectName())) { // static linked library
+ continue;
+ }
+ std::string relPath = projLib->setRelativePathTo((it->second).getProjectAbsWorkingDir());
+ if (relPath == std::string(".")) {
+ continue; // the relpath shows to itself
+ }
+ tail = last_elem;
+ last_elem->str1 = mcopystr(relPath.c_str());
+ last_elem->str2 = mcopystr((it->second).getTargetExecName().c_str());
+ last_elem->next = (struct string2_list*)Malloc(sizeof(struct string2_list));
+ last_elem = last_elem->next;
+ }
+ }
+ tail->next = NULL;
+ Free(last_elem);
+
+ if (head->str1 && head->str2)
+ return head;
+ else
+ return NULL;
+}
+
+extern "C" const char* getLibFromProject(const char* projName)
+{
+ if (!projGenHelper.getZflag()) return NULL;
+ ProjectDescriptor* lib = projGenHelper.getTargetOfProject(projName);
+ if (lib) return lib->getTargetExecName().c_str();
+ return NULL;
+}
+
+extern "C" void erase_libs() {
+ projGenHelper.cleanUp();
+}
+
+extern "C" void print_libs() {
+ projGenHelper.print();
+}
+
+
+extern "C" boolean hasSubProject(const char* projName) {
+ if (!projGenHelper.getZflag()) return FALSE;
+ if (projGenHelper.getHflag())
+ return static_cast<boolean>(projGenHelper.hasReferencedProject());
+ else if(std::string(projName) == projGenHelper.getToplevelProjectName())
+ return static_cast<boolean>(projGenHelper.hasReferencedProject());
+ else
+ return FALSE;
+}
+
+extern "C" boolean hasExternalLibrary(const char* libName, const char* projName) {
+ if (!projGenHelper.getZflag()) return FALSE;
+ ProjectDescriptor* projLib = projGenHelper.getTargetOfProject(projName);
+ if (projLib && projLib->hasLinkerLib(libName))
+ return TRUE;
+ else
+ return FALSE;
+}
+
+extern "C" boolean isTopLevelExecutable(const char* projName) {
+ if (!projGenHelper.getZflag()) return false;
+ ProjectDescriptor* proj = projGenHelper.getTargetOfProject(projName);
+ if (projGenHelper.getToplevelProjectName() != std::string(projName)) return FALSE;
+ if (proj && proj->isLibrary())
+ return FALSE;
+ else
+ return TRUE;
+}
+
+extern "C" boolean isDynamicLibrary(const char* key) {
+ if (!projGenHelper.getZflag()) return false;
+ ProjectDescriptor* proj = projGenHelper.getProjectDescriptor(key);
+ if (proj) return proj->getLinkingStrategy();
+ FATAL_ERROR("Library \"%s\" was not found", key);
+ return false;
+}
+
+extern "C" const char* getTPDFileName(const char* projName) {
+ if (!projGenHelper.getZflag()) return NULL;
+ ProjectDescriptor* proj = projGenHelper.getTargetOfProject(projName);
+ if (proj) return proj->getTPDFileName().c_str();
+ FATAL_ERROR("TPD file name to project \"%s\" was not found", projName);
+}
+
+extern "C" const char* getPathToRootDir(const char* projName) {
+ if (!projGenHelper.getZflag()) return NULL;
+ ProjectDescriptor* proj = projGenHelper.getTargetOfProject(projName);
+ const char* rootDir = projGenHelper.getRootDirOS(projName).c_str();
+ if (proj && rootDir) {
+ return rootDir;
+ }
+ FATAL_ERROR("Project \"%s\": no relative path was found to top directory at OS level.", projName);
+}
+
+extern "C" const char* findLibraryPath(const char* libraryName, const char* projName)
+{
+ if (!projGenHelper.getZflag()) return NULL;
+ ProjectDescriptor* projLib = projGenHelper.getTargetOfProject(projName);
+ if (!projLib) FATAL_ERROR("Project \"%s\" was not found in the project list", projName);
+ ProjectDescriptor* libLib = projGenHelper.getProjectDescriptor(libraryName);
+ if (!libLib) return NULL;
+ std::string str = projLib->setRelativePathTo(libLib->getProjectAbsWorkingDir());
+ size_t refIndex = projLib->getLibSearchPathIndex(libLib->getProjectName());
+ if (refIndex > projLib->numOfLibSearchPaths()) return NULL;
+ projLib->setLibSearchPath(refIndex, str);
+ return projLib->getLibSearchPath(libLib->getProjectName());
+}
+
+extern "C" const char* findLibraryName(const char* libraryName, const char* projName)
+{
+ if (!projGenHelper.getZflag()) return NULL;
+ ProjectDescriptor* projLib = projGenHelper.getTargetOfProject(projName);
+ if (!projLib) FATAL_ERROR("Project \"%s\" was not found in the project list", projName);
+ ProjectDescriptor* libLib = projGenHelper.getProjectDescriptor(libraryName);
+ if (!libLib) return NULL;
+ for (size_t i = 0; i < projLib->numOfReferencedProjects(); ++i) {
+ const std:: string refProjName = projLib->getReferencedProject(i);
+ ProjectDescriptor* refLib = projGenHelper.getTargetOfProject(refProjName.c_str());
+ if (refLib->getTargetExecName() == std::string(libraryName))
+ return libraryName;
+ }
+ return NULL;
+}
+
+extern "C" boolean isTtcn3ModuleInLibrary(const char* moduleName)
+{
+ if (!projGenHelper.getZflag()) return FALSE;
+ return (boolean)projGenHelper.isTtcn3ModuleInLibrary(moduleName);
+}
+
+extern "C" boolean isAsn1ModuleInLibrary(const char* moduleName)
+{
+ if (!projGenHelper.getZflag()) return FALSE;
+ return (boolean)projGenHelper.isAsn1ModuleInLibrary(moduleName);
+}
+
+extern "C" boolean isSourceFileInLibrary(const char* fileName)
+{
+ if (!projGenHelper.getZflag()) return FALSE;
+ return (boolean)projGenHelper.isSourceFileInLibrary(fileName);
+}
+
+extern "C" boolean isHeaderFileInLibrary(const char* fileName)
+{
+ if (!projGenHelper.getZflag()) return FALSE;
+ return (boolean)projGenHelper.isHeaderFileInLibrary(fileName);
+}
+
+extern "C" boolean isTtcnPPFileInLibrary(const char* fileName)
+{
+ if (!projGenHelper.getZflag()) return FALSE;
+ return (boolean)projGenHelper.isTtcnPPFileInLibrary(fileName);
+}
+
+
+extern "C" boolean buildObjects(const char* projName, boolean add_referenced)
+{
+ if (!projGenHelper.getZflag()) return FALSE;
+ if (projGenHelper.getHflag()) return FALSE;
+ if (add_referenced) return FALSE;
+ ProjectDescriptor* desc =projGenHelper.getTargetOfProject(projName);
+ if (desc && desc->isLibrary()) return FALSE;
+ return TRUE;
+}
+
+void append_to_library_list (const char* prjName,
+ const XPathContext& xpathCtx,
+ const char *actcfg)
+{
+ if (!projGenHelper.getZflag()) return;
+
+ char *exeXpath = mprintf(
+ "/TITAN_Project_File_Information/Configurations/Configuration[@name='%s']"
+ "/ProjectProperties/MakefileSettings/targetExecutable/text()",
+ actcfg);
+ XPathObject exeObj(run_xpath(xpathCtx, exeXpath));
+ Free(exeXpath);
+ std::string lib_name;
+ if (exeObj->nodesetval && exeObj->nodesetval->nodeNr > 0) {
+ const char* target_executable = (const char*)exeObj->nodesetval->nodeTab[0]->content;
+ autostring target_exe_dir(get_dir_from_path(target_executable));
+ autostring target_exe_file(get_file_from_path(target_executable));
+ lib_name = target_exe_file;
+ ProjectDescriptor* projDesc = projGenHelper.getTargetOfProject(prjName);
+ if (projDesc) {
+ projDesc->setTargetExecName(lib_name.c_str());
+ }
+ }
+}
+
// data structures and functions to manage excluded folders/files
-map<cstring, void> excluded_files;
+map<cstring, const char> excluded_files;
-boolean is_excluded_file(const cstring& path) {
- return excluded_files.has_key(path);
+boolean is_excluded_file(const cstring& path, const char* project) {
+ if (!excluded_files.has_key(path)) return false;
+ const char* proj = excluded_files[path];
+ if (0 == strcmp(project, proj)) return true;
+ return false;
}
vector<const char> excluded_folders;
seen_tpd_files.clear();
}
+const char* get_act_config(struct string2_list* cfg, const char* project_name) {
+ while (cfg && cfg->str1 && project_name) {
+ if (!strcmp(cfg->str1, project_name)) return cfg->str2;
+ cfg = cfg->next;
+ }
+ return NULL;
+}
+
static tpd_result process_tpd_internal(const char *p_tpd_name, const char *actcfg,
const char *file_list_path, int *p_argc, char ***p_argv,
- int *p_optind, char **p_ets_name,
+ int *p_optind, char **p_ets_name, char **p_project_name,
boolean *p_gflag, boolean *p_sflag, boolean *p_cflag, boolean *p_aflag, boolean *preprocess,
boolean *p_Rflag, boolean *p_lflag, boolean *p_mflag, boolean *p_Pflag,
boolean *p_Lflag, boolean recursive, boolean force_overwrite, boolean gen_only_top_level,
const char *output_file, char** abs_work_dir_p, struct string_list* sub_project_dirs,
const char* program_name, FILE* prj_graph_fp, struct string2_list* create_symlink_list, struct string_list* ttcn3_prep_includes,
- struct string_list* ttcn3_prep_defines, struct string_list* prep_includes, struct string_list* prep_defines,
- 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,
+ struct string_list* ttcn3_prep_defines, struct string_list* ttcn3_prep_undefines, struct string_list* prep_includes,
+ 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, 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,
- char** generatorCommandOutput, struct string2_list* target_placement_list, boolean prefix_workdir, struct string2_list* run_command_list,
- map<cstring, int>& seen_tpd_files);
+ boolean *p_Zflag, boolean *p_Hflag, char** generatorCommandOutput, struct string2_list* target_placement_list, boolean prefix_workdir,
+ struct string2_list* run_command_list, map<cstring, int>& seen_tpd_files, struct string2_list* required_configs);
extern "C" tpd_result process_tpd(const char *p_tpd_name, const char *actcfg,
const char *file_list_path, int *p_argc, char ***p_argv,
- int *p_optind, char **p_ets_name,
+ int *p_optind, char **p_ets_name, char **p_project_name,
boolean *p_gflag, boolean *p_sflag, boolean *p_cflag, boolean *p_aflag, boolean *preprocess,
boolean *p_Rflag, boolean *p_lflag, boolean *p_mflag, boolean *p_Pflag,
boolean *p_Lflag, boolean recursive, boolean force_overwrite, boolean gen_only_top_level,
const char *output_file, char** abs_work_dir_p, struct string_list* sub_project_dirs,
const char* program_name, FILE* prj_graph_fp, struct string2_list* create_symlink_list, struct string_list* ttcn3_prep_includes,
- struct string_list* ttcn3_prep_defines, struct string_list* prep_includes, struct string_list* prep_defines,
- 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,
+ struct string_list* ttcn3_prep_defines, struct string_list* ttcn3_prep_undefines, struct string_list* prep_includes,
+ 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, 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,
- char** generatorCommandOutput, struct string2_list* target_placement_list, boolean prefix_workdir, struct string2_list* run_command_list) {
+ string_list* linkerlibs, string_list* additionalObjects, string_list* linkerlibsearchp, boolean Vflag, boolean Dflag, boolean *p_Zflag,
+ boolean *p_Hflag, char** generatorCommandOutput, struct string2_list* target_placement_list, boolean prefix_workdir,
+ struct string2_list* run_command_list, struct string2_list* required_configs) {
map<cstring, int> seen_tpd_files;
+ projGenHelper.setZflag(*p_Zflag);
+ projGenHelper.setWflag(prefix_workdir);
+ projGenHelper.setHflag(*p_Hflag);
tpd_result success = process_tpd_internal(p_tpd_name,
- actcfg, file_list_path, p_argc, p_argv, p_optind, p_ets_name,
+ actcfg, file_list_path, p_argc, p_argv, p_optind, p_ets_name, p_project_name,
p_gflag, p_sflag, p_cflag, p_aflag, preprocess,
p_Rflag, p_lflag, p_mflag, p_Pflag,
p_Lflag, recursive, force_overwrite, gen_only_top_level,
output_file, abs_work_dir_p, sub_project_dirs,
program_name, prj_graph_fp, create_symlink_list, ttcn3_prep_includes,
- ttcn3_prep_defines, prep_includes, prep_defines,
- p_csflag, p_quflag, p_dsflag, cxxcompiler,
+ ttcn3_prep_defines, ttcn3_prep_undefines, prep_includes, prep_defines,
+ 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, solspeclibs, sol8speclibs,
linuxspeclibs, freebsdspeclibs, win32speclibs, ttcn3prep,
- linkerlibs, additionalObjects, linkerlibsearchp, Vflag, Dflag,
- generatorCommandOutput, target_placement_list, prefix_workdir, run_command_list, seen_tpd_files);
+ linkerlibs, additionalObjects, linkerlibsearchp, Vflag, Dflag, p_Zflag,
+ p_Hflag, generatorCommandOutput, target_placement_list, prefix_workdir,
+ run_command_list, seen_tpd_files, required_configs);
+
+ if (TPD_FAILED == success) exit(EXIT_FAILURE);
+
+ if (false == projGenHelper.sanityCheck()) {
+ fprintf (stderr, "makefilegen exits\n");
+ exit(EXIT_FAILURE);
+ }
+
+ projGenHelper.generateRefProjectWorkingDirsTo(*p_project_name);
for (size_t i = 0, num = seen_tpd_files.size(); i < num; ++i) {
const cstring& key = seen_tpd_files.get_nth_key(i);
// it must nevertheless make a copy on the heap via mcopystr().
static tpd_result process_tpd_internal(const char *p_tpd_name, const char *actcfg,
const char *file_list_path, int *p_argc, char ***p_argv,
- int *p_optind, char **p_ets_name,
+ int *p_optind, char **p_ets_name, char **p_project_name,
boolean *p_gflag, boolean *p_sflag, boolean *p_cflag, boolean *p_aflag, boolean *preprocess,
boolean *p_Rflag, boolean *p_lflag, boolean *p_mflag, boolean *p_Pflag,
boolean *p_Lflag, boolean recursive, boolean force_overwrite, boolean gen_only_top_level,
const char *output_file, char** abs_work_dir_p, struct string_list* sub_project_dirs,
const char* program_name, FILE* prj_graph_fp, struct string2_list* create_symlink_list, struct string_list* ttcn3_prep_includes,
- struct string_list* ttcn3_prep_defines, struct string_list* prep_includes, struct string_list* prep_defines,
- 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,
+ struct string_list* ttcn3_prep_defines, struct string_list* ttcn3_prep_undefines, struct string_list* prep_includes,
+ 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, 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,
- char** generatorCommandOutput, struct string2_list* target_placement_list, boolean prefix_workdir, struct string2_list* run_command_list,
- map<cstring, int>& seen_tpd_files)
+ string_list* linkerlibs, string_list* additionalObjects, string_list* linkerlibsearchp, boolean Vflag, boolean Dflag, boolean *p_Zflag,
+ boolean *p_Hflag, char** generatorCommandOutput, struct string2_list* target_placement_list, boolean prefix_workdir,
+ struct string2_list* run_command_list, map<cstring, int>& seen_tpd_files, struct string2_list* required_configs)
{
+ tpd_result result = TPD_SUCCESS;
// read-only non-pointer aliases
//char** const& local_argv = *p_argv;
int const& local_argc = *p_argc;
autostring tpd_dir(get_dir_from_path(p_tpd_name));
autostring abs_tpd_dir(get_absolute_dir(tpd_dir, NULL));
-
+ if (NULL == (const char*)abs_tpd_dir) {
+ ERROR("absolut TPD directory could not be retreaved from %s", (const char*)tpd_dir);
+ return TPD_FAILED;
+ }
autostring tpd_filename(get_file_from_path(p_tpd_name));
autostring abs_tpd_name(compose_path_name(abs_tpd_dir, tpd_filename));
} // next FolderResource
}
- if (actcfg == NULL)
+ /////////////////////////////////////////////////////////////////////////////
{
+ char *projectNameXpath = mprintf("/TITAN_Project_File_Information/ProjectName/text()");
+ XPathObject projectNameObj(run_xpath(xpathCtx, projectNameXpath));
+ Free(projectNameXpath);
+ if (projectNameObj->nodesetval && projectNameObj->nodesetval->nodeNr > 0) {
+ *p_project_name = mcopystr((const char*)projectNameObj->nodesetval->nodeTab[0]->content);
+ projGenHelper.addTarget(*p_project_name);
+ projGenHelper.setToplevelProjectName(*p_project_name);
+ ProjectDescriptor* projDesc = projGenHelper.getTargetOfProject(*p_project_name);
+ if (projDesc) projDesc->setProjectAbsTpdDir((const char*)abs_tpd_dir);
+ }
+ }
+ /////////////////////////////////////////////////////////////////////////////
+
+ if (!actcfg) {
+ actcfg = get_act_config(required_configs,*p_project_name);
+ }
+ if (actcfg == NULL) {
// Find out the active config
XPathObject activeConfig(run_xpath(xpathCtx,
"/TITAN_Project_File_Information/ActiveConfiguration/text()"));
return TPD_FAILED;
}
}
-
- /////////////////////////////////////////////////////////////////////////////
// working directory stuff
autostring workdir;
{
const char *real_workdir = folders[workdir]; // This is relative to the location of the tpd file
excluded_folders.add(real_workdir); // excluded by convention
+ autostring proj_abs_workdir;
+
autostring abs_workdir;
// If -D flag was specified then we ignore the workdir
// in the TPD (the current dir is considered the work dir).
break;
default:
if (recursive || local_argc != 0) { // we only want to create workdir if necessary
- printf("Working directory `%s' in project `%s' does not exist, trying to create it...\n", real_workdir, (const char*)abs_tpd_dir);
+ fprintf(stderr, "Working directory `%s' in project `%s' does not exist, trying to create it...\n",
+ real_workdir, (const char*)abs_tpd_dir);
int rv = mkdir(real_workdir, 0755);
if (rv) ERROR("Could not create working directory, mkdir() failed: %s", strerror(errno));
else printf("Working directory created\n");
if (hasWorkDir) { //we created working directory, or its already been created (from a parent makefilegen process maybe)
*abs_work_dir_p = get_absolute_dir(real_workdir, abs_tpd_dir);
abs_workdir = (mcopystr(*abs_work_dir_p));
+ proj_abs_workdir = mcopystr(*abs_work_dir_p);
}
}
+
+ if (Dflag) { // the path to subproject working dir is needed to find the linkerlibsearchpath
+ proj_abs_workdir = compose_path_name(abs_tpd_dir, real_workdir);
+ }
+
+ ProjectDescriptor* projDesc = projGenHelper.getTargetOfProject(*p_project_name);
+ if (projDesc) {
+ projDesc->setProjectAbsWorkingDir((const char*)proj_abs_workdir);
+ projDesc->setProjectWorkingDir(real_workdir);
+ projDesc->setTPDFileName(p_tpd_name);
+ }
+
/////////////////////////////////////////////////////////////////////////////
// Gather the excluded folders in the active config
xmlNodePtr curnode = nodes->nodeTab[i];
cstring aa((const char*)curnode->content);
- excluded_files.add(aa, 0);
+ excluded_files.add(aa, *p_project_name);
}
}
}
cstring cpath(path);
- if (!is_excluded_file(cpath) && !is_excluded_folder(path)) {
+ if (!is_excluded_file(cpath, *p_project_name) && !is_excluded_folder(path)) {
// relativeURI wins over rawURI
char *ruri = uri ? mcopystr(uri) : cook(raw, path_vars);
-
if (files.has_key(cpath)) {
ERROR("A FileResource %s must be unique!", (const char*)cpath);
- } else {
+ }
+ else {
+ const char* file_path = ruri;
+ expstring_t rel_file_dir = get_dir_from_path(file_path);
+ expstring_t file_name = get_file_from_path(file_path);
+ expstring_t abs_dir_path = get_absolute_dir(rel_file_dir, abs_tpd_dir);
+ expstring_t abs_file_name = compose_path_name(abs_dir_path, file_name);
+ if (abs_file_name != NULL) {
+ if (get_path_status(abs_file_name) == PS_FILE) {
+ FILE *fp = fopen(abs_file_name, "r");
+ if (fp != NULL) {
+ char* ttcn3_module_name;
+ if (is_ttcn3_module(abs_file_name, fp, &ttcn3_module_name)) {
+ projGenHelper.addTtcn3ModuleToProject(*p_project_name, ttcn3_module_name);
+ }
+ Free(ttcn3_module_name);
+ char* asn1_module_name;
+ if (is_asn1_module(abs_file_name, fp, &asn1_module_name)) {
+ projGenHelper.addAsn1ModuleToProject(*p_project_name, asn1_module_name);
+ }
+ Free(asn1_module_name);
+ if (projGenHelper.isCPPSourceFile(file_name)) {
+ projGenHelper.addUserSourceToProject(*p_project_name, file_name);
+ }
+ if (projGenHelper.isCPPHeaderFile(file_name)) {
+ projGenHelper.addUserHeaderToProject(*p_project_name, file_name);
+ }
+ if (projGenHelper.isTtcnPPFile(file_name)) {
+ projGenHelper.addTtcnPPToProject(*p_project_name, file_name);
+ }
+ }
+ fclose(fp);
+ }
+ }
files.add(cpath, ruri); // relativeURI to the TPD location
{ // set the *preprocess value if .ttcnpp file was found
const size_t ttcnpp_extension_len = 7; // ".ttcnpp"
*preprocess = TRUE;
}
}
+ Free(rel_file_dir);
+ Free(file_name);
+ Free(abs_dir_path);
+ Free(abs_file_name);
}
}
} // next FileResource
// Check options
xsdbool2boolean(xpathCtx, actcfg, "useAbsolutePath", p_aflag);
xsdbool2boolean(xpathCtx, actcfg, "GNUMake", p_gflag);
+ if (*p_Zflag) *p_lflag = FALSE;
xsdbool2boolean(xpathCtx, actcfg, "dynamicLinking", p_lflag);
xsdbool2boolean(xpathCtx, actcfg, "functiontestRuntime", p_Rflag);
xsdbool2boolean(xpathCtx, actcfg, "singleMode", p_sflag);
xsdbool2boolean(xpathCtx, actcfg, "suppressWarnings", p_swflag);
xsdbool2boolean(xpathCtx, actcfg, "outParamBoundness", p_Yflag);
+ projDesc = projGenHelper.getTargetOfProject(*p_project_name);
+ if (projDesc) projDesc->setLinkingStrategy(*p_lflag);
+
// Extract the "incremental dependencies" option
{
boolean incremental_deps = TRUE;
// Extract the default target option
// if it is not defined as a command line argument
if (!(*p_Lflag)) {
- char *defTargetXpath = mprintf(
+ expstring_t defTargetXpath = mprintf(
"/TITAN_Project_File_Information/Configurations/Configuration[@name='%s']"
"/ProjectProperties/MakefileSettings/defaultTarget/text()",
actcfg);
" The available targets are: 'executable', 'library'", content);
}
}
+ ProjectDescriptor* projDesc = projGenHelper.getTargetOfProject(*p_project_name);
+ if (projDesc) projDesc->setLibrary(*p_Lflag);
}
// Executable name (don't care unless top-level invocation)
}
}
}
+ {
+ //TTCN3preprocessorUnDefines
+ char *ttcn3preUndefinesXpath = mprintf(
+ "/TITAN_Project_File_Information/Configurations/Configuration[@name='%s']"
+ "/ProjectProperties/MakefileSettings/TTCN3preprocessorUndefines/listItem/text()",
+ actcfg);
+ XPathObject ttcn3preUndefinesObj(run_xpath(xpathCtx, ttcn3preUndefinesXpath));
+ Free(ttcn3preUndefinesXpath);
+
+ xmlNodeSetPtr nodes = ttcn3preUndefinesObj->nodesetval;
+
+ if (nodes) for (int i = 0; i < nodes->nodeNr; ++i) {
+ const char* content = (const char*)ttcn3preUndefinesObj->nodesetval->nodeTab[i]->content;
+
+ // add includes to the end of list
+ if (ttcn3_prep_undefines) {
+ // go to last element
+ struct string_list* last_elem = ttcn3_prep_undefines;
+ while (last_elem->next) last_elem = last_elem->next;
+ // add string to last element if empty or create new last element and add it to that
+ if (last_elem->str) {
+ last_elem->next = (struct string_list*)Malloc(sizeof(struct string_list));
+ last_elem = last_elem->next;
+ last_elem->next = NULL;
+ }
+ last_elem->str = mcopystr(content);
+ }
+ }
+ }
+
{
//preprocessorIncludes
char *preincludesXpath = mprintf(
}
}
}
+ {
+ //preprocessorUnDefines
+ char *preUndefinesXpath = mprintf(
+ "/TITAN_Project_File_Information/Configurations/Configuration[@name='%s']"
+ "/ProjectProperties/MakefileSettings/preprocessorUndefines/listItem/text()",
+ actcfg);
+ XPathObject preUndefinesObj(run_xpath(xpathCtx, preUndefinesXpath));
+ Free(preUndefinesXpath);
+
+ xmlNodeSetPtr nodes = preUndefinesObj->nodesetval;
+
+ if (nodes) for (int i = 0; i < nodes->nodeNr; ++i) {
+ const char* content = (const char*)preUndefinesObj->nodesetval->nodeTab[i]->content;
+
+ // add includes to the end of list
+ if (prep_undefines) {
+ // go to last element
+ struct string_list* last_elem = prep_undefines;
+ while (last_elem->next) last_elem = last_elem->next;
+ // add string to last element if empty or create new last element and add it to that
+ if (last_elem->str) {
+ last_elem->next = (struct string_list*)Malloc(sizeof(struct string_list));
+ last_elem = last_elem->next;
+ last_elem->next = NULL;
+ }
+ last_elem->str = mcopystr(content);
+ }
+ }
+ }
{
char *cxxCompilerXpath = mprintf(
"/TITAN_Project_File_Information/Configurations/Configuration[@name='%s']"
}
}
{
+ //The project name needed the hierarchical projects
+ char* prjNameStr = 0;
+ char *prjNameStrXpath = mprintf("/TITAN_Project_File_Information/ProjectName/text()");
+ XPathObject prjName(run_xpath(xpathCtx, prjNameStrXpath));
+ if (prjName->nodesetval && prjName->nodesetval->nodeNr == 1) {
+ prjNameStr = (char*)prjName->nodesetval->nodeTab[0]->content;
+ }
+ Free(prjNameStrXpath);
+ append_to_library_list (prjNameStr, xpathCtx, actcfg);
+
//linkerLibraries
char *linkerlibsXpath = mprintf(
"/TITAN_Project_File_Information/Configurations/Configuration[@name='%s']"
}
replacechar(&content);
last_elem->str = content;
+
+ ProjectDescriptor* projDesc = projGenHelper.getTargetOfProject(*p_project_name);
+ if (projDesc) projDesc->addToLinkerLibs(last_elem->str);
}
}
}
}
replacechar(&content);
last_elem->str = content;
+
+ ProjectDescriptor* projDesc = projGenHelper.getTargetOfProject(*p_project_name);
+ if (projDesc) projDesc->addToLibSearchPaths(last_elem->str);
}
}
}
}
}
+// collect the required configurations
+ {
+ if (required_configs) {
+ char* cfgReqsXpath(mprintf(
+ "/TITAN_Project_File_Information/Configurations/Configuration[@name='%s']"
+ "/ProjectProperties/ConfigurationRequirements/configurationRequirement",
+ actcfg));
+ XPathObject reqcfgObjects(run_xpath(xpathCtx, cfgReqsXpath));
+ Free (cfgReqsXpath);
+ xmlNodeSetPtr configs = reqcfgObjects->nodesetval;
+ if (configs) for (int i = 0; i < configs->nodeNr; ++i) {
+ xmlNodePtr curNodePtr = configs->nodeTab[i]->children;
+ const char* projectName = NULL;
+ const char* reqConfig = NULL;
+ while(curNodePtr) {
+ if (!strcmp((const char*)curNodePtr->name, "projectName")) {
+ projectName = (const char*)curNodePtr->children->content;
+ }
+ if (!strcmp((const char*)curNodePtr->name, "rerquiredConfiguration") || // backward compatibility
+ !strcmp((const char*)curNodePtr->name, "requiredConfiguration")) {
+ reqConfig = (const char*)curNodePtr->children->content;
+ }
+ curNodePtr = curNodePtr->next;
+ }
+ struct string2_list* last_elem = required_configs;
+ bool duplicate = false;
+ while (last_elem->next) {
+ if (!strcmp(last_elem->str1, projectName) && !strcmp(last_elem->str2, reqConfig)) {
+ duplicate = true;
+ }
+ else if (!strcmp(last_elem->str1, projectName) && strcmp(last_elem->str2, reqConfig)) {
+ ERROR("Required configuration is inconsistent : Project '%s' cannot have 2 "
+ "different configuration '%s' '%s'",
+ last_elem->str1, last_elem->str2, reqConfig);
+ result = TPD_FAILED;
+ }
+ last_elem = last_elem->next;
+ }
+ // add string to last element if empty or create new last element and add it to that
+ if (last_elem->str1 && !duplicate) {
+ if (strcmp(last_elem->str1, projectName) || strcmp(last_elem->str2, reqConfig)) {
+ last_elem->next = (struct string2_list*)Malloc(sizeof(struct string2_list));
+ last_elem = last_elem->next;
+ last_elem->next = NULL;
+ }
+ else {
+ duplicate = true;
+ }
+ }
+ if (!duplicate) {
+ last_elem->str1 = mcopystr(projectName);
+ last_elem->str2 = mcopystr(reqConfig);
+ }
+ }
+ }
+ }
+
// Referenced projects
{
XPathObject subprojects(run_xpath(xpathCtx,
if (name && projectLocationURI) { // collected both
// see if there is a specified configuration for the project
- const char *my_actcfg = NULL;
- autostring req_xpath(mprintf(
- "/TITAN_Project_File_Information/Configurations/Configuration[@name='%s']"
- "/ProjectProperties/ConfigurationRequirements/configurationRequirement"
- "/projectName[text()='%s']"
- // Up to this point, we selected the projectName node which contains
- // the name of the subproject. But we want its sibling.
- // So we go up one and down the other path.
- "/parent::*/rerquiredConfiguration/text()",
- //Yes, it's rerquiredConfiguration; the Designer misspells it :(
- actcfg, name));
- XPathObject reqcfgObj(run_xpath(xpathCtx, req_xpath));
- if (reqcfgObj->nodesetval && reqcfgObj->nodesetval->nodeNr == 1) {
- my_actcfg = (const char*)reqcfgObj->nodesetval->nodeTab[0]->content;
- }
+ ProjectDescriptor* projDesc = projGenHelper.getTargetOfProject(*p_project_name);
+ if (projDesc) projDesc->addToReferencedProjects(name);
+
+ const char *my_actcfg = NULL;
int my_argc = 0;
char *my_args[] = { NULL };
char **my_argv = my_args + 0;
int my_optind = 0;
boolean my_gflag = *p_gflag, my_aflag = *p_aflag, my_cflag = *p_cflag, // pass down
- my_Rflag = *p_Rflag, my_Pflag = *p_Pflag,
+ my_Rflag = *p_Rflag, my_Pflag = *p_Pflag, my_Zflag = *p_Zflag, my_Hflag = *p_Hflag,
my_sflag = 0, my_Lflag = 0, my_lflag = 0, my_mflag = 0, my_csflag = 0,
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_swflag = 0, my_Yflag = 0;
char *my_ets = NULL;
-
+ char *my_proj_name = NULL;
autostring abs_projectLocationURI(
compose_path_name(abs_tpd_dir, projectLocationURI));
char* sub_proj_abs_work_dir = NULL;
+
tpd_result success = process_tpd_internal((const char*)abs_projectLocationURI,
- my_actcfg, file_list_path, &my_argc, &my_argv, &my_optind, &my_ets,
+ my_actcfg, file_list_path, &my_argc, &my_argv, &my_optind, &my_ets, &my_proj_name,
&my_gflag, &my_sflag, &my_cflag, &my_aflag, preprocess, &my_Rflag, &my_lflag,
&my_mflag, &my_Pflag, &my_Lflag, recursive, force_overwrite, gen_only_top_level, NULL, &sub_proj_abs_work_dir,
- sub_project_dirs, program_name, prj_graph_fp, create_symlink_list, ttcn3_prep_includes, ttcn3_prep_defines, prep_includes, prep_defines, &my_csflag,
+ 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, &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, solspeclibs, sol8speclibs, linuxspeclibs, freebsdspeclibs, win32speclibs,
- ttcn3prep, linkerlibs, additionalObjects, linkerlibsearchp, Vflag, FALSE, NULL, NULL, prefix_workdir, run_command_list, seen_tpd_files);
+ ttcn3prep, linkerlibs, additionalObjects, linkerlibsearchp, Vflag, FALSE, &my_Zflag,
+ &my_Hflag, NULL, NULL, prefix_workdir, run_command_list, seen_tpd_files, required_configs);
+
autostring sub_proj_abs_work_dir_as(sub_proj_abs_work_dir); // ?!
if (success == TPD_SUCCESS) {
-
+ my_actcfg = get_act_config(required_configs, my_proj_name);
if (recursive) { // call ttcn3_makefilegen on referenced project's tpd file
// -r is not needed any more because top level process traverses all projects recursively
expstring_t command = mprintf("%s -cVD", program_name);
if (*p_Rflag) command = mputc(command, 'R');
if (*p_lflag) command = mputc(command, 'l');
if (*p_mflag) command = mputc(command, 'm');
+ if (*p_Zflag) command = mputc(command, 'Z');
+ if (*p_Hflag) command = mputc(command, 'H');
command = mputstr(command, " -t ");
command = mputstr(command, (const char*)abs_projectLocationURI);
if (my_actcfg) {
Free(my_argv); // free the array; we keep the pointers
Free(my_ets);
+ Free(my_proj_name);
}
else if (success == TPD_FAILED) {
ERROR("Failed to process %s", (const char*)abs_projectLocationURI);
xmlCleanupParser();
// ifdef debug
xmlMemoryDump();
- return TPD_SUCCESS;
+ return result;
}
struct string2_list* next;
};
+#ifdef __cplusplus
+extern "C"
+#endif
+boolean isTopLevelExecutable(const char* projName);
+
+#ifdef __cplusplus
+extern "C"
+#endif
+boolean isDynamicLibrary(const char* key);
+
+#ifdef __cplusplus
+extern "C"
+#endif
+const char* findLibraryPath(const char* libraryName, const char* projName);
+
+#ifdef __cplusplus
+extern "C"
+#endif
+const char* findLibraryName(const char* libraryName, const char* projName);
+
+#ifdef __cplusplus
+extern "C"
+#endif
+void erase_libs();
+
+#ifdef __cplusplus
+extern "C"
+#endif
+const char* getLibFromProject(const char* projName);
+
+#ifdef __cplusplus
+ extern "C"
+#endif
+struct string_list* getExternalLibs(const char* projName);
+
+#ifdef __cplusplus
+extern "C"
+#endif
+struct string_list* getExternalLibPathes(const char* projName);
+
+#ifdef __cplusplus
+extern "C"
+#endif
+struct string2_list* getLinkerLibs(const char* projName);
+
+#ifdef __cplusplus
+extern "C"
+#endif
+struct string_list* getRefWorkingDirs(const char* projName);
+
+#ifdef __cplusplus
+extern "C"
+#endif
+boolean hasExternalLibrary(const char* libName, const char* projName);
+
+#ifdef __cplusplus
+extern "C"
+#endif
+boolean hasSubProject(const char* projName);
+
+#ifdef __cplusplus
+extern "C"
+#endif
+void print_libs();
+
+#ifdef __cplusplus
+extern "C"
+#endif
+boolean isTtcn3ModuleInLibrary(const char* moduleName);
+
+#ifdef __cplusplus
+extern "C"
+#endif
+const char* getTPDFileName(const char* projName);
+
+#ifdef __cplusplus
+extern "C"
+#endif
+const char* getPathToRootDir(const char* projName);
+
+#ifdef __cplusplus
+extern "C"
+#endif
+boolean isAsn1ModuleInLibrary(const char* moduleName);
+
+#ifdef __cplusplus
+extern "C"
+#endif
+boolean isSourceFileInLibrary(const char* fileName);
+
+#ifdef __cplusplus
+extern "C"
+#endif
+boolean isHeaderFileInLibrary(const char* fileName);
+
+#ifdef __cplusplus
+extern "C"
+#endif
+boolean isTtcnPPFileInLibrary(const char* fileName);
+
+#ifdef __cplusplus
+extern "C"
+#endif
+boolean buildObjects(const char* projName, boolean add_referenced);
+
+
/**
*
* @param p_tpd_name filename
tpd_result process_tpd(const char *p_tpd_name, const char *actcfg,
const char *file_list_path,
int *argc, char ***argv,
- int *optind, char **ets_name,
+ int *optind, char **ets_name, char **project_name,
boolean *gnu_make, boolean *single_mode,
boolean *central_storage, boolean *absolute_paths,
boolean *preprocess, boolean *use_runtime_2,
boolean *library, boolean recursive, boolean force_overwrite, boolean gen_only_top_level,
const char *output_file, char** abs_work_dir, struct string_list* sub_project_dirs,
const char* program_name, FILE* prj_graph_fp, struct string2_list* create_symlink_list, struct string_list* ttcn3_prep_includes,
- struct string_list* ttcn3_prep_defines, struct string_list* prep_includes, struct string_list* prep_defines,
- boolean *codesplit, boolean *quietly, boolean *disablesubtypecheck, char** cxxcompiler,
- char** optlevel, char** optflags, boolean *disableber, boolean *disableraw, boolean *disabletext, boolean *disablexer,
+ struct string_list* ttcn3_prep_defines, struct string_list* ttcn3_prep_undefines, struct string_list* prep_includes,
+ struct string_list* prep_defines, struct string_list* prep_undefines, boolean *codesplit, boolean *quietly, boolean *disablesubtypecheck,
+ 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, 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,
- char** generatorCommandOutput, struct string2_list* target_placement_list, boolean prefix_workdir, struct string2_list* run_command_list);
+ boolean *Zflag, boolean *Hflag, char** generatorCommandOutput, struct string2_list* target_placement_list, boolean prefix_workdir, struct string2_list* run_command_list,
+ struct string2_list* required_configs);
#endif /* XPATHER_H_ */
tlv->put_in_buffer(p_buf);
ASN_BER_TLV_t::destruct(tlv);
break;}
+ case TTCN_EncDec::CT_JSON: {
+ TTCN_EncDec_ErrorContext ec("While JSON-encoding type '%s': ", p_td.name);
+ if(!p_td.json)
+ TTCN_EncDec_ErrorContext::error_internal
+ ("No JSON descriptor available for type '%s'.", p_td.name);
+ JSON_Tokenizer tok(va_arg(pvar, int) != 0);
+ JSON_encode(p_td, tok);
+ p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());
+ break;}
case TTCN_EncDec::CT_RAW:
default:
TTCN_error("Unknown coding method requested to encode type '%s'",
BER_decode_TLV(p_td, tlv, L_form);
if(tlv.isComplete) p_buf.increase_pos(tlv.get_len());
break;}
+ case TTCN_EncDec::CT_JSON: {
+ TTCN_EncDec_ErrorContext ec("While JSON-decoding type '%s': ", p_td.name);
+ if(!p_td.json)
+ TTCN_EncDec_ErrorContext::error_internal
+ ("No JSON descriptor available for type '%s'.", p_td.name);
+ JSON_Tokenizer tok((const char*)p_buf.get_data(), p_buf.get_len());
+ if(JSON_decode(p_td, tok, false)<0)
+ ec.error(TTCN_EncDec::ET_INCOMPL_MSG,
+ "Can not decode type '%s', because invalid or incomplete"
+ " message was received"
+ , p_td.name);
+ p_buf.set_pos(tok.get_buf_pos());
+ break;}
case TTCN_EncDec::CT_RAW:
default:
TTCN_error("Unknown coding method requested to decode type '%s'",
// FIXME maybe: XER_encode and decode is virtually identical to EMBEDDED_PDV
int CHARACTER_STRING_identification::XER_encode(const XERdescriptor_t& p_td,
- TTCN_Buffer& p_buf, unsigned int flavor, int indent) const
+ TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const
{
int encoded_length=(int)p_buf.get_len();
flavor &= XER_MASK;
switch (union_selection) {
case ALT_syntaxes:
- field_syntaxes->XER_encode(EMBEDDED_PDV_identification_sxs_xer_, p_buf, flavor, indent);
+ field_syntaxes->XER_encode(EMBEDDED_PDV_identification_sxs_xer_, p_buf, flavor, indent, 0);
break;
case ALT_syntax:
- field_syntax->XER_encode(EMBEDDED_PDV_identification_sx_xer_, p_buf, flavor, indent);
+ field_syntax->XER_encode(EMBEDDED_PDV_identification_sx_xer_, p_buf, flavor, indent, 0);
break;
case ALT_presentation__context__id:
- field_presentation__context__id->XER_encode(EMBEDDED_PDV_identification_pci_xer_, p_buf, flavor, indent);
+ field_presentation__context__id->XER_encode(EMBEDDED_PDV_identification_pci_xer_, p_buf, flavor, indent, 0);
break;
case ALT_context__negotiation:
- field_context__negotiation->XER_encode(EMBEDDED_PDV_identification_cn_xer_, p_buf, flavor, indent);
+ field_context__negotiation->XER_encode(EMBEDDED_PDV_identification_cn_xer_, p_buf, flavor, indent, 0);
break;
case ALT_transfer__syntax:
- field_transfer__syntax->XER_encode(EMBEDDED_PDV_identification_ts_xer_, p_buf, flavor, indent);
+ field_transfer__syntax->XER_encode(EMBEDDED_PDV_identification_ts_xer_, p_buf, flavor, indent, 0);
break;
case ALT_fixed:
- field_fixed->XER_encode(EMBEDDED_PDV_identification_fix_xer_, p_buf, flavor, indent);
+ field_fixed->XER_encode(EMBEDDED_PDV_identification_fix_xer_, p_buf, flavor, indent, 0);
break;
default:
TTCN_EncDec_ErrorContext::error_internal("Unknown selection.");
}
int CHARACTER_STRING_identification::XER_decode(const XERdescriptor_t& p_td,
- XmlReaderWrap& reader, unsigned int flavor)
+ XmlReaderWrap& reader, unsigned int flavor, embed_values_dec_struct_t*)
{
int exer = is_exer(flavor);
// we are supposed to be parked on our element
size_t namelen = strlen(name);
switch (namelen) {
case 8: // syntaxes
- syntaxes().XER_decode(EMBEDDED_PDV_identification_sxs_xer_, reader, flavor);
+ syntaxes().XER_decode(EMBEDDED_PDV_identification_sxs_xer_, reader, flavor, 0);
break;
case 6: // syntax
- syntax().XER_decode(EMBEDDED_PDV_identification_sx_xer_, reader, flavor);
+ syntax().XER_decode(EMBEDDED_PDV_identification_sx_xer_, reader, flavor, 0);
break;
case 23: // presentation-context-id
- presentation__context__id().XER_decode(EMBEDDED_PDV_identification_pci_xer_, reader, flavor);
+ presentation__context__id().XER_decode(EMBEDDED_PDV_identification_pci_xer_, reader, flavor, 0);
break;
case 19: // context-negotiation
- context__negotiation().XER_decode(EMBEDDED_PDV_identification_cn_xer_, reader, flavor);
+ context__negotiation().XER_decode(EMBEDDED_PDV_identification_cn_xer_, reader, flavor, 0);
break;
case 15: // transfer-syntax
- transfer__syntax().XER_decode(EMBEDDED_PDV_identification_ts_xer_, reader, flavor);
+ transfer__syntax().XER_decode(EMBEDDED_PDV_identification_ts_xer_, reader, flavor, 0);
break;
case 5: // fixed
- fixed().XER_decode(EMBEDDED_PDV_identification_fix_xer_, reader, flavor);
+ fixed().XER_decode(EMBEDDED_PDV_identification_fix_xer_, reader, flavor, 0);
break;
default:
}
int CHARACTER_STRING_identification_syntaxes::XER_encode(const XERdescriptor_t& p_td,
- TTCN_Buffer& p_buf, unsigned int flavor, int indent) const
+ TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const
{
int encoded_length=(int)p_buf.get_len();
begin_xml(p_td, p_buf, flavor, indent++, false);
- field_abstract.XER_encode(CHARACTER_STRING_identification_sxs_abs_xer_, p_buf, flavor, indent);
- field_transfer.XER_encode(CHARACTER_STRING_identification_sxs_xfr_xer_, p_buf, flavor, indent);
+ field_abstract.XER_encode(CHARACTER_STRING_identification_sxs_abs_xer_, p_buf, flavor, indent, 0);
+ field_transfer.XER_encode(CHARACTER_STRING_identification_sxs_xfr_xer_, p_buf, flavor, indent, 0);
end_xml(p_td, p_buf, flavor, --indent, false);
}
int CHARACTER_STRING_identification_syntaxes::XER_decode(
- const XERdescriptor_t& /*p_td*/, XmlReaderWrap& reader, unsigned int flavor)
+ const XERdescriptor_t& /*p_td*/, XmlReaderWrap& reader, unsigned int flavor, embed_values_dec_struct_t*)
{ // we stand on <syntaxes>, move ahead first
for (int success = reader.Read(); success == 1; success = reader.Read())
{
break;
}
// FIXME this assumes the right element
- field_abstract.XER_decode(EMBEDDED_PDV_identification_sxs_abs_xer_, reader, flavor);
- field_transfer.XER_decode(EMBEDDED_PDV_identification_sxs_xfr_xer_, reader, flavor);
+ field_abstract.XER_decode(EMBEDDED_PDV_identification_sxs_abs_xer_, reader, flavor, 0);
+ field_transfer.XER_decode(EMBEDDED_PDV_identification_sxs_xfr_xer_, reader, flavor, 0);
for (int success = 1; success == 1; success = reader.Read())
{
int type = reader.NodeType();
}
int CHARACTER_STRING_identification_context__negotiation::XER_encode(const XERdescriptor_t& p_td,
- TTCN_Buffer& p_buf, unsigned int flavor, int indent) const
+ TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const
{
int encoded_length=(int)p_buf.get_len();
begin_xml(p_td, p_buf, flavor, indent++, false);
- field_presentation__context__id.XER_encode(CHARACTER_STRING_identification_pci_xer_, p_buf, flavor, indent);
- field_transfer__syntax .XER_encode(CHARACTER_STRING_identification_ts_xer_ , p_buf, flavor, indent);
+ field_presentation__context__id.XER_encode(CHARACTER_STRING_identification_pci_xer_, p_buf, flavor, indent, 0);
+ field_transfer__syntax .XER_encode(CHARACTER_STRING_identification_ts_xer_ , p_buf, flavor, indent, 0);
end_xml(p_td, p_buf, flavor, --indent, false);
}
int CHARACTER_STRING_identification_context__negotiation::XER_decode(
- const XERdescriptor_t& p_td, XmlReaderWrap& reader, unsigned int flavor)
+ const XERdescriptor_t& p_td, XmlReaderWrap& reader, unsigned int flavor, embed_values_dec_struct_t*)
{
int exer = is_exer(flavor);
int type = reader.NodeType(), depth = -1;
depth = reader.Depth();
success = reader.Read();
}
- field_presentation__context__id.XER_decode(EMBEDDED_PDV_identification_cn_pci_xer_, reader, flavor);
- field_transfer__syntax .XER_decode(EMBEDDED_PDV_identification_cn_tsx_xer_, reader, flavor);
+ field_presentation__context__id.XER_decode(EMBEDDED_PDV_identification_cn_pci_xer_, reader, flavor, 0);
+ field_transfer__syntax .XER_decode(EMBEDDED_PDV_identification_cn_tsx_xer_, reader, flavor, 0);
for (; success == 1; success = reader.Read()) {
type = reader.NodeType();
if (XML_READER_TYPE_END_ELEMENT == type) {
case TTCN_EncDec::CT_XER: {
TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
unsigned XER_coding=va_arg(pvar, unsigned);
- XER_encode(*p_td.xer,p_buf, XER_coding, 0);
+ XER_encode(*p_td.xer,p_buf, XER_coding, 0, 0);
p_buf.put_c('\n');
break;}
case TTCN_EncDec::CT_JSON: {
if (type==XML_READER_TYPE_ELEMENT)
break;
}
- XER_decode(*p_td.xer, reader, XER_coding);
+ XER_decode(*p_td.xer, reader, XER_coding, 0);
size_t bytes = reader.ByteConsumed();
p_buf.set_pos(bytes);
break;}
return TRUE;
}
-int CHARACTER_STRING::XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, unsigned int flavor, int indent) const
+int CHARACTER_STRING::XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf,
+ unsigned int flavor, int indent, embed_values_enc_struct_t*) const
{
if(!is_bound()) {
TTCN_EncDec_ErrorContext::error
flavor &= ~XER_RECOF; // ASN.1 character string doesn't care
begin_xml(p_td, p_buf, flavor, indent++, false);
- field_identification.XER_encode(CHARACTER_STRING_identification_xer_, p_buf, flavor, indent);
+ field_identification.XER_encode(CHARACTER_STRING_identification_xer_, p_buf, flavor, indent, 0);
// data-value-descriptor is OPTIONAL and can never be present.
// Its encoding is empty.
- field_string__value .XER_encode(CHARACTER_STRING_data_value_xer_ , p_buf, flavor, indent);
+ field_string__value .XER_encode(CHARACTER_STRING_data_value_xer_ , p_buf, flavor, indent, 0);
end_xml(p_td, p_buf, flavor, --indent, false);
}
int CHARACTER_STRING::XER_decode(const XERdescriptor_t& p_td,
- XmlReaderWrap& reader, unsigned int flavor)
+ XmlReaderWrap& reader, unsigned int flavor, embed_values_dec_struct_t*)
{
int exer = is_exer(flavor);
int success = reader.Ok(), depth = -1, type;
break;
}
}
- field_identification .XER_decode(CHARACTER_STRING_identification_xer_ , reader, flavor);
- field_data__value__descriptor.XER_decode(CHARACTER_STRING_data_value_descriptor_xer_, reader, flavor);
+ field_identification .XER_decode(CHARACTER_STRING_identification_xer_ , reader, flavor, 0);
+ field_data__value__descriptor.XER_decode(CHARACTER_STRING_data_value_descriptor_xer_, reader, flavor, 0);
if (field_data__value__descriptor.is_value()) {
TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG,
"data-value-descriptor not allowed for EMBEDDED PDV");
}
- field_string__value .XER_decode(CHARACTER_STRING_data_value_xer_ , reader, flavor);
+ field_string__value .XER_decode(CHARACTER_STRING_data_value_xer_ , reader, flavor, 0);
for (success = reader.Read(); success == 1; success = reader.Read()) {
type = reader.NodeType();
if (XML_READER_TYPE_END_ELEMENT == type) {
ASN_BER_TLV_t* BER_encode_TLV(const TTCN_Typedescriptor_t& p_td, unsigned p_coding) const;
boolean BER_decode_TLV(const TTCN_Typedescriptor_t& p_td, const ASN_BER_TLV_t& p_tlv, unsigned L_form);
int XER_encode(const XERdescriptor_t& p_td,
- TTCN_Buffer& p_buf, unsigned int flavor, int indent) const;
+ TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const;
int XER_decode(const XERdescriptor_t& p_td,
- XmlReaderWrap& reader, unsigned int flavor);
+ XmlReaderWrap& reader, unsigned int flavor, embed_values_dec_struct_t*);
private:
boolean BER_decode_set_selection(const ASN_BER_TLV_t& p_tlv);
public:
ASN_BER_TLV_t* BER_encode_TLV(const TTCN_Typedescriptor_t& p_td, unsigned p_coding) const;
boolean BER_decode_TLV(const TTCN_Typedescriptor_t& p_td, const ASN_BER_TLV_t& p_tlv, unsigned L_form);
int XER_encode(const XERdescriptor_t& p_td,
- TTCN_Buffer& p_buf, unsigned int flavor, int indent) const;
+ TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const;
int XER_decode(const XERdescriptor_t& p_td,
- XmlReaderWrap& reader, unsigned int flavor);
+ XmlReaderWrap& reader, unsigned int flavor, embed_values_dec_struct_t*);
};
class CHARACTER_STRING_identification_syntaxes_template : public Base_Template {
ASN_BER_TLV_t* BER_encode_TLV(const TTCN_Typedescriptor_t& p_td, unsigned p_coding) const;
boolean BER_decode_TLV(const TTCN_Typedescriptor_t& p_td, const ASN_BER_TLV_t& p_tlv, unsigned L_form);
int XER_encode(const XERdescriptor_t& p_td,
- TTCN_Buffer& p_buf, unsigned int flavor, int indent) const;
+ TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const;
int XER_decode(const XERdescriptor_t& p_td,
- XmlReaderWrap& reader, unsigned int flavor);
+ XmlReaderWrap& reader, unsigned int flavor, embed_values_dec_struct_t*);
};
class CHARACTER_STRING_identification_context__negotiation_template : public Base_Template {
void decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...);
ASN_BER_TLV_t* BER_encode_TLV(const TTCN_Typedescriptor_t& p_td, unsigned p_coding) const;
boolean BER_decode_TLV(const TTCN_Typedescriptor_t& p_td, const ASN_BER_TLV_t& p_tlv, unsigned L_form);
- int XER_encode(const XERdescriptor_t&, TTCN_Buffer&, unsigned int, int) const;
- int XER_decode(const XERdescriptor_t&, XmlReaderWrap& reader, unsigned int);
+ int XER_encode(const XERdescriptor_t&, TTCN_Buffer&, unsigned int, int, embed_values_enc_struct_t*) const;
+ int XER_decode(const XERdescriptor_t&, XmlReaderWrap& reader, unsigned int, embed_values_dec_struct_t*);
};
class CHARACTER_STRING_template : public Base_Template {
// FIXME maybe: XER_encode and decode is virtually identical to CHARACTER_STRING
int EMBEDDED_PDV_identification::XER_encode(const XERdescriptor_t& p_td,
- TTCN_Buffer& p_buf, unsigned int flavor, int indent) const
+ TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const
{
int indenting = !is_canonical(flavor);
int exer = is_exer(flavor);
++indent;
switch (union_selection) {
case ALT_syntaxes:
- field_syntaxes->XER_encode(EMBEDDED_PDV_identification_sxs_xer_, p_buf, flavor, indent);;
+ field_syntaxes->XER_encode(EMBEDDED_PDV_identification_sxs_xer_, p_buf, flavor, indent, 0);;
break;
case ALT_syntax:
- field_syntax->XER_encode(EMBEDDED_PDV_identification_sx_xer_, p_buf, flavor, indent);;
+ field_syntax->XER_encode(EMBEDDED_PDV_identification_sx_xer_, p_buf, flavor, indent, 0);;
break;
case ALT_presentation__context__id:
- field_presentation__context__id->XER_encode(EMBEDDED_PDV_identification_pci_xer_, p_buf, flavor, indent);;
+ field_presentation__context__id->XER_encode(EMBEDDED_PDV_identification_pci_xer_, p_buf, flavor, indent, 0);;
break;
case ALT_context__negotiation:
- field_context__negotiation->XER_encode(EMBEDDED_PDV_identification_cn_xer_, p_buf, flavor, indent);;
+ field_context__negotiation->XER_encode(EMBEDDED_PDV_identification_cn_xer_, p_buf, flavor, indent, 0);;
break;
case ALT_transfer__syntax:
- field_transfer__syntax->XER_encode(EMBEDDED_PDV_identification_ts_xer_, p_buf, flavor, indent);;
+ field_transfer__syntax->XER_encode(EMBEDDED_PDV_identification_ts_xer_, p_buf, flavor, indent, 0);;
break;
case ALT_fixed:
- field_fixed->XER_encode(EMBEDDED_PDV_identification_fix_xer_, p_buf, flavor, indent);;
+ field_fixed->XER_encode(EMBEDDED_PDV_identification_fix_xer_, p_buf, flavor, indent, 0);;
break;
default:
TTCN_EncDec_ErrorContext::error_internal("Unknown selection.");
}
int EMBEDDED_PDV_identification::XER_decode(const XERdescriptor_t& p_td,
- XmlReaderWrap& reader, unsigned int flavor)
+ XmlReaderWrap& reader, unsigned int flavor, embed_values_dec_struct_t*)
{
int exer = is_exer(flavor);
// we are supposed to be parked on our element
size_t namelen = strlen(name);
switch (namelen) {
case 8: // syntaxes
- syntaxes().XER_decode(EMBEDDED_PDV_identification_sxs_xer_, reader, flavor);
+ syntaxes().XER_decode(EMBEDDED_PDV_identification_sxs_xer_, reader, flavor, 0);
break;
case 6: // syntax
- syntax().XER_decode(EMBEDDED_PDV_identification_sx_xer_, reader, flavor);
+ syntax().XER_decode(EMBEDDED_PDV_identification_sx_xer_, reader, flavor, 0);
break;
case 23: // presentation-context-id
- presentation__context__id().XER_decode(EMBEDDED_PDV_identification_pci_xer_, reader, flavor);
+ presentation__context__id().XER_decode(EMBEDDED_PDV_identification_pci_xer_, reader, flavor, 0);
break;
case 19: // context-negotiation
- context__negotiation().XER_decode(EMBEDDED_PDV_identification_cn_xer_, reader, flavor);
+ context__negotiation().XER_decode(EMBEDDED_PDV_identification_cn_xer_, reader, flavor, 0);
break;
case 15: // transfer-syntax
- transfer__syntax().XER_decode(EMBEDDED_PDV_identification_ts_xer_, reader, flavor);
+ transfer__syntax().XER_decode(EMBEDDED_PDV_identification_ts_xer_, reader, flavor, 0);
break;
case 5: // fixed
- fixed().XER_decode(EMBEDDED_PDV_identification_fix_xer_, reader, flavor);
+ fixed().XER_decode(EMBEDDED_PDV_identification_fix_xer_, reader, flavor, 0);
break;
default:
}
int EMBEDDED_PDV_identification_syntaxes::XER_encode(const XERdescriptor_t& p_td,
- TTCN_Buffer& p_buf, unsigned int flavor, int indent) const
+ TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const
{
int indenting = !is_canonical(flavor);
int exer = is_exer(flavor);
p_buf.put_s((size_t)p_td.namelens[exer] - 1 + indenting, (const unsigned char*)p_td.names[exer]);
++indent;
- field_abstract.XER_encode(EMBEDDED_PDV_identification_sxs_abs_xer_, p_buf, flavor, indent);
- field_transfer.XER_encode(EMBEDDED_PDV_identification_sxs_xfr_xer_, p_buf, flavor, indent);
+ field_abstract.XER_encode(EMBEDDED_PDV_identification_sxs_abs_xer_, p_buf, flavor, indent, 0);
+ field_transfer.XER_encode(EMBEDDED_PDV_identification_sxs_xfr_xer_, p_buf, flavor, indent, 0);
if (indenting) do_indent(p_buf, --indent);
p_buf.put_c('<');
}
int EMBEDDED_PDV_identification_syntaxes::XER_decode(const XERdescriptor_t& /*p_td*/,
- XmlReaderWrap& reader, unsigned int flavor)
+ XmlReaderWrap& reader, unsigned int flavor, embed_values_dec_struct_t*)
{ // we stand on <syntaxes>, move ahead first
int type;
for (int success = reader.Read(); success == 1; success = reader.Read())
break;
}
// FIXME this assumes the right element
- field_abstract.XER_decode(EMBEDDED_PDV_identification_sxs_abs_xer_, reader, flavor);
- field_transfer.XER_decode(EMBEDDED_PDV_identification_sxs_xfr_xer_, reader, flavor);
+ field_abstract.XER_decode(EMBEDDED_PDV_identification_sxs_abs_xer_, reader, flavor, 0);
+ field_transfer.XER_decode(EMBEDDED_PDV_identification_sxs_xfr_xer_, reader, flavor, 0);
for (int success = 1; success == 1; success = reader.Read())
{
type = reader.NodeType();
}
int EMBEDDED_PDV_identification_context__negotiation::XER_encode(const XERdescriptor_t& p_td,
- TTCN_Buffer& p_buf, unsigned int flavor, int indent) const
+ TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const
{
int indenting = !is_canonical(flavor);
int exer = is_exer(flavor);
p_buf.put_s((size_t)p_td.namelens[exer] - 1 + indenting, (const unsigned char*)p_td.names[exer]);
++indent;
- field_presentation__context__id.XER_encode(EMBEDDED_PDV_identification_cn_pci_xer_, p_buf, flavor, indent);
- field_transfer__syntax .XER_encode(EMBEDDED_PDV_identification_cn_tsx_xer_, p_buf, flavor, indent);
+ field_presentation__context__id.XER_encode(EMBEDDED_PDV_identification_cn_pci_xer_, p_buf, flavor, indent, 0);
+ field_transfer__syntax .XER_encode(EMBEDDED_PDV_identification_cn_tsx_xer_, p_buf, flavor, indent, 0);
if (indenting) do_indent(p_buf, --indent);
p_buf.put_c('<');
}
int EMBEDDED_PDV_identification_context__negotiation::XER_decode(
- const XERdescriptor_t& p_td, XmlReaderWrap& reader, unsigned int flavor)
+ const XERdescriptor_t& p_td, XmlReaderWrap& reader, unsigned int flavor, embed_values_dec_struct_t*)
{
int exer = is_exer(flavor);
int type = reader.NodeType(), depth = -1;
depth = reader.Depth();
success = reader.Read();
}
- field_presentation__context__id.XER_decode(EMBEDDED_PDV_identification_cn_pci_xer_, reader, flavor);
- field_transfer__syntax .XER_decode(EMBEDDED_PDV_identification_cn_tsx_xer_, reader, flavor);
+ field_presentation__context__id.XER_decode(EMBEDDED_PDV_identification_cn_pci_xer_, reader, flavor, 0);
+ field_transfer__syntax .XER_decode(EMBEDDED_PDV_identification_cn_tsx_xer_, reader, flavor, 0);
for (; success == 1; success = reader.Read()) {
type = reader.NodeType();
if (XML_READER_TYPE_END_ELEMENT == type) {
case TTCN_EncDec::CT_XER: {
TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
unsigned XER_coding=va_arg(pvar, unsigned);
- XER_encode(*p_td.xer,p_buf, XER_coding, 0);
+ XER_encode(*p_td.xer,p_buf, XER_coding, 0, 0);
break;}
case TTCN_EncDec::CT_JSON: {
TTCN_EncDec_ErrorContext ec("While JSON-encoding type '%s': ", p_td.name);
if (type==XML_READER_TYPE_ELEMENT)
break;
}
- XER_decode(*p_td.xer, reader, XER_coding);
+ XER_decode(*p_td.xer, reader, XER_coding, 0);
size_t bytes = reader.ByteConsumed();
p_buf.set_pos(bytes);
break;}
}
int EMBEDDED_PDV::XER_encode(const XERdescriptor_t& p_td,
- TTCN_Buffer& p_buf, unsigned int flavor, int indent) const {
+ TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const {
if(!is_bound()) {
TTCN_EncDec_ErrorContext::error
(TTCN_EncDec::ET_UNBOUND, "Encoding an unbound value.");
p_buf.put_s((size_t)p_td.namelens[exer] - 1 + indenting, (const unsigned char*)p_td.names[exer]);
flavor &= XER_MASK;
++indent;
- field_identification .XER_encode(EMBEDDED_PDV_identification_xer_ , p_buf, flavor, indent);
+ field_identification .XER_encode(EMBEDDED_PDV_identification_xer_ , p_buf, flavor, indent, 0);
if (field_data__value__descriptor.is_value()) {
TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG,
"data-value-descriptor not allowed for EMBEDDED PDV");
}
- field_data__value__descriptor.XER_encode(EMBEDDED_PDV_data_value_descriptor_xer_, p_buf, flavor, indent);
- field_data__value .XER_encode(EMBEDDED_PDV_data_value_xer_ , p_buf, flavor, indent);
+ field_data__value__descriptor.XER_encode(EMBEDDED_PDV_data_value_descriptor_xer_, p_buf, flavor, indent, 0);
+ field_data__value .XER_encode(EMBEDDED_PDV_data_value_xer_ , p_buf, flavor, indent, 0);
if (indenting) do_indent(p_buf, --indent);
p_buf.put_c('<');
return (int)p_buf.get_len() - encoded_length;
}
-int EMBEDDED_PDV::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, unsigned int flavor)
+int EMBEDDED_PDV::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, unsigned int flavor, embed_values_dec_struct_t*)
{
int exer = is_exer(flavor);
int depth = 1, type, success;
break;
}
}
- field_identification .XER_decode(EMBEDDED_PDV_identification_xer_ , reader, flavor);
- field_data__value__descriptor.XER_decode(EMBEDDED_PDV_data_value_descriptor_xer_, reader, flavor);
+ field_identification .XER_decode(EMBEDDED_PDV_identification_xer_ , reader, flavor, 0);
+ field_data__value__descriptor.XER_decode(EMBEDDED_PDV_data_value_descriptor_xer_, reader, flavor, 0);
if (field_data__value__descriptor.is_value()) {
TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG,
"data-value-descriptor not allowed for EMBEDDED PDV");
}
- field_data__value .XER_decode(EMBEDDED_PDV_data_value_xer_ , reader, flavor);
+ field_data__value .XER_decode(EMBEDDED_PDV_data_value_xer_ , reader, flavor, 0);
for (success = reader.Read(); success == 1; success = reader.Read()) {
type = reader.NodeType();
if (XML_READER_TYPE_END_ELEMENT == type) {
ASN_BER_TLV_t* BER_encode_TLV(const TTCN_Typedescriptor_t& p_td, unsigned p_coding) const;
boolean BER_decode_TLV(const TTCN_Typedescriptor_t& p_td, const ASN_BER_TLV_t& p_tlv, unsigned L_form);
int XER_encode(const XERdescriptor_t& p_td,
- TTCN_Buffer& p_buf, unsigned int flavor, int indent) const;
+ TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const;
int XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
- unsigned int flavor);
+ unsigned int flavor, embed_values_dec_struct_t*);
private:
boolean BER_decode_set_selection(const ASN_BER_TLV_t& p_tlv);
public:
//void decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...);
ASN_BER_TLV_t* BER_encode_TLV(const TTCN_Typedescriptor_t& p_td, unsigned p_coding) const;
boolean BER_decode_TLV(const TTCN_Typedescriptor_t& p_td, const ASN_BER_TLV_t& p_tlv, unsigned L_form);
- int XER_encode(const XERdescriptor_t&, TTCN_Buffer&, unsigned int, int) const;
- int XER_decode(const XERdescriptor_t&, XmlReaderWrap& reader, unsigned int);
+ int XER_encode(const XERdescriptor_t&, TTCN_Buffer&, unsigned int, int, embed_values_enc_struct_t*) const;
+ int XER_decode(const XERdescriptor_t&, XmlReaderWrap& reader, unsigned int, embed_values_dec_struct_t*);
};
class EMBEDDED_PDV_identification_syntaxes_template : public Base_Template {
//void decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...);
ASN_BER_TLV_t* BER_encode_TLV(const TTCN_Typedescriptor_t& p_td, unsigned p_coding) const;
boolean BER_decode_TLV(const TTCN_Typedescriptor_t& p_td, const ASN_BER_TLV_t& p_tlv, unsigned L_form);
- int XER_encode(const XERdescriptor_t&, TTCN_Buffer&, unsigned int, int) const;
- int XER_decode(const XERdescriptor_t&, XmlReaderWrap& reader, unsigned int);
+ int XER_encode(const XERdescriptor_t&, TTCN_Buffer&, unsigned int, int, embed_values_enc_struct_t*) const;
+ int XER_decode(const XERdescriptor_t&, XmlReaderWrap& reader, unsigned int, embed_values_dec_struct_t*);
};
class EMBEDDED_PDV_identification_context__negotiation_template : public Base_Template {
void decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...);
ASN_BER_TLV_t* BER_encode_TLV(const TTCN_Typedescriptor_t& p_td, unsigned p_coding) const;
boolean BER_decode_TLV(const TTCN_Typedescriptor_t& p_td, const ASN_BER_TLV_t& p_tlv, unsigned L_form);
- int XER_encode(const XERdescriptor_t&, TTCN_Buffer&, unsigned int, int) const;
- int XER_decode(const XERdescriptor_t&, XmlReaderWrap&, unsigned int);
+ int XER_encode(const XERdescriptor_t&, TTCN_Buffer&, unsigned int, int, embed_values_enc_struct_t*) const;
+ int XER_decode(const XERdescriptor_t&, XmlReaderWrap&, unsigned int, embed_values_dec_struct_t*);
};
class EMBEDDED_PDV_template : public Base_Template {
ASN_BER_TLV_t* BER_encode_TLV(const TTCN_Typedescriptor_t& p_td, unsigned p_coding) const;
boolean BER_decode_TLV(const TTCN_Typedescriptor_t& p_td, const ASN_BER_TLV_t& p_tlv, unsigned L_form);
int XER_encode(const XERdescriptor_t& p_td,
- TTCN_Buffer& p_buf, unsigned int flavor, int indent) const;
+ TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const;
int XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
- unsigned int flavor);
+ unsigned int flavor, embed_values_dec_struct_t*);
private:
boolean BER_decode_set_selection(const ASN_BER_TLV_t& p_tlv);
public:
ASN_BER_TLV_t* BER_encode_TLV(const TTCN_Typedescriptor_t& p_td, unsigned p_coding) const;
boolean BER_decode_TLV(const TTCN_Typedescriptor_t& p_td, const ASN_BER_TLV_t& p_tlv, unsigned L_form);
int XER_encode(const XERdescriptor_t& p_td,
- TTCN_Buffer& p_buf, unsigned int flavor, int indent) const;
+ TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const;
int XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
- unsigned int flavor);
+ unsigned int flavor, embed_values_dec_struct_t*);
};
/** Transform the information from the visible format to the encoding format
}
int EXTERNALtransfer_encoding::XER_encode(const XERdescriptor_t& p_td,
- TTCN_Buffer& p_buf, unsigned int flavor, int indent) const
+ TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const
{
int indenting = !is_canonical(flavor);
int exer = is_exer(flavor);
++indent;
switch (union_selection) {
case ALT_single__ASN1__type:
- field_single__ASN1__type->XER_encode(EXTERNAL_encoding_singleASN_xer_, p_buf, flavor, indent);
+ field_single__ASN1__type->XER_encode(EXTERNAL_encoding_singleASN_xer_, p_buf, flavor, indent, 0);
break;
case ALT_octet__aligned:
- field_octet__aligned ->XER_encode(EXTERNAL_encoding_octet_aligned_xer_, p_buf, flavor, indent);
+ field_octet__aligned ->XER_encode(EXTERNAL_encoding_octet_aligned_xer_, p_buf, flavor, indent, 0);
break;
case ALT_arbitrary:
- field_arbitrary ->XER_encode(EXTERNAL_encoding_arbitrary_xer_, p_buf, flavor, indent);
+ field_arbitrary ->XER_encode(EXTERNAL_encoding_arbitrary_xer_, p_buf, flavor, indent, 0);
break;
case UNBOUND_VALUE:
TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,
}
int EXTERNALtransfer_encoding::XER_decode(const XERdescriptor_t& p_td,
- XmlReaderWrap& reader, unsigned int flavor)
+ XmlReaderWrap& reader, unsigned int flavor, embed_values_dec_struct_t*)
{
int exer = is_exer(flavor);
int success = reader.Ok(), type, depth = -1;
switch (*name) {
case 's': // single-ASN1-type
- single__ASN1__type().XER_decode(EXTERNAL_encoding_singleASN_xer_, reader, flavor);
+ single__ASN1__type().XER_decode(EXTERNAL_encoding_singleASN_xer_, reader, flavor, 0);
break;
case 'o': // octet-aligned
- octet__aligned().XER_decode(EXTERNAL_encoding_octet_aligned_xer_, reader, flavor);
+ octet__aligned().XER_decode(EXTERNAL_encoding_octet_aligned_xer_, reader, flavor, 0);
break;
case 'a': // arbitrary
- arbitrary().XER_decode(EXTERNAL_encoding_arbitrary_xer_, reader, flavor);
+ arbitrary().XER_decode(EXTERNAL_encoding_arbitrary_xer_, reader, flavor, 0);
break;
default:
}
int EXTERNALtransfer::XER_encode(const XERdescriptor_t& p_td,
- TTCN_Buffer& p_buf, unsigned int flavor, int indent) const
+ TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const
{
int indenting = !is_canonical(flavor);
int exer = is_exer(flavor);
p_buf.put_s((size_t)p_td.namelens[exer] - 1 + indenting, (const unsigned char*)p_td.names[exer]);
++indent;
- field_direct__reference .XER_encode(EXTERNAL_direct_reference_xer_ , p_buf, flavor, indent);
- field_indirect__reference .XER_encode(EXTERNAL_indirect_reference_xer_ , p_buf, flavor, indent);
- field_data__value__descriptor.XER_encode(EXTERNAL_data_value_descriptor_xer_, p_buf, flavor, indent);
- field_encoding .XER_encode(EXTERNAL_encoding_xer_ , p_buf, flavor, indent);
+ field_direct__reference .XER_encode(EXTERNAL_direct_reference_xer_ , p_buf, flavor, indent, 0);
+ field_indirect__reference .XER_encode(EXTERNAL_indirect_reference_xer_ , p_buf, flavor, indent, 0);
+ field_data__value__descriptor.XER_encode(EXTERNAL_data_value_descriptor_xer_, p_buf, flavor, indent, 0);
+ field_encoding .XER_encode(EXTERNAL_encoding_xer_ , p_buf, flavor, indent, 0);
if (indenting) do_indent(p_buf, --indent);
p_buf.put_c('<');
return (int)p_buf.get_len() - encoded_length;
}
- int EXTERNALtransfer::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, unsigned int flavor)
+ int EXTERNALtransfer::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
+ unsigned int flavor, embed_values_dec_struct_t*)
{
int exer = is_exer(flavor);
int success = reader.Ok(), depth = -1;
}
}
- field_direct__reference .XER_decode(EXTERNAL_direct_reference_xer_ , reader, flavor);
- field_indirect__reference .XER_decode(EXTERNAL_indirect_reference_xer_ , reader, flavor);
- field_data__value__descriptor.XER_decode(EXTERNAL_data_value_descriptor_xer_, reader, flavor);
- field_encoding .XER_decode(EXTERNAL_encoding_xer_ , reader, flavor);
+ field_direct__reference .XER_decode(EXTERNAL_direct_reference_xer_ , reader, flavor, 0);
+ field_indirect__reference .XER_decode(EXTERNAL_indirect_reference_xer_ , reader, flavor, 0);
+ field_data__value__descriptor.XER_decode(EXTERNAL_data_value_descriptor_xer_, reader, flavor, 0);
+ field_encoding .XER_decode(EXTERNAL_encoding_xer_ , reader, flavor, 0);
for (success = reader.Read(); success == 1; success = reader.Read()) {
int type = reader.NodeType();
}
int EXTERNAL::XER_encode(const XERdescriptor_t& p_td,
- TTCN_Buffer& p_buf, unsigned int flavor, int indent) const
+ TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const
{
if(!is_bound()) {
TTCN_EncDec_ErrorContext::error
}
EXTERNALtransfer xfer;
xfer.load(*this);
- return xfer.XER_encode(p_td, p_buf, flavor, indent);
+ return xfer.XER_encode(p_td, p_buf, flavor, indent, 0);
}
int EXTERNAL::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
- unsigned int flavor)
+ unsigned int flavor, embed_values_dec_struct_t*)
{
EXTERNALtransfer xfer;
- xfer.XER_decode(p_td, reader, flavor);
+ xfer.XER_decode(p_td, reader, flavor, 0);
transfer(&xfer);
return 1; // decode successful
}
case TTCN_EncDec::CT_XER: {
TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
unsigned XER_coding=va_arg(pvar, unsigned);
- XER_encode(*p_td.xer, p_buf, XER_coding, 0);
+ XER_encode(*p_td.xer, p_buf, XER_coding, 0, 0);
break;}
case TTCN_EncDec::CT_JSON: {
TTCN_EncDec_ErrorContext ec("While JSON-encoding type '%s': ", p_td.name);
if (type==XML_READER_TYPE_ELEMENT)
break;
}
- XER_decode(*p_td.xer, reader, XER_coding);
+ XER_decode(*p_td.xer, reader, XER_coding, 0);
size_t bytes = reader.ByteConsumed();
p_buf.set_pos(bytes);
break;}
ASN_BER_TLV_t* BER_encode_TLV(const TTCN_Typedescriptor_t& p_td, unsigned p_coding) const;
boolean BER_decode_TLV(const TTCN_Typedescriptor_t& p_td, const ASN_BER_TLV_t& p_tlv, unsigned L_form);
int XER_encode(const XERdescriptor_t& p_td,
- TTCN_Buffer& p_buf, unsigned int flavor, int indent) const;
+ TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const;
int XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
- unsigned int flavor);
+ unsigned int flavor, embed_values_dec_struct_t*);
};
class EXTERNAL_template : public Base_Template {
case TTCN_EncDec::CT_XER: {
TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
unsigned XER_coding=va_arg(pvar, unsigned);
- XER_encode(*p_td.xer, p_buf, XER_coding, 0);
+ XER_encode(*p_td.xer, p_buf, XER_coding, 0, 0);
+ break;}
+ case TTCN_EncDec::CT_JSON: {
+ TTCN_EncDec_ErrorContext ec("While JSON-encoding type '%s': ", p_td.name);
+ if(!p_td.json)
+ TTCN_EncDec_ErrorContext::error_internal
+ ("No JSON descriptor available for type '%s'.", p_td.name);
+ JSON_Tokenizer tok(va_arg(pvar, int) != 0);
+ JSON_encode(p_td, tok);
+ p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());
break;}
case TTCN_EncDec::CT_RAW:
default:
if(tlv.isComplete) p_buf.increase_pos(tlv.get_len());
break;}
case TTCN_EncDec::CT_XER: {
- TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
+ TTCN_EncDec_ErrorContext ec("While XER-decoding type '%s': ", p_td.name);
unsigned XER_coding=va_arg(pvar, unsigned);
XmlReaderWrap reader(p_buf);
int success = reader.Read();
if (type==XML_READER_TYPE_ELEMENT)
break;
}
- XER_decode(*p_td.xer, reader, XER_coding);
+ XER_decode(*p_td.xer, reader, XER_coding, 0);
size_t bytes = reader.ByteConsumed();
p_buf.set_pos(bytes);
break;}
+ case TTCN_EncDec::CT_JSON: {
+ TTCN_EncDec_ErrorContext ec("While JSON-decoding type '%s': ", p_td.name);
+ if(!p_td.json)
+ TTCN_EncDec_ErrorContext::error_internal
+ ("No JSON descriptor available for type '%s'.", p_td.name);
+ JSON_Tokenizer tok((const char*)p_buf.get_data(), p_buf.get_len());
+ if(JSON_decode(p_td, tok, false)<0)
+ ec.error(TTCN_EncDec::ET_INCOMPL_MSG,
+ "Can not decode type '%s', because invalid or incomplete"
+ " message was received"
+ , p_td.name);
+ p_buf.set_pos(tok.get_buf_pos());
+ break;}
case TTCN_EncDec::CT_RAW:
default:
TTCN_error("Unknown coding method requested to decode type '%s'",
}
int ASN_NULL::XER_encode(const XERdescriptor_t& p_td,
- TTCN_Buffer& p_buf, unsigned int flavor, int indent ) const
+ TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const
{
int exer = is_exer(flavor);
TTCN_EncDec_ErrorContext ec("While XER encoding NULL type: ");
}
int ASN_NULL::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
- unsigned int flavor)
+ unsigned int flavor, embed_values_dec_struct_t*)
{
int exer = is_exer(flavor);
TTCN_EncDec_ErrorContext ec("While XER decoding NULL type: ");
return 1; // decode successful
}
+int ASN_NULL::JSON_encode(const TTCN_Typedescriptor_t&, JSON_Tokenizer& p_tok) const
+{
+ if (!is_bound()) {
+ TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,
+ "Encoding an unbound ASN.1 NULL value.");
+ return -1;
+ }
+
+ return p_tok.put_next_token(JSON_TOKEN_LITERAL_NULL);
+}
+
+int ASN_NULL::JSON_decode(const TTCN_Typedescriptor_t&, JSON_Tokenizer& p_tok, boolean p_silent)
+{
+ json_token_t token = JSON_TOKEN_NONE;
+ int dec_len = p_tok.get_next_token(&token, NULL, NULL);
+ if (JSON_TOKEN_ERROR == token) {
+ JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_BAD_TOKEN_ERROR, "");
+ return JSON_ERROR_FATAL;
+ }
+ else if (JSON_TOKEN_LITERAL_NULL != token) {
+ return JSON_ERROR_INVALID_TOKEN;
+ }
+ bound_flag = TRUE;
+ return dec_len;
+}
+
boolean operator==(asn_null_type, const ASN_NULL& other_value)
{
if (!other_value.is_bound()) TTCN_error("The right operand of comparison "
boolean BER_decode_TLV(const TTCN_Typedescriptor_t& p_td,
const ASN_BER_TLV_t& p_tlv, unsigned L_form);
int XER_encode(const XERdescriptor_t& p_td,
- TTCN_Buffer& p_buf, unsigned int flavor, int indent) const;
+ TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const;
int XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
- unsigned int flavor);
+ unsigned int flavor, embed_values_dec_struct_t*);
+
+ /** Encodes accordingly to the JSON encoding rules.
+ * Returns the length of the encoded data. */
+ int JSON_encode(const TTCN_Typedescriptor_t&, JSON_Tokenizer&) const;
+
+ /** Decodes accordingly to the JSON decoding rules.
+ * Returns the length of the encoded data. */
+ int JSON_decode(const TTCN_Typedescriptor_t&, JSON_Tokenizer&, boolean);
};
extern boolean operator==(asn_null_type par_value, const ASN_NULL& other_value);
}
TTCN_Logger::log_event_str(" }");
}
+
+#ifdef TITAN_RUNTIME_2
+ // Dummy functions, only used in record of/set of in RT2 (the referenced indices
+ // cannot be deleted, since arrays have a fixed size)
+ void add_refd_index(int) {}
+ void remove_refd_index(int) {}
+#endif
};
extern unsigned int get_port_array_index(int index_value,
}
TTCN_Logger::log_event_str(" }");
}
+
+#ifdef TITAN_RUNTIME_2
+ // Dummy functions, only used in record of/set of in RT2 (the referenced indices
+ // cannot be deleted, since arrays have a fixed size)
+ void add_refd_index(int) {}
+ void remove_refd_index(int) {}
+#endif
};
////////////////////////////////////////////////////////////////////////////////
* Returns the length of the decoded data. */
int JSON_decode(const TTCN_Typedescriptor_t&, JSON_Tokenizer&, boolean);
- // Dummy functions, only used in record of/set of (the referenced indices
+#ifdef TITAN_RUNTIME_2
+ // Dummy functions, only used in record of/set of in RT2 (the referenced indices
// cannot be deleted, since arrays have a fixed size)
void add_refd_index(int) {}
void remove_refd_index(int) {}
+#endif
};
template <typename T_type, unsigned int array_size, int index_offset>
#include "JSON.hh"
#include "XmlReader.hh"
#include "Module_list.hh"
+#include "Universal_charstring.hh"
#include <openssl/bn.h>
if(!p_td.xer) TTCN_EncDec_ErrorContext::error_internal(
"No XER descriptor available for type '%s'.", p_td.name);
unsigned XER_coding=va_arg(pvar, unsigned);
- XER_encode(*(p_td.xer),p_buf, XER_coding, 0);
+ XER_encode(*(p_td.xer),p_buf, XER_coding, 0, 0);
p_buf.put_c('\n');
break;}
case TTCN_EncDec::CT_JSON: {
for (int success=reader.Read(); success==1; success=reader.Read()) {
if (reader.NodeType() == XML_READER_TYPE_ELEMENT) break;
}
- XER_decode(*(p_td.xer), reader, XER_coding);
+ XER_decode(*(p_td.xer), reader, XER_coding, 0);
size_t bytes = reader.ByteConsumed();
p_buf.set_pos(bytes);
break;}
}
int Base_Type::XER_encode(const XERdescriptor_t& p_td,
- TTCN_Buffer&, unsigned int, int) const
+ TTCN_Buffer&, unsigned int, int, embed_values_enc_struct_t*) const
{
TTCN_error("XER encoding requested for type '%-.*s' which has no"
" XER encoding method.", p_td.namelens[0]-2, p_td.names[0]);
return 0;
}
-int Base_Type::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap&, unsigned int) {
+int Base_Type::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap&,
+ unsigned int, embed_values_dec_struct_t*) {
TTCN_error("XER decoding requested for type '%-.*s' which has no"
" XER decoding method.", p_td.namelens[0]-2, p_td.names[0]);
return 0;
NULL, &VERDICTTYPE_xer_, &VERDICTTYPE_json_, TTCN_Typedescriptor_t::DONTCARE};
const TTCN_Typedescriptor_t OBJID_descr_={"OBJECT IDENTIFIER", &OBJID_ber_,
- NULL, NULL, &OBJID_xer_, NULL, TTCN_Typedescriptor_t::OBJID};
+ NULL, NULL, &OBJID_xer_, &OBJID_json_, TTCN_Typedescriptor_t::OBJID};
const TTCN_Typedescriptor_t BITSTRING_descr_={"BIT STRING", &BITSTRING_ber_,
&BITSTRING_raw_, NULL, &BITSTRING_xer_, &BITSTRING_json_, TTCN_Typedescriptor_t::DONTCARE};
NULL, NULL, TTCN_Typedescriptor_t::DONTCARE};
const TTCN_Typedescriptor_t ASN_NULL_descr_={"NULL", &ASN_NULL_ber_, NULL,
- NULL, &ASN_NULL_xer_, NULL, TTCN_Typedescriptor_t::DONTCARE};
+ NULL, &ASN_NULL_xer_, &ASN_NULL_json_, TTCN_Typedescriptor_t::DONTCARE};
const TTCN_Typedescriptor_t ASN_ANY_descr_={"ANY", &ASN_ANY_ber_, NULL,
- NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE};
+ NULL, NULL, &ASN_ANY_json_, TTCN_Typedescriptor_t::DONTCARE};
const TTCN_Typedescriptor_t EXTERNAL_descr_={"EXTERNAL", &EXTERNAL_ber_, NULL,
NULL, &EXTERNAL_xer_, NULL, TTCN_Typedescriptor_t::DONTCARE};
NULL, NULL, &UTF8String_xer_, NULL, TTCN_Typedescriptor_t::UTF8STRING};
const TTCN_Typedescriptor_t ASN_ROID_descr_={"RELATIVE-OID", &ASN_ROID_ber_,
- NULL, NULL, &ASN_ROID_xer_, NULL, TTCN_Typedescriptor_t::ROID};
+ NULL, NULL, &ASN_ROID_xer_, &ASN_ROID_json_, TTCN_Typedescriptor_t::ROID};
const TTCN_Typedescriptor_t NumericString_descr_={"NumericString",
&NumericString_ber_, NULL, NULL, &NumericString_xer_, NULL, TTCN_Typedescriptor_t::DONTCARE};
#include "Vector.hh"
#ifdef TITAN_RUNTIME_2
#include "Struct_of.hh"
+#include "XER.hh"
#endif
struct ASN_BERdescriptor_t;
struct TTCN_JSONdescriptor_t;
class XmlReaderWrap;
class Module_Param;
+struct embed_values_enc_struct_t;
+struct embed_values_dec_struct_t;
/** @brief Type descriptor
*
*/
virtual void set_to_present();
/** @} */
-
+
virtual ~Base_Type() { }
#endif
* @param p_buf buffer
* @param flavor one of XER_flavor values
* @param indent indentation level
+ * @param emb_val embed values data (only relevant for record of types)
* @return number of bytes written into the buffer
*/
VIRTUAL_IF_RUNTIME_2 int XER_encode(const XERdescriptor_t& p_td,
- TTCN_Buffer& p_buf, unsigned int flavor, int indent) const;
+ TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t* emb_val) const;
#ifdef TITAN_RUNTIME_2
virtual int XER_encode_negtest(const Erroneous_descriptor_t* /*p_err_descr*/,
const XERdescriptor_t& /*p_td*/, TTCN_Buffer& /*p_buf*/,
- unsigned int /*flavor*/, int /*indent*/) const;
+ unsigned int /*flavor*/, int /*indent*/, embed_values_enc_struct_t* /*emb_val*/) const;
#endif
/** Decode the current object from the supplied buffer.
* @param p_td type descriptor
* @param reader Wrapper around the XML processor
* @param flavor one of XER_flavor values
+ * @param emb_val embed values data (only relevant for record of types)
* @return number of bytes "consumed"
*/
VIRTUAL_IF_RUNTIME_2 int XER_decode(const XERdescriptor_t& p_td,
- XmlReaderWrap& reader, unsigned int flavor);
+ XmlReaderWrap& reader, unsigned int flavor, embed_values_dec_struct_t* emb_val);
/** Return an array of namespace declarations.
*
} *val_ptr;
Erroneous_descriptor_t* err_descr;
- /** Stores the indices of elements that are referenced by 'out' and 'inout' parameters.
- * These elements must not be deleted.*/
- Vector<int> refd_indices;
-
- /** Cached maximum value of \a refd_indices (default: -1).*/
- int max_refd_index;
+ struct refd_index_struct {
+ /** Stores the indices of elements that are referenced by 'out' and 'inout' parameters.
+ * These elements must not be deleted.*/
+ Vector<int> refd_indices;
+
+ /** Cached maximum value of \a refd_indices (default: -1).*/
+ int max_refd_index;
+ } *refd_ind_ptr;
static boolean compare_function(const Record_Of_Type *left_ptr, int left_index, const Record_Of_Type *right_ptr, int right_index);
- Record_Of_Type() : val_ptr(NULL), err_descr(NULL), max_refd_index(-1) {}
+ Record_Of_Type() : val_ptr(NULL), err_descr(NULL), refd_ind_ptr(NULL) {}
Record_Of_Type(null_type other_value);
Record_Of_Type(const Record_Of_Type& other_value);
/// Assignment disabled
virtual int TEXT_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer&, Limit_Token_List&, boolean no_err=FALSE, boolean first_call=TRUE);
virtual int XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf,
- unsigned int flavor, int indent) const;
+ unsigned int flavor, int indent, embed_values_enc_struct_t*) const;
virtual int XER_encode_negtest(const Erroneous_descriptor_t* p_err_descr,
- const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, unsigned flavor, int indent) const;
+ const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, unsigned flavor, int indent, embed_values_enc_struct_t*) const;
/// Helper for XER_encode_negtest
int encode_element(int i, const Erroneous_values_t* err_vals,
const Erroneous_descriptor_t* emb_descr,
- TTCN_Buffer& p_buf, unsigned int flavor, int indent) const;
- virtual int XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, unsigned int);
+ TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t* emb_val) const;
+ virtual int XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, unsigned int, embed_values_dec_struct_t*);
virtual boolean isXerAttribute() const;
virtual boolean isXmlValueList() const;
virtual int TEXT_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer&, Limit_Token_List&, boolean no_err=FALSE, boolean first_call=TRUE);
virtual int XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf,
- unsigned int flavor, int indent) const;
+ unsigned int flavor, int indent, embed_values_enc_struct_t*) const;
virtual int XER_encode_negtest(const Erroneous_descriptor_t* p_err_descr,
const XERdescriptor_t& p_td, TTCN_Buffer& p_buf,
- unsigned int flavor, int indent) const;
- virtual int XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, unsigned int);
+ unsigned int flavor, int indent, embed_values_enc_struct_t*) const;
+ virtual int XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
+ unsigned int, embed_values_dec_struct_t*);
/// @{
/// Methods overridden in the derived (generated) class
virtual int get_xer_num_attr() const { return 0; /* default */ }
private:
/// Helper for XER_encode_negtest
int encode_field(int i, const Erroneous_values_t* err_vals, const Erroneous_descriptor_t* emb_descr,
- TTCN_Buffer& p_buf, unsigned int sub_flavor, int indent) const;
+ TTCN_Buffer& p_buf, unsigned int sub_flavor, int indent, embed_values_enc_struct_t* emb_val) const;
};
////////////////////////////////////////////////////////////////////////////////
virtual int TEXT_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer&, Limit_Token_List&, boolean no_err=FALSE, boolean first_call=TRUE);
virtual int XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf,
- unsigned int flavor, int indent) const;
- virtual int XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, unsigned int);
+ unsigned int flavor, int indent, embed_values_enc_struct_t*) const;
+ virtual int XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
+ unsigned int, embed_values_dec_struct_t*);
/** Encodes accordingly to the JSON encoding rules.
* Returns the length of the encoded data. */
case TTCN_EncDec::CT_XER: {
TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
unsigned XER_coding=va_arg(pvar, unsigned);
- XER_encode(*p_td.xer, p_buf, XER_coding, 0);
+ XER_encode(*p_td.xer, p_buf, XER_coding, 0, 0);
break;}
case TTCN_EncDec::CT_JSON: {
- TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
+ TTCN_EncDec_ErrorContext ec("While JSON-encoding type '%s': ", p_td.name);
if(!p_td.json)
TTCN_EncDec_ErrorContext::error_internal
("No JSON descriptor available for type '%s'.", p_td.name);
, p_td.name);
break;}
case TTCN_EncDec::CT_XER: {
- TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
+ TTCN_EncDec_ErrorContext ec("While XER-decoding type '%s': ", p_td.name);
unsigned XER_coding=va_arg(pvar, unsigned);
XmlReaderWrap reader(p_buf);
int success = reader.Read();
if (type==XML_READER_TYPE_ELEMENT)
break;
}
- XER_decode(*p_td.xer, reader, XER_coding);
+ XER_decode(*p_td.xer, reader, XER_coding, 0);
size_t bytes = reader.ByteConsumed();
p_buf.set_pos(bytes);
break;}
}
int BITSTRING::XER_encode(const XERdescriptor_t& p_td,
- TTCN_Buffer& p_buf, unsigned int flavor, int indent) const
+ TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const
{
if(!is_bound()) {
TTCN_EncDec_ErrorContext::error
}
int BITSTRING::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
- unsigned int flavor)
+ unsigned int flavor, embed_values_dec_struct_t*)
{
int exer = is_exer(flavor);
int success = reader.Ok(), depth = -1, type;
int RAW_decode(const TTCN_Typedescriptor_t& , TTCN_Buffer&, int, raw_order_t,
boolean no_err=FALSE, int sel_field=-1, boolean first_call=TRUE);
- int XER_encode(const XERdescriptor_t&, TTCN_Buffer&, unsigned int, int) const;
- int XER_decode(const XERdescriptor_t&, XmlReaderWrap& reader, unsigned int);
+ int XER_encode(const XERdescriptor_t&, TTCN_Buffer&, unsigned int, int, embed_values_enc_struct_t*) const;
+ int XER_decode(const XERdescriptor_t&, XmlReaderWrap& reader, unsigned int, embed_values_dec_struct_t*);
/** Encodes accordingly to the JSON encoding rules.
* Returns the length of the encoded data. */
case TTCN_EncDec::CT_XER: {
TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
unsigned XER_coding=va_arg(pvar, unsigned);
- XER_encode(*p_td.xer, p_buf, XER_coding, 0);
+ XER_encode(*p_td.xer, p_buf, XER_coding, 0, 0);
break;}
case TTCN_EncDec::CT_JSON: {
TTCN_EncDec_ErrorContext ec("While JSON-encoding type '%s': ", p_td.name);
, p_td.name);
break;}
case TTCN_EncDec::CT_XER: {
- TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
+ TTCN_EncDec_ErrorContext ec("While XER-decoding type '%s': ", p_td.name);
unsigned XER_coding=va_arg(pvar, unsigned);
XmlReaderWrap reader(p_buf);
for (int success = reader.Read(); success==1; success=reader.Read()) {
if (type==XML_READER_TYPE_ELEMENT)
break;
}
- XER_decode(*p_td.xer, reader, XER_coding);
+ XER_decode(*p_td.xer, reader, XER_coding, 0);
size_t bytes = reader.ByteConsumed();
p_buf.set_pos(bytes);
break;}
}
int BOOLEAN::XER_encode(const XERdescriptor_t& p_td,
- TTCN_Buffer& p_buf, unsigned int flavor, int indent) const
+ TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const
{
if(!is_bound()) {
TTCN_EncDec_ErrorContext::error
}
int BOOLEAN::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
- unsigned int flavor)
+ unsigned int flavor, embed_values_dec_struct_t*)
{
const boolean exer = is_exer(flavor);
int XMLValueList = !exer && is_record_of(flavor);
int TEXT_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer&, Limit_Token_List&,
boolean no_err=FALSE, boolean first_call=TRUE);
int XER_encode(const XERdescriptor_t& p_td,
- TTCN_Buffer& p_buf, unsigned int flavor, int indent) const;
+ TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const;
int XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
- unsigned int flavor);
+ unsigned int flavor, embed_values_dec_struct_t*);
/** Encodes accordingly to the JSON encoding rules.
* Returns the length of the encoded data. */
case TTCN_EncDec::CT_XER: {
TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
unsigned XER_coding=va_arg(pvar, unsigned);
- XER_encode(*p_td.xer, p_buf, XER_coding, 0);
+ XER_encode(*p_td.xer, p_buf, XER_coding, 0, 0);
p_buf.put_c('\n');
break;}
case TTCN_EncDec::CT_JSON: {
, p_td.name);
break;}
case TTCN_EncDec::CT_XER: {
- TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
+ TTCN_EncDec_ErrorContext ec("While XER-decoding type '%s': ", p_td.name);
unsigned XER_coding=va_arg(pvar, unsigned);
XmlReaderWrap reader(p_buf);
int success = reader.Read();
if (type==XML_READER_TYPE_ELEMENT)
break;
}
- XER_decode(*p_td.xer, reader, XER_coding);
+ XER_decode(*p_td.xer, reader, XER_coding, 0);
size_t bytes = reader.ByteConsumed();
p_buf.set_pos(bytes);
break;}
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int CHARSTRING::XER_encode(const XERdescriptor_t& p_td,
- TTCN_Buffer& p_buf, unsigned int flavor, int indent) const
+ TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const
{
if(!is_bound()) {
TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,
}
int CHARSTRING::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
- unsigned int flavor) {
+ unsigned int flavor, embed_values_dec_struct_t*) {
int exer = is_exer(flavor);
int success = reader.Ok(), depth = -1;
TTCN_Buffer&) const;
int TEXT_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer&, Limit_Token_List&,
boolean no_err=FALSE, boolean first_call=TRUE);
- int XER_encode(const XERdescriptor_t&, TTCN_Buffer&, unsigned int, int) const;
- int XER_decode(const XERdescriptor_t&, XmlReaderWrap& reader, unsigned int);
+ int XER_encode(const XERdescriptor_t&, TTCN_Buffer&, unsigned int, int, embed_values_enc_struct_t*) const;
+ int XER_decode(const XERdescriptor_t&, XmlReaderWrap& reader, unsigned int, embed_values_dec_struct_t*);
/** Returns the charstring in the format a string would appear in C or TTCN-3 code.
* Inserts double quotation marks to the beginning and end of the string and
case TTCN_EncDec::CT_XER: {
TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
unsigned XER_coding=va_arg(pvar, unsigned);
- XER_encode(*p_td.xer, p_buf, XER_coding, 0);
+ XER_encode(*p_td.xer, p_buf, XER_coding, 0, 0);
break;}
case TTCN_EncDec::CT_JSON: {
TTCN_EncDec_ErrorContext ec("While JSON-encoding type '%s': ", p_td.name);
, p_td.name);
break;}
case TTCN_EncDec::CT_XER: {
- TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
+ TTCN_EncDec_ErrorContext ec("While XER-decoding type '%s': ", p_td.name);
unsigned XER_coding=va_arg(pvar, unsigned);
XmlReaderWrap reader(p_buf);
for (int success = reader.Read(); success==1; success=reader.Read()) {
if (type==XML_READER_TYPE_ELEMENT)
break;
}
- XER_decode(*p_td.xer, reader, XER_coding);
+ XER_decode(*p_td.xer, reader, XER_coding, 0);
size_t bytes = reader.ByteConsumed();
p_buf.set_pos(bytes);
break;}
}
int FLOAT::XER_encode(const XERdescriptor_t& p_td,
- TTCN_Buffer& p_buf, unsigned int flavor, int indent) const
+ TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const
{
if(!is_bound()) {
TTCN_EncDec_ErrorContext::error(
}
int FLOAT::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
- unsigned int flavor)
+ unsigned int flavor, embed_values_dec_struct_t*)
{
int exer = is_exer(flavor);
int success = reader.Ok(), depth = -1;
int sel_field=-1, boolean first_call=TRUE);
int XER_encode(const XERdescriptor_t& p_td,
- TTCN_Buffer& p_buf, unsigned int flavor, int indent) const;
+ TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const;
int XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
- unsigned int flavor);
+ unsigned int flavor, embed_values_dec_struct_t*);
/** Encodes accordingly to the JSON encoding rules.
* Returns the length of the encoded data. */
case TTCN_EncDec::CT_XER: {
TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
unsigned XER_coding=va_arg(pvar, unsigned);
- XER_encode(*p_td.xer, p_buf, XER_coding, 0);
+ XER_encode(*p_td.xer, p_buf, XER_coding, 0, 0);
break;}
case TTCN_EncDec::CT_JSON: {
TTCN_EncDec_ErrorContext ec("While JSON-encoding type '%s': ", p_td.name);
" message was received", p_td.name);
break;}
case TTCN_EncDec::CT_XER: {
- TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
+ TTCN_EncDec_ErrorContext ec("While XER-decoding type '%s': ", p_td.name);
unsigned XER_coding=va_arg(pvar, unsigned);
XmlReaderWrap reader(p_buf);
int success = reader.Read();
if (type==XML_READER_TYPE_ELEMENT)
break;
}
- XER_decode(*p_td.xer, reader, XER_coding);
+ XER_decode(*p_td.xer, reader, XER_coding, 0);
size_t bytes = reader.ByteConsumed();
p_buf.set_pos(bytes);
break;}
case TTCN_EncDec::CT_JSON: {
- TTCN_EncDec_ErrorContext ec("While JSON-encoding type '%s': ", p_td.name);
+ TTCN_EncDec_ErrorContext ec("While JSON-decoding type '%s': ", p_td.name);
if(!p_td.json)
TTCN_EncDec_ErrorContext::error_internal
("No JSON descriptor available for type '%s'.", p_td.name);
extern const char cb64[];
int HEXSTRING::XER_encode(const XERdescriptor_t& p_td,
- TTCN_Buffer& p_buf, unsigned int flavor, int indent) const
+ TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const
{
if(!is_bound()) {
TTCN_EncDec_ErrorContext::error
*/
int HEXSTRING::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
- unsigned int flavor)
+ unsigned int flavor, embed_values_dec_struct_t*)
{
int exer = is_exer(flavor);
int success = reader.Ok(), depth = -1, type;
int RAW_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer&, int, raw_order_t,
boolean no_err=FALSE, int sel_field=-1, boolean first_call=TRUE);
int XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf,
- unsigned int flavor, int indent) const;
+ unsigned int flavor, int indent, embed_values_enc_struct_t*) const;
int XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
- unsigned int flavor);
+ unsigned int flavor, embed_values_dec_struct_t*);
/** Encodes accordingly to the JSON encoding rules.
* Returns the length of the encoded data. */
case TTCN_EncDec::CT_XER: {
TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
unsigned XER_coding=va_arg(pvar, unsigned);
- XER_encode(*p_td.xer, p_buf, XER_coding, 0);
+ XER_encode(*p_td.xer, p_buf, XER_coding, 0, 0);
break;}
case TTCN_EncDec::CT_JSON: {
TTCN_EncDec_ErrorContext ec("While JSON-encoding type '%s': ", p_td.name);
if (type==XML_READER_TYPE_ELEMENT)
break;
}
- XER_decode(*p_td.xer, reader, XER_coding);
+ XER_decode(*p_td.xer, reader, XER_coding, 0);
size_t bytes = reader.ByteConsumed();
p_buf.set_pos(bytes);
break;}
}
int INTEGER::XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf,
- unsigned int flavor, int indent) const
+ unsigned int flavor, int indent, embed_values_enc_struct_t*) const
{
if (!is_bound()) {
TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,
}
int INTEGER::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
- unsigned int flavor)
+ unsigned int flavor, embed_values_dec_struct_t*)
{
const boolean exer = is_exer(flavor);
int depth = -1, success = reader.Ok(), type;
/** @brief Encode according to XML Encoding Rules.
**/
int XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, unsigned int flavor,
- int indent) const;
+ int indent, embed_values_enc_struct_t*) const;
/** @brief Decode according to XML Encoding Rules.
**/
int XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
- unsigned int flavor);
+ unsigned int flavor, embed_values_dec_struct_t*);
/** Encodes accordingly to the JSON encoding rules.
* Returns the length of the encoded data. */
const TTCN_JSONdescriptor_t VideotexString_json_ = { false, NULL, false, NULL };
const TTCN_JSONdescriptor_t VisibleString_json_ = { false, NULL, false, NULL };
+
+const TTCN_JSONdescriptor_t ASN_NULL_json_ = { false, NULL, false, NULL };
+
+const TTCN_JSONdescriptor_t OBJID_json_ = { false, NULL, false, NULL };
+
+const TTCN_JSONdescriptor_t ASN_ROID_json_ = { false, NULL, false, NULL };
+
+const TTCN_JSONdescriptor_t ASN_ANY_json_ = { false, NULL, false, NULL };
+
+const TTCN_JSONdescriptor_t ENUMERATED_json_ = { false, NULL, false, NULL };
extern const TTCN_JSONdescriptor_t TeletexString_json_;
extern const TTCN_JSONdescriptor_t VideotexString_json_;
extern const TTCN_JSONdescriptor_t VisibleString_json_;
+extern const TTCN_JSONdescriptor_t ASN_NULL_json_;
+extern const TTCN_JSONdescriptor_t OBJID_json_;
+extern const TTCN_JSONdescriptor_t ASN_ROID_json_;
+extern const TTCN_JSONdescriptor_t ASN_ANY_json_;
+extern const TTCN_JSONdescriptor_t ENUMERATED_json_;
/** JSON decoder error codes */
enum json_decode_error {
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 $(RT2_SOURCES)
+Verdicttype.cc XER.cc XmlReader.cc TitanLoggerControlImpl.cc TCov.cc JSON.cc \
+Profiler.cc $(RT2_SOURCES)
# Keep GENERATED_SOURCES at the beginning. This may speed up parallel builds
# by starting early the compilation of the largest files.
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
+JSON.hh Profiler.hh
# Copied during "make install"
ifdef REGEX_DIR
case TTCN_EncDec::CT_XER: {
TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
unsigned XER_coding=va_arg(pvar, unsigned);
- XER_encode(*p_td.xer, p_buf, XER_coding, 0);
+ XER_encode(*p_td.xer, p_buf, XER_coding, 0, 0);
+ break;}
+ case TTCN_EncDec::CT_JSON: {
+ TTCN_EncDec_ErrorContext ec("While JSON-encoding type '%s': ", p_td.name);
+ if(!p_td.json)
+ TTCN_EncDec_ErrorContext::error_internal
+ ("No JSON descriptor available for type '%s'.", p_td.name);
+ JSON_Tokenizer tok(va_arg(pvar, int) != 0);
+ JSON_encode(p_td, tok);
+ p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());
break;}
default:
TTCN_error("Unknown coding method requested to encode type '%s'",
("No RAW descriptor available for type '%s'.", p_td.name);
break;}
case TTCN_EncDec::CT_XER: {
- TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
+ TTCN_EncDec_ErrorContext ec("While XER-decoding type '%s': ", p_td.name);
unsigned XER_coding=va_arg(pvar, unsigned);
XmlReaderWrap reader(p_buf);
int success = reader.Read();
if (type==XML_READER_TYPE_ELEMENT)
break;
}
- XER_decode(*p_td.xer, reader, XER_coding);
+ XER_decode(*p_td.xer, reader, XER_coding, 0);
size_t bytes = reader.ByteConsumed();
p_buf.set_pos(bytes);
break;}
+ case TTCN_EncDec::CT_JSON: {
+ TTCN_EncDec_ErrorContext ec("While JSON-decoding type '%s': ", p_td.name);
+ if(!p_td.json)
+ TTCN_EncDec_ErrorContext::error_internal
+ ("No JSON descriptor available for type '%s'.", p_td.name);
+ JSON_Tokenizer tok((const char*)p_buf.get_data(), p_buf.get_len());
+ if(JSON_decode(p_td, tok, false)<0)
+ ec.error(TTCN_EncDec::ET_INCOMPL_MSG,
+ "Can not decode type '%s', because invalid or incomplete"
+ " message was received"
+ , p_td.name);
+ p_buf.set_pos(tok.get_buf_pos());
+ break;}
default:
TTCN_error("Unknown coding method requested to decode type '%s'",
p_td.name);
int OBJID::XER_encode(const XERdescriptor_t& p_td,
- TTCN_Buffer& p_buf, unsigned int flavor, int indent ) const
+ TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const
{
if(!is_bound()) {
TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,
return (int)p_buf.get_len() - encoded_length;
}
+void OBJID::from_string(char* p_str)
+{
+ // Count dots to find number of components. (1 dot = 2 components, etc.)
+ unsigned comps = 1;
+ const char *p;
+ for (p = p_str; *p != 0; ++p) {
+ if (*p == '.') ++comps;
+ }
+ // p now points at the end of the string. If it was empty, then there were
+ // no components; compensate the fact that we started at 1.
+ init_struct((p != p_str) ? comps : 0);
+
+ char *beg, *end = 0;
+ comps = 0;
+ for (beg = p_str; beg < p; ++beg) {
+ errno = 0;
+ long ret = strtol(beg, &end, 10);
+ if (errno) break;
+
+ // TODO check value for too big ?
+ (*this)[comps++] = ret;
+ beg = end; // move to the dot; will move past it when incremented
+ }
+}
+
int OBJID::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
- unsigned int flavor)
+ unsigned int flavor, embed_values_dec_struct_t*)
{
int exer = is_exer(flavor);
int success = reader.Ok(), depth = -1;
TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG, "Bogus object identifier");
return 0;
}
- // Count dots to find number of components. (1 dot = 2 components, etc.)
- unsigned comps = 1;
- const char *p;
- for (p = val; *p != 0; ++p) {
- if (*p == '.') ++comps;
- }
- // p now points at the end of the string. If it was empty, then there were
- // no components; compensate the fact that we started at 1.
- init_struct((p != val) ? comps : 0);
-
- char *beg, *end = 0;
- comps = 0;
- for (beg = val; beg < p; ++beg) {
- errno = 0;
- long ret = strtol(beg, &end, 10);
- if (errno) break;
-
- // TODO check value for too big ?
- (*this)[comps++] = ret;
- beg = end; // move to the dot; will move past it when incremented
- }
+
+ from_string(val);
xmlFree(val);
}
return 1; // decode successful
}
+int OBJID::JSON_encode(const TTCN_Typedescriptor_t&, JSON_Tokenizer& p_tok) const
+{
+ if (!is_bound()) {
+ TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,
+ "Encoding an unbound object identifier value.");
+ return -1;
+ }
+
+ char* objid_str = mcopystrn("\"", 1);
+ for (int i = 0; i < val_ptr->n_components; ++i) {
+ objid_str = mputprintf(objid_str, "%s" OBJID_FMT, (i > 0 ? "." : ""), val_ptr->components_ptr[i]);
+ }
+ objid_str = mputstrn(objid_str, "\"", 1);
+ int enc_len = p_tok.put_next_token(JSON_TOKEN_STRING, objid_str);
+ Free(objid_str);
+ return enc_len;
+}
+
+int OBJID::JSON_decode(const TTCN_Typedescriptor_t& p_td, JSON_Tokenizer& p_tok, boolean p_silent)
+{
+ json_token_t token = JSON_TOKEN_NONE;
+ char* value = 0;
+ size_t value_len = 0;
+ boolean error = false;
+ int dec_len = 0;
+ boolean use_default = p_td.json->default_value && 0 == p_tok.get_buffer_length();
+ if (use_default) {
+ // No JSON data in the buffer -> use default value
+ value = (char*)p_td.json->default_value;
+ value_len = strlen(value);
+ } else {
+ dec_len = p_tok.get_next_token(&token, &value, &value_len);
+ }
+ if (JSON_TOKEN_ERROR == token) {
+ JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_BAD_TOKEN_ERROR, "");
+ return JSON_ERROR_FATAL;
+ }
+ else if (JSON_TOKEN_STRING == token || use_default) {
+ if (use_default || (value_len > 2 && value[0] == '\"' && value[value_len - 1] == '\"')) {
+ if (!use_default) {
+ // The default value doesn't have quotes around it
+ value_len -= 2;
+ ++value;
+ }
+ // need a null-terminated string
+ char* value2 = mcopystrn(value, value_len);
+ from_string(value2);
+ Free(value2);
+ }
+ }
+ else {
+ return JSON_ERROR_INVALID_TOKEN;
+ }
+
+ if (error) {
+ JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_FORMAT_ERROR, "string", "object identifier");
+ if (p_silent) {
+ clean_up();
+ }
+ return JSON_ERROR_FATAL;
+ }
+ return dec_len;
+}
void OBJID_template::clean_up()
{
void init_struct(int n_components);
void copy_value();
+
+ /** Initializes the object identifier with a string containing the components
+ * separated by dots. */
+ void from_string(char* p_str);
public:
typedef unsigned int objid_element;
boolean BER_decode_TLV(const TTCN_Typedescriptor_t& p_td,
const ASN_BER_TLV_t& p_tlv, unsigned L_form);
int XER_encode(const XERdescriptor_t& p_td,
- TTCN_Buffer& p_buf, unsigned int flavor, int indent) const;
+ TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const;
int XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
- unsigned int flavor);
+ unsigned int flavor, embed_values_dec_struct_t*);
+
+ /** Encodes accordingly to the JSON encoding rules.
+ * Returns the length of the encoded data. */
+ int JSON_encode(const TTCN_Typedescriptor_t&, JSON_Tokenizer&) const;
+
+ /** Decodes accordingly to the JSON decoding rules.
+ * Returns the length of the encoded data. */
+ int JSON_decode(const TTCN_Typedescriptor_t&, JSON_Tokenizer&, boolean);
};
// objid template class
case TTCN_EncDec::CT_XER: {
TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
unsigned XER_coding=va_arg(pvar, unsigned);
- XER_encode(*p_td.xer, p_buf, XER_coding, 0);
+ XER_encode(*p_td.xer, p_buf, XER_coding, 0, 0);
break;}
case TTCN_EncDec::CT_JSON: {
TTCN_EncDec_ErrorContext ec("While TEXT-encoding type '%s': ", p_td.name);
, p_td.name);
break;}
case TTCN_EncDec::CT_XER: {
- TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
+ TTCN_EncDec_ErrorContext ec("While XER-decoding type '%s': ", p_td.name);
unsigned XER_coding=va_arg(pvar, unsigned);
XmlReaderWrap reader(p_buf);
int success = reader.Read();
if (type==XML_READER_TYPE_ELEMENT)
break;
}
- XER_decode(*p_td.xer, reader, XER_coding);
+ XER_decode(*p_td.xer, reader, XER_coding, 0);
size_t bytes = reader.ByteConsumed();
p_buf.set_pos(bytes);
break;}
extern const char cb64[];
int OCTETSTRING::XER_encode(const XERdescriptor_t& p_td,
- TTCN_Buffer& p_buf, unsigned int flavor, int indent) const
+ TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const
{
if(!is_bound()) {
TTCN_EncDec_ErrorContext::error
}
int OCTETSTRING::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
- unsigned int flavor)
+ unsigned int flavor, embed_values_dec_struct_t*)
{
int exer = is_exer(flavor);
int success = reader.Ok(), depth = -1, type;
int TEXT_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer&, Limit_Token_List&,
boolean no_err=FALSE, boolean first_call=TRUE);
int XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf,
- unsigned int flavor, int indent) const;
+ unsigned int flavor, int indent, embed_values_enc_struct_t*) const;
int XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
- unsigned int flavor);
+ unsigned int flavor, embed_values_dec_struct_t*);
/** Encodes accordingly to the JSON encoding rules.
* Returns the length of the encoded data. */
template <typename T_type>
class OPTIONAL : public Base_Type {
+ /** The value, if present (owned by OPTIONAL)
+ * In Runtime2 the pointer is null, when the value is not present.
+ * In Runtime1 its presence is indicated by the optional_selection member. */
+ T_type *optional_value;
+
/** Specifies the state of the optional field
- * @tricky The optional value can be modified through parameter references,
+ * @tricky In Runtime2 the optional value can be modified through parameter references,
* in which case this member variable will not be updated. Always use the function
* get_selection() instead of directly referencing this variable. */
- optional_sel optional_selection;
-
- /** The value, if present (owned by OPTIONAL) */
- T_type *optional_value;
+ optional_sel optional_selection;
+#ifdef TITAN_RUNTIME_2
/** Stores the number of elements referenced by 'out' and 'inout' parameters,
- * if the optional field is a record of/set of/array.
+ * if the optional field is a record of/set of/array (only in Runtime2).
* If at least one element is referenced, the value must not be deleted. */
- int param_refs;
+ int param_refs;
+#endif
/** Set the optional value to present.
* If the value was already present, does nothing.
void set_to_present() {
if (optional_selection != OPTIONAL_PRESENT) {
optional_selection = OPTIONAL_PRESENT;
- if (optional_value == NULL) {
+#ifdef TITAN_RUNTIME_2
+ if (optional_value == NULL)
+#endif
optional_value = new T_type;
- }
}
}
inline
#endif
void set_to_omit() {
+#ifdef TITAN_RUNTIME_2
if (is_present()) {
if (param_refs > 0) {
optional_value->clean_up();
optional_value = NULL;
}
}
+#else
+ if (optional_selection == OPTIONAL_PRESENT) {
+ delete optional_value;
+ }
+#endif
optional_selection = OPTIONAL_OMIT;
}
public:
/// Default constructor creates an unbound object
- OPTIONAL() : optional_selection(OPTIONAL_UNBOUND), optional_value(NULL), param_refs(0) { }
+ OPTIONAL() : optional_value(NULL), optional_selection(OPTIONAL_UNBOUND)
+#ifdef TITAN_RUNTIME_2
+ , param_refs(0)
+#endif
+ { }
/// Construct an optional object set to omit.
/// @p other_value must be OMIT_VALUE, or else dynamic testcase error.
/// Construct from an object of different type
template <typename T_tmp>
OPTIONAL(const T_tmp& other_value)
- : optional_selection(OPTIONAL_PRESENT),
- optional_value(new T_type(other_value)),
- param_refs(0) { }
+ : optional_value(new T_type(other_value))
+ , optional_selection(OPTIONAL_PRESENT)
+#ifdef TITAN_RUNTIME_2
+ , param_refs(0)
+#endif
+ { }
- ~OPTIONAL()
- { if (NULL != optional_value) delete optional_value; }
+ ~OPTIONAL() {
+#ifdef TITAN_RUNTIME_2
+ if (NULL != optional_value)
+#else
+ if (optional_selection == OPTIONAL_PRESENT)
+#endif
+ delete optional_value;
+ }
void clean_up();
{ return is_equal(other_value); }
#endif
+#ifdef TITAN_RUNTIME_2
boolean is_bound() const;
+#else
+ inline boolean is_bound() const { return optional_selection != OPTIONAL_UNBOUND; }
+#endif
boolean is_value() const
{ return optional_selection == OPTIONAL_PRESENT && optional_value->is_value(); }
/** Whether the optional value is present.
* @return \c true if optional_selection is OPTIONAL_PRESENT, else \c false */
+#ifdef TITAN_RUNTIME_2
boolean is_present() const;
+#else
+ inline boolean is_present() const { return optional_selection==OPTIONAL_PRESENT; }
+#endif
#ifdef TITAN_RUNTIME_2
/** @name override virtual functions of Base_Type
*/
boolean ispresent() const;
+#ifdef TITAN_RUNTIME_2
/** @tricky Calculates and returns the actual state of the optional object,
- * not just the optional_selection member. */
+ * not just the optional_selection member.
+ * (Only needed in Runtime2, in Runtime1 optional_selection is always up to date.) */
optional_sel get_selection() const;
+#else
+ inline optional_sel get_selection() const { return optional_selection; }
+#endif
void log() const;
void set_param(Module_Param& param);
raw_order_t top_bit_ord, boolean no_err=FALSE, int sel_field=-1, boolean first_call=TRUE);
#endif
- int XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& buf, unsigned int flavor, int indent) const;
+ int XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& buf, unsigned int flavor,
+ int indent, embed_values_enc_struct_t* emb_val) const;
#ifdef TITAN_RUNTIME_2
int XER_encode_negtest(const Erroneous_descriptor_t* p_err_descr,
- const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, unsigned int flavor, int indent) const;
+ const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, unsigned int flavor,
+ int indent, embed_values_enc_struct_t* emb_val) const;
#endif
/** Used during XML decoding, in case this object is an AnyElement field in a record.
* Determines whether XER_decode() should be called or this field should be omitted.
* @param next_field_name name of the next field in the record, or null if this is the last one
* @param parent_tag_closed true, if the record's XML tag is closed (is an empty element)*/
bool XER_check_any_elem(XmlReaderWrap& reader, const char* next_field_name, bool parent_tag_closed);
- int XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, unsigned int flavor);
+ int XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
+ unsigned int flavor, embed_values_dec_struct_t* emb_val);
char ** collect_ns(const XERdescriptor_t& p_td, size_t& num, bool& def_ns) const;
* Returns the length of the decoded data. */
int JSON_decode(const TTCN_Typedescriptor_t&, JSON_Tokenizer&, boolean);
+#ifdef TITAN_RUNTIME_2
/** Called before an element of an optional record of/set of is indexed and passed as an
- * 'inout' or 'out' parameter to a function.
+ * 'inout' or 'out' parameter to a function (only in Runtime2).
* Sets the optional value to present (this would be done by the indexing operation
* anyway) and redirects the call to the optional value. */
void add_refd_index(int index);
/** Called after an element of an optional record of/set of is passed as an
- * 'inout' or 'out' parameter to a function.
+ * 'inout' or 'out' parameter to a function (only in Runtime2).
* Redirects the call to the optional value. */
void remove_refd_index(int index);
+#endif
/** Called before an element of an optional record of/set of is passed as an
* 'inout' or 'out' parameter to a function. Returns the size of the record of/
template<typename T_type>
Base_Type* OPTIONAL<T_type>::get_opt_value()
{
+#ifdef TITAN_RUNTIME_2
if (!is_present())
+#else
+ if (optional_selection!=OPTIONAL_PRESENT)
+#endif
TTCN_error("Internal error: get_opt_value() called on a non-present optional field.");
return optional_value;
}
template<typename T_type>
const Base_Type* OPTIONAL<T_type>::get_opt_value() const
{
+#ifdef TITAN_RUNTIME_2
if (!is_present())
+#else
+ if (optional_selection!=OPTIONAL_PRESENT)
+#endif
TTCN_error("Internal error: get_opt_value() const called on a non-present optional field.");
return optional_value;
}
template<typename T_type>
boolean OPTIONAL<T_type>::is_seof() const
{
- return (is_present()) ? optional_value->is_seof() : T_type().is_seof();
+ return
+#ifdef TITAN_RUNTIME_2
+ (is_present())
+#else
+ (optional_selection==OPTIONAL_PRESENT)
+#endif
+ ? optional_value->is_seof() : T_type().is_seof();
}
template<typename T_type>
const TTCN_Typedescriptor_t* OPTIONAL<T_type>::get_descriptor() const
{
- return (is_present()) ? optional_value->get_descriptor() : T_type().get_descriptor();
+ return
+#ifdef TITAN_RUNTIME_2
+ (is_present())
+#else
+ (optional_selection==OPTIONAL_PRESENT)
+#endif
+ ? optional_value->get_descriptor() : T_type().get_descriptor();
}
#endif
template<typename T_type>
OPTIONAL<T_type>::OPTIONAL(template_sel other_value)
- : optional_selection(OPTIONAL_OMIT), optional_value(NULL), param_refs(0)
+ : optional_value(NULL), optional_selection(OPTIONAL_OMIT)
+#ifdef TITAN_RUNTIME_2
+ , param_refs(0)
+#endif
{
if (other_value != OMIT_VALUE)
TTCN_error("Setting an optional field to an invalid value.");
template<typename T_type>
OPTIONAL<T_type>::OPTIONAL(const OPTIONAL& other_value)
: Base_Type(other_value)
- , optional_selection(other_value.optional_selection)
, optional_value(NULL)
+ , optional_selection(other_value.optional_selection)
+#ifdef TITAN_RUNTIME_2
, param_refs(0)
+#endif
{
switch (other_value.optional_selection) {
case OPTIONAL_PRESENT:
template<typename T_type> template<typename T_tmp>
OPTIONAL<T_type>::OPTIONAL(const OPTIONAL<T_tmp>& other_value)
- : optional_selection(other_value.get_selection()), optional_value(NULL), param_refs(0)
+ : optional_value(NULL), optional_selection(other_value.get_selection())
+#ifdef TITAN_RUNTIME_2
+ , param_refs(0)
+#endif
{
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
template<typename T_type>
void OPTIONAL<T_type>::clean_up()
{
+#ifdef TITAN_RUNTIME_2
if (is_present()) {
if (param_refs > 0) {
optional_value->clean_up();
optional_value = NULL;
}
}
+#else
+ if (OPTIONAL_PRESENT == optional_selection) {
+ delete optional_value;
+ }
+#endif
optional_selection = OPTIONAL_UNBOUND;
}
{
switch (other_value.optional_selection) {
case OPTIONAL_PRESENT:
- optional_selection = OPTIONAL_PRESENT;
+#ifdef TITAN_RUNTIME_2
if (NULL == optional_value) {
+#else
+ if (optional_selection != OPTIONAL_PRESENT) {
+#endif
optional_value = new T_type(*other_value.optional_value);
+ optional_selection = OPTIONAL_PRESENT;
} else *optional_value = *other_value.optional_value;
break;
case OPTIONAL_OMIT:
{
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
- optional_selection = OPTIONAL_PRESENT;
+#ifdef TITAN_RUNTIME_2
if (NULL == optional_value) {
+#else
+ if (optional_selection != OPTIONAL_PRESENT) {
+#endif
optional_value = new T_type((const T_tmp&)other_value);
+ optional_selection = OPTIONAL_PRESENT;
} else *optional_value = (const T_tmp&)other_value;
break;
case OPTIONAL_OMIT:
OPTIONAL<T_type>&
OPTIONAL<T_type>::operator=(const T_tmp& other_value)
{
- optional_selection = OPTIONAL_PRESENT;
+#ifdef TITAN_RUNTIME_2
if (NULL == optional_value) {
+#else
+ if (optional_selection != OPTIONAL_PRESENT) {
+#endif
optional_value = new T_type(other_value);
+ optional_selection = OPTIONAL_PRESENT;
} else *optional_value = other_value;
return *this;
}
template<typename T_type>
boolean OPTIONAL<T_type>::is_equal(template_sel other_value) const
{
+#ifdef TITAN_RUNTIME_2
if (!is_bound()) {
+#else
+ if (optional_selection == OPTIONAL_UNBOUND) {
+#endif
if (other_value == UNINITIALIZED_TEMPLATE) return TRUE;
TTCN_error("The left operand of comparison is an unbound optional value.");
}
if (other_value != OMIT_VALUE) TTCN_error("Internal error: The right operand "
"of comparison is an invalid value.");
- return !is_present();
+ return
+#ifdef TITAN_RUNTIME_2
+ !is_present();
+#else
+ optional_selection == OPTIONAL_OMIT;
+#endif
}
template<typename T_type>
boolean OPTIONAL<T_type>::is_equal(const OPTIONAL& other_value) const
{
+#ifdef TITAN_RUNTIME_2
if (!is_bound()) {
- if (!other_value.is_bound()) return TRUE;
+ if (!other_value.is_bound())
+#else
+ if (optional_selection == OPTIONAL_UNBOUND) {
+ if (other_value.optional_selection == OPTIONAL_UNBOUND)
+#endif
+ return TRUE;
TTCN_error("The left operand of "
"comparison is an unbound optional value.");
}
+#ifdef TITAN_RUNTIME_2
if (!other_value.is_bound())
+#else
+ if (other_value.optional_selection == OPTIONAL_UNBOUND)
+#endif
TTCN_error("The right operand of comparison is an unbound optional value.");
+#ifdef TITAN_RUNTIME_2
boolean present = is_present();
if (present != other_value.is_present()) return FALSE;
else if (present)
+#else
+ if (optional_selection != other_value.optional_selection) return FALSE;
+ else if (optional_selection == OPTIONAL_PRESENT)
+#endif
return *optional_value == *other_value.optional_value;
else return TRUE;
}
template<typename T_type> template <typename T_tmp>
boolean OPTIONAL<T_type>::is_equal(const T_tmp& other_value) const
{
+#ifdef TITAN_RUNTIME_2
switch (get_selection()) {
+#else
+ switch (optional_selection) {
+#endif
case OPTIONAL_PRESENT:
return *optional_value == other_value;
case OPTIONAL_OMIT:
template<typename T_type> template <typename T_tmp>
boolean OPTIONAL<T_type>::is_equal(const OPTIONAL<T_tmp>& other_value) const
{
+#ifdef TITAN_RUNTIME_2
if (!is_bound()) {
- if (!other_value.is_bound()) return TRUE;
+ if (!other_value.is_bound())
+#else
+ optional_sel other_selection = other_value.get_selection();
+ if (optional_selection == OPTIONAL_UNBOUND) {
+ if (other_selection == OPTIONAL_UNBOUND)
+#endif
+ return TRUE;
TTCN_error("The left operand of "
"comparison is an unbound optional value.");
}
- if (!other_value.is_bound()) TTCN_error("The right operand of "
- "comparison is an unbound optional value.");
+#ifdef TITAN_RUNTIME_2
+ if (!other_value.is_bound())
+#else
+ if (other_selection == OPTIONAL_UNBOUND)
+#endif
+ TTCN_error("The right operand of comparison is an unbound optional value.");
+#ifdef TITAN_RUNTIME_2
boolean present = is_present();
if (present != other_value.is_present()) return FALSE;
else if (present)
+#else
+ if (optional_selection != other_selection) return FALSE;
+ else if (optional_selection == OPTIONAL_PRESENT)
+#endif
return *optional_value == (const T_tmp&)other_value;
else return TRUE;
}
+#ifdef TITAN_RUNTIME_2
template<typename T_type>
boolean OPTIONAL<T_type>::is_bound() const
{
return FALSE;
}
}
+#endif
template<typename T_type>
boolean OPTIONAL<T_type>::ispresent() const
case OPTIONAL_PRESENT:
return TRUE;
case OPTIONAL_OMIT:
+#ifdef TITAN_RUNTIME_2
if (NULL != optional_value) {
return optional_value->is_bound();
}
+#endif
return FALSE;
default:
+#ifdef TITAN_RUNTIME_2
if (NULL != optional_value && optional_value->is_bound()) {
return TRUE;
}
+#endif
TTCN_error("Using an unbound optional field.");
- return FALSE;
}
+ return FALSE;
}
+#ifdef TITAN_RUNTIME_2
template<typename T_type>
optional_sel OPTIONAL<T_type>::get_selection() const
{
}
return OPTIONAL_UNBOUND;
}
+#endif
template<typename T_type>
void OPTIONAL<T_type>::log() const
{
+#ifdef TITAN_RUNTIME_2
switch (get_selection()) {
+#else
+ switch (optional_selection) {
+#endif
case OPTIONAL_PRESENT:
optional_value->log();
break;
template<typename T_type>
void OPTIONAL<T_type>::encode_text(Text_Buf& text_buf) const
{
+#ifdef TITAN_RUNTIME_2
switch (get_selection()) {
+#else
+ switch (optional_selection) {
+#endif
case OPTIONAL_OMIT:
text_buf.push_int((RInt)FALSE);
break;
template<typename T_type>
int OPTIONAL<T_type>::JSON_encode(const TTCN_Typedescriptor_t& p_td, JSON_Tokenizer& p_tok) const
{
+#ifdef TITAN_RUNTIME_2
switch(get_selection()) {
+#else
+ switch(optional_selection) {
+#endif
case OPTIONAL_PRESENT:
return optional_value->JSON_encode(p_td, p_tok);
case OPTIONAL_OMIT:
template<typename T_type>
int OPTIONAL<T_type>::JSON_decode(const TTCN_Typedescriptor_t& p_td, JSON_Tokenizer& p_tok, boolean p_silent)
{
+ // try the optional value first
+ set_to_present();
size_t buf_pos = p_tok.get_buf_pos();
- json_token_t token = JSON_TOKEN_NONE;
- int dec_len = p_tok.get_next_token(&token, NULL, NULL);
- if (JSON_TOKEN_ERROR == token) {
- JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_BAD_TOKEN_ERROR, "");
- dec_len = JSON_ERROR_FATAL;
- }
- else if (JSON_TOKEN_LITERAL_NULL == token) {
- set_to_omit();
+ int dec_len = optional_value->JSON_decode(p_td, p_tok, p_silent);
+ if (JSON_ERROR_FATAL == dec_len) {
+ if (p_silent) {
+ clean_up();
+ } else {
+ set_to_omit();
+ }
}
- else {
- // read the token again
- set_to_present();
+ else if (JSON_ERROR_INVALID_TOKEN == dec_len) {
+ // invalid token, rewind the buffer and check if it's a "null" (= omit)
+ // this needs to be checked after the optional value, because it might also be
+ // able to decode a "null" value
p_tok.set_buf_pos(buf_pos);
- int ret_val = optional_value->JSON_decode(p_td, p_tok, p_silent);
- if (0 > ret_val) {
- if (p_silent) {
- clean_up();
- } else {
- set_to_omit();
- }
+ json_token_t token = JSON_TOKEN_NONE;
+ dec_len = p_tok.get_next_token(&token, NULL, NULL);
+ if (JSON_TOKEN_LITERAL_NULL == token) {
+ set_to_omit();
+ }
+ else {
+ // cannot get JSON_TOKEN_ERROR here, that was already checked by the optional value
+ dec_len = JSON_ERROR_INVALID_TOKEN;
}
- dec_len = ret_val;
}
return dec_len;
}
+#ifdef TITAN_RUNTIME_2
template<typename T_type>
void OPTIONAL<T_type>::add_refd_index(int index)
{
--param_refs;
optional_value->remove_refd_index(index);
}
-
-template<typename T_type>
-int OPTIONAL<T_type>::size_of()
-{
- if (!is_present()) {
- return 0;
- }
- return optional_value->size_of();
-}
+#endif
template<typename T_type>
OPTIONAL<T_type>::operator T_type&()
template<typename T_type>
OPTIONAL<T_type>::operator const T_type&() const
{
+#ifdef TITAN_RUNTIME_2
if (!is_present())
+#else
+ if (optional_selection != OPTIONAL_PRESENT)
+#endif
TTCN_error("Using the value of an optional field containing omit.");
return *optional_value;
}
unsigned p_coding) const
{
BER_chk_descr(p_td);
+#ifdef TITAN_RUNTIME_2
switch (get_selection()) {
+#else
+ switch (optional_selection) {
+#endif
case OPTIONAL_PRESENT:
return optional_value->BER_encode_TLV(p_td, p_coding);
case OPTIONAL_OMIT:
const TTCN_Typedescriptor_t& p_td, unsigned p_coding) const
{
BER_chk_descr(p_td);
+#ifdef TITAN_RUNTIME_2
switch (get_selection()) {
+#else
+ switch (optional_selection) {
+#endif
case OPTIONAL_PRESENT:
return optional_value->BER_encode_TLV_negtest(p_err_descr, p_td, p_coding);
case OPTIONAL_OMIT:
template<typename T_type>
int
-OPTIONAL<T_type>::XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& buf, unsigned int flavor, int indent) const
+OPTIONAL<T_type>::XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& buf, unsigned int flavor, int indent, embed_values_enc_struct_t* emb_val) const
{
+#ifdef TITAN_RUNTIME_2
switch (get_selection()) {
+#else
+ switch (optional_selection) {
+#endif
case OPTIONAL_PRESENT:
- return optional_value->XER_encode(p_td, buf, flavor, indent);
+ return optional_value->XER_encode(p_td, buf, flavor, indent, emb_val);
case OPTIONAL_OMIT:
return 0; // nothing to do !
default:
template<typename T_type>
int
OPTIONAL<T_type>::XER_encode_negtest(const Erroneous_descriptor_t* p_err_descr,
- const XERdescriptor_t& p_td, TTCN_Buffer& buf, unsigned int flavor, int indent) const
+ const XERdescriptor_t& p_td, TTCN_Buffer& buf, unsigned int flavor, int indent,
+ embed_values_enc_struct_t* emb_val) const
{
switch (get_selection()) {
case OPTIONAL_PRESENT:
- return optional_value->XER_encode_negtest(p_err_descr, p_td, buf, flavor, indent);
+ return optional_value->XER_encode_negtest(p_err_descr, p_td, buf, flavor, indent, emb_val);
case OPTIONAL_OMIT:
return 0; // nothing to do !
default:
template<typename T_type>
int
-OPTIONAL<T_type>::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, unsigned int flavor)
+OPTIONAL<T_type>::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
+ unsigned int flavor, embed_values_dec_struct_t* emb_val)
{
int exer = is_exer(flavor);
for (int success = reader.Ok(); success==1; success=reader.Read()) {
if (!check_namespace((const char*)reader.NamespaceUri(), p_td)) break;
set_to_present();
- optional_value->XER_decode(p_td, reader, flavor);
+ optional_value->XER_decode(p_td, reader, flavor, emb_val);
goto finished;
}
else break;
found_it:
set_to_present();
//success = reader.Read(); // move to next thing TODO should it loop till an element ?
- optional_value->XER_decode(p_td, reader, flavor);
+ optional_value->XER_decode(p_td, reader, flavor, emb_val);
}
else break; // it's not us, bail
template<typename T_type>
char ** OPTIONAL<T_type>::collect_ns(const XERdescriptor_t& p_td, size_t& num, bool& def_ns) const {
+#ifdef TITAN_RUNTIME_2
switch (get_selection()) {
+#else
+ switch (optional_selection) {
+#endif
case OPTIONAL_PRESENT:
return optional_value->collect_ns(p_td, num, def_ns);
case OPTIONAL_OMIT:
void OPTIONAL<T_type>::BER_decode_opentypes(TTCN_Type_list& p_typelist,
unsigned L_form)
{
+#ifdef TITAN_RUNTIME_2
if (is_present()) {
optional_selection = OPTIONAL_PRESENT;
+#else
+ if (optional_selection==OPTIONAL_PRESENT) {
+#endif
optional_value->BER_decode_opentypes(p_typelist, L_form);
}
}
int OPTIONAL<T_type>::TEXT_encode(const TTCN_Typedescriptor_t& p_td,
TTCN_Buffer& buff) const
{
- if (get_selection())
+ if (is_present())
return optional_value->TEXT_encode(p_td, buff);
TTCN_error("Internal error: TEXT encoding an unbound/omit optional field.");
return 0;
int OPTIONAL<T_type>::TEXT_encode_negtest(const Erroneous_descriptor_t* p_err_descr,
const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& buff) const
{
- if (get_selection())
+ if (is_present())
return optional_value->TEXT_encode_negtest(p_err_descr, p_td, buff);
TTCN_error("Internal error: TEXT encoding an unbound/omit optional field.");
return 0;
--- /dev/null
+///////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2000-2015 Ericsson Telecom AB
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// which accompanies this distribution, and is available at
+// http://www.eclipse.org/legal/epl-v10.html
+///////////////////////////////////////////////////////////////////////////////
+
+#include "Profiler.hh"
+#include <sys/time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "JSON_Tokenizer.hh"
+#include "memory.h"
+#include "Runtime.hh"
+
+////////////////////////////////////
+////////// TTCN3_Profiler //////////
+////////////////////////////////////
+
+TTCN3_Profiler ttcn3_prof;
+
+TTCN3_Profiler::TTCN3_Profiler()
+: disable_profiler(FALSE), disable_coverage(FALSE), aggregate_data(FALSE)
+, disable_stats(FALSE)
+{
+ database_filename = mcopystr("profiler.db");
+ stats_filename = mcopystr("profiler.stats");
+ reset();
+}
+
+TTCN3_Profiler::~TTCN3_Profiler()
+{
+ if (!disable_profiler || !disable_coverage) {
+ import_data();
+ export_data();
+ if (!disable_stats && (TTCN_Runtime::is_single() || TTCN_Runtime::is_hc())) {
+ print_stats();
+ }
+ }
+ for (size_t i = 0; i < profiler_db.size(); ++i) {
+ Free(profiler_db[i].filename);
+ for (size_t j = 0; j < profiler_db[i].functions.size(); ++j) {
+ Free(profiler_db[i].functions[j].name);
+ }
+ }
+ Free(database_filename);
+ Free(stats_filename);
+}
+
+void TTCN3_Profiler::set_disable_profiler(boolean p_disable_profiler)
+{
+ disable_profiler = p_disable_profiler;
+}
+
+void TTCN3_Profiler::set_disable_coverage(boolean p_disable_coverage)
+{
+ disable_coverage = p_disable_coverage;
+}
+
+void TTCN3_Profiler::set_database_filename(const char* p_database_filename)
+{
+ Free(database_filename);
+ database_filename = mcopystr(p_database_filename);
+}
+
+void TTCN3_Profiler::set_aggregate_data(boolean p_aggregate_data)
+{
+ aggregate_data = p_aggregate_data;
+}
+
+void TTCN3_Profiler::set_stats_filename(const char* p_stats_filename)
+{
+ Free(stats_filename);
+ stats_filename = mcopystr(p_stats_filename);
+}
+
+void TTCN3_Profiler::set_disable_stats(boolean p_disable_stats)
+{
+ disable_stats = p_disable_stats;
+}
+
+boolean TTCN3_Profiler::is_profiler_disabled() const
+{
+ return disable_profiler;
+}
+
+#define IMPORT_FORMAT_ERROR(cond) \
+ if (cond) { \
+ TTCN_warning("Database format is invalid. Profiler and/or code coverage data will not be loaded."); \
+ return; \
+ }
+
+void TTCN3_Profiler::init_data_file()
+{
+ // delete the database file (from the previous run) if data aggregation is not set
+ if (!aggregate_data && (!disable_profiler || !disable_coverage)) {
+ remove(database_filename);
+ }
+}
+
+void TTCN3_Profiler::import_data()
+{
+ // open the file, if it exists
+ FILE* file = fopen(database_filename, "r");
+ if (NULL == file) {
+ return;
+ }
+
+ // get the file size
+ fseek(file, 0, SEEK_END);
+ int file_size = ftell(file);
+ rewind(file);
+
+ // read the entire file into a character buffer
+ char* buffer = (char*)Malloc(file_size);
+ fread(buffer, 1, file_size, file);
+
+ // initialize a JSON tokenizer with the buffer
+ JSON_Tokenizer json(buffer, file_size);
+ Free(buffer);
+
+ // attempt to read tokens from the buffer
+ // if the format is invalid, abort the importing process
+ json_token_t token = JSON_TOKEN_NONE;
+ char* value = NULL;
+ size_t value_len = 0;
+
+ // start of main array
+ json.get_next_token(&token, NULL, NULL);
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_ARRAY_START != token);
+
+ // read objects (one for each TTCN-3 file), until the main array end mark is reached
+ json.get_next_token(&token, NULL, NULL);
+ while (JSON_TOKEN_OBJECT_START == token) {
+ size_t file_index = 0;
+
+ // file name:
+ json.get_next_token(&token, &value, &value_len);
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_NAME != token || value_len != 4 ||
+ 0 != strncmp(value, "file", value_len));
+
+ // read the file name and see if its record already exists
+ json.get_next_token(&token, &value, &value_len);
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_STRING != token);
+ for (file_index = 0; file_index < profiler_db.size(); ++file_index) {
+ if (strlen(profiler_db[file_index].filename) == value_len - 2 &&
+ 0 == strncmp(profiler_db[file_index].filename, value + 1, value_len - 2)) {
+ break;
+ }
+ }
+
+ // insert a new element if the file was not found
+ if (profiler_db.size() == file_index) {
+ profiler_db_item_t item;
+ item.filename = mcopystrn(value + 1, value_len - 2);
+ profiler_db.push_back(item);
+ }
+
+ // functions:
+ json.get_next_token(&token, &value, &value_len);
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_NAME != token || value_len != 9 ||
+ 0 != strncmp(value, "functions", value_len));
+
+ // read and store the functions (an array of objects, same as before)
+ json.get_next_token(&token, NULL, NULL);
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_ARRAY_START != token);
+ json.get_next_token(&token, NULL, NULL);
+ while (JSON_TOKEN_OBJECT_START == token) {
+ size_t function_index = 0;
+
+ // function name:
+ json.get_next_token(&token, &value, &value_len);
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_NAME != token || value_len != 4 ||
+ 0 != strncmp(value, "name", value_len));
+
+ // read the function name, it will be checked later
+ json.get_next_token(&token, &value, &value_len);
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_STRING != token);
+ char* function_name = mcopystrn(value + 1, value_len - 2);
+
+ // function start line:
+ json.get_next_token(&token, &value, &value_len);
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_NAME != token || value_len != 10 ||
+ 0 != strncmp(value, "start line", value_len));
+
+ // read the start line and check if the function already exists
+ json.get_next_token(&token, &value, &value_len);
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_NUMBER != token);
+ int start_line = atoi(value);
+ for (function_index = 0; function_index < profiler_db[file_index].functions.size(); ++function_index) {
+ if (profiler_db[file_index].functions[function_index].lineno == start_line &&
+ 0 == strcmp(profiler_db[file_index].functions[function_index].name, function_name)) {
+ break;
+ }
+ }
+
+ // insert a new element if the function was not found
+ if (profiler_db[file_index].functions.size() == function_index) {
+ profiler_db_item_t::profiler_function_data_t func_data;
+ func_data.name = function_name;
+ func_data.lineno = start_line;
+ func_data.exec_count = 0;
+ func_data.total_time = 0.0;
+ profiler_db[file_index].functions.push_back(func_data);
+ }
+
+ if (!disable_coverage) {
+ // function execution count:
+ json.get_next_token(&token, &value, &value_len);
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_NAME != token || value_len != 15 ||
+ 0 != strncmp(value, "execution count", value_len));
+
+ // read the execution count and add it to the current data
+ json.get_next_token(&token, &value, &value_len);
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_NUMBER != token);
+ profiler_db[file_index].functions[function_index].exec_count += atoi(value);
+ }
+
+ if (!disable_profiler) {
+ // total function execution time:
+ json.get_next_token(&token, &value, &value_len);
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_NAME != token || value_len != 10 ||
+ 0 != strncmp(value, "total time", value_len));
+
+ // read the total time and add it to the current data
+ json.get_next_token(&token, &value, &value_len);
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_NUMBER != token);
+ profiler_db[file_index].functions[function_index].total_time += atof(value);
+ }
+
+ // end of the function's object
+ json.get_next_token(&token, NULL, NULL);
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_OBJECT_END != token);
+
+ // read the next token (either the start of another object or the function array end)
+ json.get_next_token(&token, NULL, NULL);
+ }
+
+ // function array end
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_ARRAY_END != token);
+
+ // lines:
+ json.get_next_token(&token, &value, &value_len);
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_NAME != token || value_len != 5 ||
+ 0 != strncmp(value, "lines", value_len));
+
+ // read and store the lines (an array of objects, same as before)
+ json.get_next_token(&token, NULL, NULL);
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_ARRAY_START != token);
+ json.get_next_token(&token, NULL, NULL);
+ while (JSON_TOKEN_OBJECT_START == token) {
+
+ // line number:
+ json.get_next_token(&token, &value, &value_len);
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_NAME != token || value_len != 6 ||
+ 0 != strncmp(value, "number", value_len));
+
+ // read the line number and check if the line already exists
+ json.get_next_token(&token, &value, &value_len);
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_NUMBER != token);
+ int lineno = atoi(value);
+ IMPORT_FORMAT_ERROR(lineno < 0);
+ size_t line_no = lineno;
+ if (line_no >= profiler_db[file_index].lines.size()) {
+ for (size_t i = profiler_db[file_index].lines.size(); i <= line_no; ++i) {
+ profiler_db_item_t::profiler_line_data_t line_data;
+ line_data.total_time = 0.0;
+ line_data.exec_count = 0;
+ profiler_db[file_index].lines.push_back(line_data);
+ }
+ }
+
+ if (!disable_coverage) {
+ // line execution count:
+ json.get_next_token(&token, &value, &value_len);
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_NAME != token || value_len != 15 ||
+ 0 != strncmp(value, "execution count", value_len));
+
+ // read the execution count and add it to the current data
+ json.get_next_token(&token, &value, &value_len);
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_NUMBER != token);
+ profiler_db[file_index].lines[line_no].exec_count += atoi(value);
+ }
+
+ if (!disable_profiler) {
+ // total line execution time:
+ json.get_next_token(&token, &value, &value_len);
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_NAME != token || value_len != 10 ||
+ 0 != strncmp(value, "total time", value_len));
+
+ // read the total time and add it to the current data
+ json.get_next_token(&token, &value, &value_len);
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_NUMBER != token);
+ profiler_db[file_index].lines[line_no].total_time += atof(value);
+ }
+
+ // end of the line's object
+ json.get_next_token(&token, NULL, NULL);
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_OBJECT_END != token);
+
+ // read the next token (either the start of another object or the line array end)
+ json.get_next_token(&token, NULL, NULL);
+ }
+
+ // line array end
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_ARRAY_END != token);
+
+ // end of the file's object
+ json.get_next_token(&token, NULL, NULL);
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_OBJECT_END != token);
+
+ // read the next token (either the start of another object or the main array end)
+ json.get_next_token(&token, NULL, NULL);
+ }
+
+ // main array end
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_ARRAY_END != token);
+}
+
+void TTCN3_Profiler::export_data()
+{
+ // nothing to export if the database is empty
+ if (profiler_db.empty()) {
+ return;
+ }
+
+ // check whether the file can be opened for writing
+ FILE* file = fopen(database_filename, "w");
+ if (NULL == file) {
+ TTCN_warning("Could not open file '%s' for writing. Profiler and/or code coverage "
+ "data will not be saved.", database_filename);
+ return;
+ }
+
+ // use the JSON tokenizer to create a JSON document from the database
+ JSON_Tokenizer json(true);
+
+ // main array, contains an element for each file
+ json.put_next_token(JSON_TOKEN_ARRAY_START, NULL);
+ for (size_t i = 0; i < profiler_db.size(); ++i) {
+
+ // each file's data is stored in an object
+ json.put_next_token(JSON_TOKEN_OBJECT_START, NULL);
+
+ // store the file name
+ json.put_next_token(JSON_TOKEN_NAME, "file");
+ char* file_name_str = mprintf("\"%s\"", profiler_db[i].filename);
+ json.put_next_token(JSON_TOKEN_STRING, file_name_str);
+ Free(file_name_str);
+
+ // store the function data in an array (one element for each function)
+ json.put_next_token(JSON_TOKEN_NAME, "functions");
+ json.put_next_token(JSON_TOKEN_ARRAY_START, NULL);
+ for (size_t j = 0; j < profiler_db[i].functions.size(); ++j) {
+
+ // the data is stored in an object for each function
+ json.put_next_token(JSON_TOKEN_OBJECT_START, NULL);
+
+ // store the function name
+ json.put_next_token(JSON_TOKEN_NAME, "name");
+ char* func_name_str = mprintf("\"%s\"", profiler_db[i].functions[j].name);
+ json.put_next_token(JSON_TOKEN_STRING, func_name_str);
+ Free(func_name_str);
+
+ // store the function start line
+ json.put_next_token(JSON_TOKEN_NAME, "start line");
+ char* start_line_str = mprintf("%d", profiler_db[i].functions[j].lineno);
+ json.put_next_token(JSON_TOKEN_NUMBER, start_line_str);
+ Free(start_line_str);
+
+ if (!disable_coverage) {
+ // store the function execution count
+ json.put_next_token(JSON_TOKEN_NAME, "execution count");
+ char* exec_count_str = mprintf("%d", profiler_db[i].functions[j].exec_count);
+ json.put_next_token(JSON_TOKEN_NUMBER, exec_count_str);
+ Free(exec_count_str);
+ }
+
+ if (!disable_profiler) {
+ // store the function's total execution time
+ json.put_next_token(JSON_TOKEN_NAME, "total time");
+ char* exec_count_str = mprintf("%.6lf", profiler_db[i].functions[j].total_time);
+ json.put_next_token(JSON_TOKEN_NUMBER, exec_count_str);
+ Free(exec_count_str);
+ }
+
+ // end of function object
+ json.put_next_token(JSON_TOKEN_OBJECT_END, NULL);
+ }
+
+ // end of function data array
+ json.put_next_token(JSON_TOKEN_ARRAY_END, NULL);
+
+ // store the line data in an array (one element for each line with useful data)
+ json.put_next_token(JSON_TOKEN_NAME, "lines");
+ json.put_next_token(JSON_TOKEN_ARRAY_START, NULL);
+ for (size_t j = 0; j < profiler_db[i].lines.size(); ++j) {
+ if (0.0 != profiler_db[i].lines[j].total_time ||
+ 0 != profiler_db[i].lines[j].exec_count) {
+
+ // store line data in an object
+ json.put_next_token(JSON_TOKEN_OBJECT_START, NULL);
+
+ // store the line number
+ json.put_next_token(JSON_TOKEN_NAME, "number");
+ char* line_number_str = mprintf("%lu", j);
+ json.put_next_token(JSON_TOKEN_NUMBER, line_number_str);
+ Free(line_number_str);
+
+ if (!disable_coverage) {
+ // store the line execution count
+ json.put_next_token(JSON_TOKEN_NAME, "execution count");
+ char* exec_count_str = mprintf("%d", profiler_db[i].lines[j].exec_count);
+ json.put_next_token(JSON_TOKEN_NUMBER, exec_count_str);
+ Free(exec_count_str);
+ }
+
+ if (!disable_profiler) {
+ // store the line's total execution time
+ json.put_next_token(JSON_TOKEN_NAME, "total time");
+ char* exec_count_str = mprintf("%.6lf", profiler_db[i].lines[j].total_time);
+ json.put_next_token(JSON_TOKEN_NUMBER, exec_count_str);
+ Free(exec_count_str);
+ }
+
+ // end of this line's object
+ json.put_next_token(JSON_TOKEN_OBJECT_END, NULL);
+ }
+ }
+
+ // end of line data array
+ json.put_next_token(JSON_TOKEN_ARRAY_END, NULL);
+
+ // end of this file's object
+ json.put_next_token(JSON_TOKEN_OBJECT_END, NULL);
+ }
+
+ // end of main array
+ json.put_next_token(JSON_TOKEN_ARRAY_END, NULL);
+
+ // write the JSON document into the file
+ fprintf(file, "%s\n", json.get_buffer());
+ fclose(file);
+}
+
+void TTCN3_Profiler::print_stats()
+{
+ if (profiler_db.empty()) {
+ return;
+ }
+
+ // title
+ char* title_str = mprintf(
+ "##################################################\n"
+ "%s## TTCN-3 %s%s%sstatistics ##%s\n"
+ "##################################################\n\n\n"
+ , disable_profiler ? "#######" : (disable_coverage ? "#########" : "")
+ , disable_profiler ? "" : "profiler "
+ , (disable_profiler || disable_coverage) ? "" : "and "
+ , disable_coverage ? "" : "code coverage "
+ , disable_profiler ? "######" : (disable_coverage ? "#########" : ""));
+
+ // line data
+ char* line_data_str = mprintf(
+ "-------------------------------------------------\n"
+ "%s- Code line data (%s%s%s) -%s\n"
+ "-------------------------------------------------\n"
+ , disable_profiler ? "-------" : (disable_coverage ? "---------" : "")
+ , disable_profiler ? "" : "total time"
+ , (disable_profiler || disable_coverage) ? "" : " / "
+ , disable_coverage ? "" : "execution count"
+ , disable_profiler ? "------" : (disable_coverage ? "---------" : ""));
+
+ // average time / exec count for lines
+ char* line_avg_str = NULL;
+ if (!disable_coverage && !disable_profiler) {
+ line_avg_str = mcopystr(
+ "-------------------------------------------------\n"
+ "- Average time / execution count for code lines -\n"
+ "-------------------------------------------------\n");
+ }
+
+ // function data
+ char* func_data_str = mprintf(
+ "------------------------------------------------\n"
+ "%s- Function data (%s%s%s) -%s\n"
+ "------------------------------------------------\n"
+ , disable_profiler ? "-------" : (disable_coverage ? "---------" : "")
+ , disable_profiler ? "" : "total time"
+ , (disable_profiler || disable_coverage) ? "" : " / "
+ , disable_coverage ? "" : "execution count"
+ , disable_profiler ? "------" : (disable_coverage ? "---------" : ""));
+
+ // average time / exec count for functions
+ char* func_avg_str = NULL;
+ if (!disable_coverage && !disable_profiler) {
+ func_avg_str = mcopystr(
+ "------------------------------------------------\n"
+ "- Average time / execution count for functions -\n"
+ "------------------------------------------------\n");
+ }
+
+ // cycle through the database and gather the necessary data
+ for (size_t i = 0; i < profiler_db.size(); ++i) {
+ if (i > 0) {
+ // add separators between files
+ line_data_str = mputstr(line_data_str, "-------------------------------------------------\n");
+ func_data_str = mputstr(func_data_str, "------------------------------------------------\n");
+ if (!disable_profiler && !disable_coverage) {
+ line_avg_str = mputstr(line_avg_str, "-------------------------------------------------\n");
+ func_avg_str = mputstr(func_avg_str, "------------------------------------------------\n");
+ }
+ }
+
+ // lines
+ for (size_t j = 0; j < profiler_db[i].lines.size(); ++j) {
+ if (0.0 != profiler_db[i].lines[j].total_time ||
+ 0 != profiler_db[i].lines[j].exec_count) {
+ if (!disable_profiler) {
+ line_data_str = mputprintf(line_data_str, "%.6lfs", profiler_db[i].lines[j].total_time);
+ if (!disable_coverage) {
+ line_data_str = mputstrn(line_data_str, "\t/\t", 3);
+ line_avg_str = mputprintf(line_avg_str, "%.6lfs",
+ profiler_db[i].lines[j].total_time / profiler_db[i].lines[j].exec_count);
+ }
+ }
+ if (!disable_coverage) {
+ line_data_str = mputprintf(line_data_str, "%d", profiler_db[i].lines[j].exec_count);
+ }
+
+ // line specification (including function name for the function's start line)
+ char* line_spec_str = mprintf("\t%s:%lu", profiler_db[i].filename, j);
+ int func = get_function(i, j);
+ if (-1 != func) {
+ line_spec_str = mputprintf(line_spec_str, " [%s]", profiler_db[i].functions[func].name);
+ }
+ line_spec_str = mputstrn(line_spec_str, "\n", 1);
+
+ // add the line spec string to the other strings
+ line_data_str = mputstr(line_data_str, line_spec_str);
+ if (!disable_profiler && !disable_coverage) {
+ line_avg_str = mputstr(line_avg_str, line_spec_str);
+ }
+ }
+ }
+
+ // functions
+ for (size_t j = 0; j < profiler_db[i].functions.size(); ++j) {
+ if (!disable_profiler) {
+ func_data_str = mputprintf(func_data_str, "%.6lfs", profiler_db[i].functions[j].total_time);
+ if (!disable_coverage) {
+ func_data_str = mputstrn(func_data_str, "\t/\t", 3);
+ func_avg_str = mputprintf(func_avg_str, "%.6lfs",
+ profiler_db[i].functions[j].total_time / profiler_db[i].functions[j].exec_count);
+ }
+ }
+ if (!disable_coverage) {
+ func_data_str = mputprintf(func_data_str, "%d", profiler_db[i].functions[j].exec_count);
+ }
+
+ // functions specification
+ char* func_spec_str = mprintf("\t%s:%d [%s]\n", profiler_db[i].filename,
+ profiler_db[i].functions[j].lineno, profiler_db[i].functions[j].name);
+
+ // add the line spec string to the other strings
+ func_data_str = mputstr(func_data_str, func_spec_str);
+ if (!disable_profiler && !disable_coverage) {
+ func_avg_str = mputstr(func_avg_str, func_spec_str);
+ }
+ }
+ }
+
+ // add new lines at the end of each segment
+ line_data_str = mputstrn(line_data_str, "\n", 1);
+ func_data_str = mputstrn(func_data_str, "\n", 1);
+ if (!disable_profiler && !disable_coverage) {
+ line_avg_str = mputstrn(line_avg_str, "\n", 1);
+ func_avg_str = mputstrn(func_avg_str, "\n", 1);
+ }
+
+ // write the statistics to the specified file
+ FILE* file = fopen(stats_filename, "w");
+ if (NULL == file) {
+ TTCN_warning("Could not open file '%s' for writing. Profiler and/or code coverage "
+ "statistics will not be saved.", stats_filename);
+ return;
+ }
+ fprintf(file, "%s%s%s%s%s"
+ , title_str, line_data_str
+ , (disable_profiler || disable_coverage) ? "" : line_avg_str
+ , func_data_str, (disable_profiler || disable_coverage) ? "" : func_avg_str);
+ fclose(file);
+}
+
+void TTCN3_Profiler::reset()
+{
+ prev_time = 0.0;
+ prev_file = NULL;
+ prev_line = -1;
+ prev_stack_len = 0;
+}
+
+double TTCN3_Profiler::get_time()
+{
+ timeval tv;
+ gettimeofday(&tv, NULL);
+ return tv.tv_sec + tv.tv_usec / 1000000.0;
+}
+
+void TTCN3_Profiler::enter_function(const char* filename, int lineno, const char* function_name)
+{
+ if (disable_profiler && disable_coverage) {
+ return;
+ }
+
+ // Note that the execution time of the last line in a function
+ // is measured by using the stack depth.
+ execute_line(filename, lineno);
+
+ int element = get_element(filename);
+
+ // store function data
+ int func = get_function(element, lineno);
+ if (-1 == func) {
+ create_function(element, lineno, function_name);
+ func = profiler_db[element].functions.size() - 1;
+ }
+
+ if (!disable_coverage) {
+ ++profiler_db[element].functions[func].exec_count;
+ }
+}
+
+void TTCN3_Profiler::execute_line(const char* filename, int lineno)
+{
+ if (disable_profiler && disable_coverage) {
+ return;
+ }
+
+ if (!disable_profiler) {
+ double currentTime = get_time();
+
+ // prev line should not be measured, because it is still running: we are in longer stack level
+ if (0.0 == prev_time || TTCN3_Stack_Depth::depth() > prev_stack_len) {
+ // add prev timer to call stack:
+ TTCN3_Stack_Depth::add_stack(prev_stack_len, prev_file, filename, prev_line, lineno);
+ }
+ else {
+ // if stack level is the same or higher: current line should be measured:
+ double elapsed = currentTime - prev_time;
+
+ // add the elapsed time to the time of the previous line:
+ add_line_time(elapsed, get_element(prev_file), prev_line);
+
+ TTCN3_Stack_Depth::update_stack_elapsed(elapsed);
+ }
+ }
+
+ // several instructions could be in the same line, only count the line once
+ if (!disable_coverage && (lineno != prev_line || NULL == prev_file ||
+ 0 != strcmp(prev_file, filename))) {
+ int element = get_element(filename);
+
+ // make sure the line exists in the database
+ create_lines(element, lineno);
+
+ // increase line execution count
+ ++profiler_db[element].lines[lineno].exec_count;
+ }
+
+ // store the current location as previous for the next call
+ set_prev(disable_profiler ? -1 : TTCN3_Stack_Depth::depth(), filename, lineno);
+}
+
+int TTCN3_Profiler::get_element(const char* filename)
+{
+ for (size_t i = 0; i < profiler_db.size(); ++i) {
+ if (0 == strcmp(profiler_db[i].filename, filename)) {
+ return i;
+ }
+ }
+
+ profiler_db_item_t item;
+ item.filename = mcopystr(filename);
+ profiler_db.push_back(item);
+ return profiler_db.size() - 1;
+}
+
+int TTCN3_Profiler::get_function(int element, int lineno)
+{
+ for (size_t i = 0; i < profiler_db[element].functions.size(); ++i) {
+ if (profiler_db[element].functions[i].lineno == lineno) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+void TTCN3_Profiler::create_function(int element, int lineno, const char* function_name)
+{
+ profiler_db_item_t::profiler_function_data_t func_data;
+ func_data.lineno = lineno;
+ func_data.total_time = 0.0;
+ func_data.exec_count = 0;
+ func_data.name = mcopystr(function_name);
+ profiler_db[element].functions.push_back(func_data);
+}
+
+void TTCN3_Profiler::create_lines(int element, int lineno)
+{
+ // set 0 for the unknown lines
+ size_t line_no = lineno;
+ if (profiler_db[element].lines.size() <= line_no) {
+ for (size_t i = profiler_db[element].lines.size(); i <= line_no; ++i) {
+ profiler_db_item_t::profiler_line_data_t line_data;
+ line_data.total_time = 0.0;
+ line_data.exec_count = 0;
+ profiler_db[element].lines.push_back(line_data);
+ }
+ }
+}
+
+void TTCN3_Profiler::add_line_time(double elapsed, int element, int lineno)
+{
+ if (-1 == lineno) {
+ return;
+ }
+
+ // ensure the line data exists
+ create_lines(element, lineno);
+
+ // increase the time of the line in the current file:
+ profiler_db[element].lines[lineno].total_time += elapsed;
+}
+
+void TTCN3_Profiler::add_function_time(double elapsed, int element, int lineno)
+{
+ int func = get_function(element, lineno);
+ if (-1 == func) {
+ return;
+ }
+ profiler_db[element].functions[func].total_time += elapsed;
+}
+
+void TTCN3_Profiler::update_last()
+{
+ if (0.0 == prev_time) {
+ return;
+ }
+
+ double currentTime = get_time();
+ double elapsed = currentTime - prev_time;
+
+ int element = get_element(prev_file);
+
+ // add the elapsed time to the time of the previous line:
+ add_line_time(elapsed, element, prev_line);
+ TTCN3_Stack_Depth::update_stack_elapsed(elapsed);
+
+ // reset measurement:
+ prev_time = 0.0;
+}
+
+void TTCN3_Profiler::set_prev(int stack_len, const char* filename, int lineno)
+{
+ prev_file = filename;
+ prev_line = lineno;
+ if (!disable_profiler) {
+ prev_time = get_time();
+ prev_stack_len = stack_len;
+ }
+}
+
+/////////////////////////////////////
+///////// TTCN3_Stack_Depth /////////
+/////////////////////////////////////
+
+int TTCN3_Stack_Depth::current_depth = -1;
+Vector<TTCN3_Stack_Depth::call_stack_timer_item_t> TTCN3_Stack_Depth::call_stack_timer_db;
+
+TTCN3_Stack_Depth::TTCN3_Stack_Depth()
+{
+ if (ttcn3_prof.is_profiler_disabled()) {
+ return;
+ }
+ ++current_depth;
+}
+
+TTCN3_Stack_Depth::~TTCN3_Stack_Depth()
+{
+ if (ttcn3_prof.is_profiler_disabled()) {
+ return;
+ }
+ ttcn3_prof.update_last();
+ remove_stack();
+ if (0 == current_depth) {
+ ttcn3_prof.reset();
+ }
+ --current_depth;
+}
+
+void TTCN3_Stack_Depth::add_stack(int stack_len, const char* caller_file, const char* func_file,
+ int caller_line, int start_line)
+{
+ call_stack_timer_item_t item;
+ item.stack_len = stack_len;
+ item.caller_file = caller_file;
+ item.func_file = func_file;
+ item.caller_line = caller_line;
+ item.start_line = start_line;
+ item.elapsed = 0.0;
+ call_stack_timer_db.push_back(item);
+}
+
+void TTCN3_Stack_Depth::remove_stack()
+{
+ // if stack level is the same or higher: measure the time:
+ double elapsed = call_stack_timer_db[current_depth].elapsed;
+
+ int element = ttcn3_prof.get_element(call_stack_timer_db[current_depth].func_file);
+
+ // add elapsed time to the total execution time of the previous line:
+ ttcn3_prof.add_function_time(elapsed, element, call_stack_timer_db[current_depth].start_line);
+
+ ttcn3_prof.set_prev(call_stack_timer_db[current_depth].stack_len,
+ call_stack_timer_db[current_depth].caller_file,
+ call_stack_timer_db[current_depth].caller_line);
+
+ call_stack_timer_db.erase_at(current_depth);
+}
+
+void TTCN3_Stack_Depth::update_stack_elapsed(double elapsed)
+{
+ for(int i = 0; i <= current_depth; i++) {
+ call_stack_timer_db[i].elapsed += elapsed;
+ }
+}
\ No newline at end of file
--- /dev/null
+///////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2000-2015 Ericsson Telecom AB
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// which accompanies this distribution, and is available at
+// http://www.eclipse.org/legal/epl-v10.html
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef PROFILER_HH
+#define PROFILER_HH
+
+#include "Vector.hh"
+#include "Types.h"
+
+/** This class performs profiling and code coverage on lines and functions in
+ * TTCN-3 code (requires the -z compiler option).
+ * Customizable through the configuration file's [PROFILER] section. */
+class TTCN3_Profiler {
+public:
+
+ /** Database entry for one file */
+ struct profiler_db_item_t {
+ /** Database entry for one line */
+ struct profiler_line_data_t {
+ /** The line's total execution time */
+ double total_time;
+ /** The number of times this line was executed */
+ int exec_count;
+ };
+ /** Database entry for one function (including test cases, alt steps, the control part, etc.) */
+ struct profiler_function_data_t {
+ /** Function name (owned) */
+ char* name;
+ /** Function starting line */
+ int lineno;
+ /** The function's total execution time */
+ double total_time;
+ /** The number of times this function was executed */
+ int exec_count;
+ };
+ /** TTCN-3 File name (relative path, owned) */
+ char* filename;
+ /** Contains database entries for all the lines in this file (its index is
+ * the line number, so there may be empty elements) */
+ Vector<profiler_line_data_t> lines;
+ /** Contains database entries for all the functions in this file (one entry
+ * for each function) */
+ Vector<profiler_function_data_t> functions;
+ };
+
+ /** Constructor */
+ TTCN3_Profiler();
+ /** Destructor - adds all gathered data to the database file and prints
+ * statistics if necessary */
+ ~TTCN3_Profiler();
+
+ /** Enables or disables profiling - called by the config file parser */
+ void set_disable_profiler(boolean p_disable_profiler);
+ /** Enables or disables code coverage - called by the config file parser */
+ void set_disable_coverage(boolean p_disable_coverage);
+ /** Sets the database file name (default is "profiler.db" - called by the config file parser */
+ void set_database_filename(const char* p_database_filename);
+ /** Enables or disables data aggregation - called by the config file parser */
+ void set_aggregate_data(boolean p_aggregate_data);
+ /** Sets the statistics file name (default is "profiler.stats" - called by the config file parser */
+ void set_stats_filename(const char* p_stats_filename);
+ /** Enables or disables the printing of statistics - called by the config file parser */
+ void set_disable_stats(boolean p_disable_stats);
+
+ /** Returns true if profiling is disabled */
+ boolean is_profiler_disabled() const;
+
+ /** Deletes the database file if data aggregation is not set */
+ void init_data_file();
+ /** Adds the data from the database file to the local database */
+ void import_data();
+ /** Writes the local database to the database file (overwrites the file) */
+ void export_data();
+
+ /** Calculates and prints statistics from the gathered data */
+ void print_stats();
+
+ /** Resets data related to the previous location and time (the local database is not changed) */
+ void reset();
+ /** Returns the current time (in seconds) */
+ static double get_time();
+ /** Called when a TTCN-3 function starts execution - stores data */
+ void enter_function(const char* filename, int lineno, const char* function_name);
+ /** Called when a TTCN-3 code line starts execution - stores data */
+ void execute_line(const char* filename, int lineno);
+ /** Returns the index of a TTCN-3 file's entry in the local database */
+ int get_element(const char* filename);
+ /** Returns the index of a TTCN-3 function's entry in the database
+ * @param element index of the file (where the function is declared)
+ * @param lineno function start line */
+ int get_function(int element, int lineno);
+ /** Creates a new TTCN-3 function entry and inserts it in the database
+ * @param element file entry's index
+ * @param lineno function start line
+ * @param function_name name of the function */
+ void create_function(int element, int lineno, const char* function_name);
+ /** Creates TTCN-3 code line entries up to the given line number */
+ void create_lines(int element, int lineno);
+ /** Adds elapsed time to the specified TTCN-3 code line's total time */
+ void add_line_time(double elapsed, int element, int lineno);
+ /** Adds elapsed time to the specified TTCN-3 function's total time*/
+ void add_function_time(double elapsed, int element, int lineno);
+ /** Called when a TTCN-3 function's execution ends - stores data */
+ void update_last();
+ /** Stores data related to the previous location */
+ void set_prev(int stack_len, const char* filename, int lineno);
+
+private:
+ /** Profiling is disabled if true */
+ boolean disable_profiler;
+ /** Code coverage is disabled if true */
+ boolean disable_coverage;
+ /** Contains the database file name */
+ char* database_filename;
+ /** If true, data gathered by previous runs will be added to the data gathered
+ * in this run */
+ boolean aggregate_data;
+ /** Contains the statistics file name */
+ char* stats_filename;
+ /** Statistics will not be calculated and printed if true */
+ boolean disable_stats;
+
+ /** The time measured at the previous TTCN-3 code line */
+ double prev_time;
+ /** Name of the TTCN-3 file, where the last executed line is (not owned) */
+ const char* prev_file;
+ /** The number of the previously executed line */
+ int prev_line;
+ /** The local database */
+ Vector<profiler_db_item_t> profiler_db;
+ /** The stack length at the previously executed line */
+ int prev_stack_len;
+};
+
+/** The global TTCN3_Profiler object
+ *
+ * One instance is created in each process (in parallel mode).
+ * After construction the configuration file parser may change the profiler's settings.
+ * The destructor merges its data with that of other processes (and possibly with previous runs)
+ * through the database file. The last destructor (the one in the Host Controller's process)
+ * prints the statistics (if enabled). */
+extern TTCN3_Profiler ttcn3_prof;
+
+/** Helper class for profiling
+ *
+ * Its instances depict the current call stack. One instance is created at the start
+ * of each TTCN-3 function execution, and it's destroyed at the function's end. */
+class TTCN3_Stack_Depth {
+public:
+ /** Entry for one function call in the call stack */
+ struct call_stack_timer_item_t {
+ /** Stack length before the function call */
+ int stack_len;
+ /** File name, where the calling function is declared (not owned) */
+ const char* caller_file;
+ /** File name, where the called function is declared (not owned)*/
+ const char* func_file;
+ /** Calling function's start line */
+ int caller_line;
+ /** Called function's start line */
+ int start_line;
+ /** Time elapsed in this function call */
+ double elapsed;
+ };
+
+ /** Constructor - increases the stack depth */
+ TTCN3_Stack_Depth();
+ /** Destructor - decreases the stack depth, updates call times in the profiler */
+ ~TTCN3_Stack_Depth();
+
+ /** Returns the current stack depth */
+ static int depth() { return current_depth; }
+ /** Inserts a new function call entry into the call stack database */
+ static void add_stack(int stack_len, const char* caller_file, const char* func_file,
+ int caller_line, int start_line);
+ /** Removes the last entry from the call stack database */
+ static void remove_stack();
+ /** Adds the elapsed time to all entries in the call stack database */
+ static void update_stack_elapsed(double elapsed);
+private:
+ /** The current stack depth (starts from 0)*/
+ static int current_depth;
+ /** The call stack database */
+ static Vector<call_stack_timer_item_t> call_stack_timer_db;
+};
+
+#endif /* PROFILER_HH */
+
boolean is_omit() const;
boolean is_any_or_omit() const;
- // Dummy functions, only used in record of/set of value
+#ifdef TITAN_RUNTIME_2
+ // Dummy functions, only used in record of/set of value in RT2
void add_refd_index(int) {}
void remove_refd_index(int) {}
+#endif
};
#ifndef TITAN_RUNTIME_2
default: // nothing to do
break;
}
- XER_encode(*p_td.xer,p_buf, XER_coding, 0);
+ XER_encode(*p_td.xer,p_buf, XER_coding, 0, 0);
p_buf.put_c('\n');
break; }
case TTCN_EncDec::CT_JSON: {
if (type==XML_READER_TYPE_ELEMENT)
break;
}
- XER_decode(*p_td.xer, reader, XER_coding);
+ XER_decode(*p_td.xer, reader, XER_coding, 0);
size_t bytes = reader.ByteConsumed();
p_buf.set_pos(bytes);
break; }
extern void xml_escape(const unsigned int c, TTCN_Buffer& p_buf);
int UNIVERSAL_CHARSTRING::XER_encode(const XERdescriptor_t& p_td,
- TTCN_Buffer& p_buf, unsigned int flavor, int indent) const
+ TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const
{
if(!is_bound()) {
TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,
universal_char const uspace = {0,0,0,32};
int UNIVERSAL_CHARSTRING::XER_decode(const XERdescriptor_t& p_td,
- XmlReaderWrap& reader, unsigned int flavor)
+ XmlReaderWrap& reader, unsigned int flavor, embed_values_dec_struct_t*)
{
int exer = is_exer(flavor);
int success = reader.Ok(), depth = -1;
boolean BER_decode_TLV(const TTCN_Typedescriptor_t& p_td,
const ASN_BER_TLV_t& p_tlv, unsigned L_form);
- int XER_encode(const XERdescriptor_t&, TTCN_Buffer&, unsigned int, int) const;
- int XER_decode(const XERdescriptor_t&, XmlReaderWrap& reader, unsigned int);
+ int XER_encode(const XERdescriptor_t&, TTCN_Buffer&, unsigned int, int, embed_values_enc_struct_t*) const;
+ int XER_decode(const XERdescriptor_t&, XmlReaderWrap& reader, unsigned int, embed_values_dec_struct_t*);
/** Decodes UTF-8 into the internal representation (UCS4-BE)
*
* @param n_octets number of UTF-8 bytes (not characters)
case TTCN_EncDec::CT_XER: {
TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
unsigned XER_coding=va_arg(pvar, unsigned);
- XER_encode(*p_td.xer, p_buf, XER_coding, 0);
+ XER_encode(*p_td.xer, p_buf, XER_coding, 0, 0);
break;}
case TTCN_EncDec::CT_JSON: {
TTCN_EncDec_ErrorContext ec("While JSON-encoding type '%s': ", p_td.name);
if (type==XML_READER_TYPE_ELEMENT)
break;
}
- XER_decode(*p_td.xer, reader, XER_coding);
+ XER_decode(*p_td.xer, reader, XER_coding, 0);
size_t bytes = reader.ByteConsumed();
p_buf.set_pos(bytes);
break;}
int VERDICTTYPE::XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf,
- unsigned int p_flavor, int p_indent) const
+ unsigned int p_flavor, int p_indent, embed_values_enc_struct_t*) const
{
int encoded_length=(int)p_buf.get_len();
//const boolean e_xer = is_exer(p_flavor);
}
int VERDICTTYPE::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& p_reader,
- unsigned int p_flavor)
+ unsigned int p_flavor, embed_values_dec_struct_t*)
{
int rd_ok = 1, type;
const int e_xer = is_exer(p_flavor);
TTCN_EncDec::coding_t p_coding, ...);
int XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf,
- unsigned int flavor, int indent) const;
+ unsigned int flavor, int indent, embed_values_enc_struct_t*) const;
int XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
- unsigned int flavor);
+ unsigned int flavor, embed_values_dec_struct_t*);
/** Encodes accordingly to the JSON encoding rules.
* Returns the length of the encoded data. */
class XmlReaderWrap;
class Base_Type;
+#ifdef TITAN_RUNTIME_2
+class Record_Of_Type;
+class Erroneous_descriptor_t;
+#endif
class TTCN_Module;
/** @defgroup XER XER codec
* Example:
* @code
* int Foo::XER_encode(const XERdescriptor_t& p_td,
- * TTCN_Buffer& p_buf, unsigned int flavor, int indent) const {
+ * TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const {
* int canon = is_canonical(flavor);
* if (!canon) do_indent(p_buf, indent);
* // output the start tag
*
* @code
* int Foo::XER_encode(const XERdescriptor_t& p_td,
- * TTCN_Buffer& p_buf, unsigned int flavor, int indent) const {
+ * TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const {
* int canon = is_canonical(flavor);
* if (!canon) do_indent(p_buf, indent);
* // output an empty element tag
const char** ns_uris;
};
+/** Information related to the embedded values in XML encoding
+ *
+ * Used when a record/set with the EMBED-VALUES coding instruction contains
+ * one or more record of/set of fields. */
+struct embed_values_enc_struct_t
+{
+#ifdef TITAN_RUNTIME_2
+ /** Stores the array of embedded values */
+ const Record_Of_Type* embval_array;
+ /** Stores the erroneous descriptor of the embedded values field (for negative tests) */
+ const Erroneous_descriptor_t* embval_err;
+ /** Error value index for the embedded values (for negative tests) */
+ int embval_err_val_idx;
+ /** Erroneous descriptor index for the embedded values (for negative tests) */
+ int embval_err_descr_idx;
+#else
+ /** Stores the array of embedded values as a Base_Type (use get_embedded_value
+ * to retrieve values - temporarily disabled) */
+ const Base_Type* embval_array;
+ /** Stores the size of the embedded value array */
+ int embval_size;
+#endif
+ /** Stores the index of the next embedded value to be read */
+ int embval_index;
+};
+
+/** Information related to the embedded values in XML decoding
+ *
+ * Used when a record/set with the EMBED-VALUES coding instruction contains
+ * one or more record of/set of fields. */
+struct embed_values_dec_struct_t
+{
+#ifdef TITAN_RUNTIME_2
+ /** Stores the array of embedded values */
+ Record_Of_Type* embval_array;
+#else
+ /** Stores the array of embedded values as a Base_type (use set_embedded_value
+ * to insert new values - temporarily disabled) */
+ Base_Type* embval_array;
+#endif
+ /** Stores the number of embedded values that are currently in the array,
+ * and the index where the next one should be inserted */
+ int embval_index;
+};
+
/** Check the name of an XML node against a XER type descriptor.
*
* @param name the (local, unqualified) name of the XML element
%x SC_commentblock SC_cstring SC_DEFINE
%s SC_MODULE_PARAMETERS SC_LOGGING SC_TESTPORT_PARAMETERS SC_EXECUTE SC_GROUPS
%s SC_COMPONENTS SC_EXTERNAL_COMMANDS SC_MAIN_CONTROLLER SC_INCLUDE SC_ORDERED_INCLUDE
-%s SC_STRING2TTCN_COMPONENT
+%s SC_STRING2TTCN_COMPONENT SC_PROFILER
%%
}
}
+<*>"["{WS}PROFILER{WS}"]" {
+ if (YY_START!=SC_commentblock && YY_START!=SC_cstring) {
+ BEGIN(SC_PROFILER);
+ return ProfilerKeyword;
+ }
+}
+
<*>"["{WS}TESTPORT_PARAMETERS{WS}"]" {
if (YY_START!=SC_commentblock && YY_START!=SC_cstring) {
BEGIN(SC_TESTPORT_PARAMETERS);
infinity return InfinityKeyword;
}
-<SC_MODULE_PARAMETERS,SC_LOGGING>
+<SC_MODULE_PARAMETERS,SC_LOGGING,SC_PROFILER>
{
true {
yylval.bool_val = TRUE;
[Dd]elete return Delete;
}
+<SC_PROFILER>
+{
+ [Dd]isable[Pp]rofiler return DisableProfilerKeyword;
+ [Dd]isable[Cc]overage return DisableCoverageKeyword;
+ [Dd]ata[Bb]ase[Ff]ile return DatabaseFileKeyword;
+ [Aa]ggregate[Dd]ata return AggregateDataKeyword;
+ [Ss]tatistics[Ff]ile return StatisticsFileKeyword;
+ [Dd]isable[Ss]tatistics return DisableStatisticsKeyword;
+}
+
<SC_EXECUTE>control return ControlKeyword;
<SC_EXTERNAL_COMMANDS>
#include "LoggingBits.hh"
#include "LoggingParam.hh"
+#include "Profiler.hh"
+
#define YYERROR_VERBOSE
#include "config_process.lex.hh"
%token ModuleParametersKeyword
%token LoggingKeyword
+%token ProfilerKeyword
%token TestportParametersKeyword
%token ExecuteKeyword
%token ExternalCommandsKeyword
%token Retry
%token Delete
%token TtcnStringParsingKeyword
+%token DisableProfilerKeyword "DisableProfiler"
+%token DisableCoverageKeyword "DisableCoverage"
+%token DatabaseFileKeyword "DatabaseFile"
+%token AggregateDataKeyword "AggregateData"
+%token StatisticsFileKeyword "StatisticsFile"
+%token DisableStatisticsKeyword "DisableStatistics"
%type <int_val> IntegerValue
%type <float_val> FloatValue
Section:
ModuleParametersSection
| LoggingSection
+ | ProfilerSection
| TestportParametersSection
| ExecuteSection
| ExternalCommandsSection
| Detailed { $$ = TTCN_Logger::LOGEVENTTYPES_SUBCATEGORIES; }
;
+/*********************** [PROFILER] ********************************/
+
+ProfilerSection:
+ ProfilerKeyword ProfilerSettings
+;
+
+ProfilerSettings:
+ /* empty */
+| ProfilerSettings ProfilerSetting optSemiColon
+;
+
+ProfilerSetting:
+ DisableProfilerSetting
+| DisableCoverageSetting
+| DatabaseFileSetting
+| AggregateDataSetting
+| StatisticsFileSetting
+| DisableStatisticsSetting
+;
+
+DisableProfilerSetting:
+ DisableProfilerKeyword AssignmentChar BooleanValue {
+ ttcn3_prof.set_disable_profiler($3);
+ }
+;
+
+DisableCoverageSetting:
+ DisableCoverageKeyword AssignmentChar BooleanValue {
+ ttcn3_prof.set_disable_coverage($3);
+ }
+;
+
+DatabaseFileSetting:
+ DatabaseFileKeyword AssignmentChar StringValue {
+ ttcn3_prof.set_database_filename($3);
+ }
+;
+
+AggregateDataSetting:
+ AggregateDataKeyword AssignmentChar BooleanValue {
+ ttcn3_prof.set_aggregate_data($3);
+ }
+;
+
+StatisticsFileSetting:
+ StatisticsFileKeyword AssignmentChar StringValue {
+ ttcn3_prof.set_stats_filename($3);
+ }
+;
+
+DisableStatisticsSetting:
+ DisableStatisticsKeyword AssignmentChar BooleanValue {
+ ttcn3_prof.set_disable_stats($3);
+ }
+;
+
/**************** [TESTPORT_PARAMETERS] ****************************/
TestportParametersSection:
string_map_free(config_defines);
config_defines = NULL;
+ ttcn3_prof.init_data_file();
+
return !error_flag;
}
}
int Base_Type::XER_encode_negtest(const Erroneous_descriptor_t* /*p_err_descr*/,
- const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, unsigned int flavor, int indent) const
+ const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const
{
- return XER_encode(p_td, p_buf, flavor, indent); // ignore erroneous
+ return XER_encode(p_td, p_buf, flavor, indent, 0); // ignore erroneous
}
int Base_Type::RAW_encode_negtest(const Erroneous_descriptor_t *,
val_ptr = NULL;
}
else if (val_ptr->ref_count == 1) {
- if (refd_indices.empty()) {
+ if (NULL == refd_ind_ptr) {
for (int elem_count = 0; elem_count < val_ptr->n_elements; elem_count++) {
if (val_ptr->value_elements[elem_count] != NULL) {
delete val_ptr->value_elements[elem_count];
}
Record_Of_Type::Record_Of_Type(null_type /*other_value*/)
-: Base_Type(), val_ptr(new recordof_setof_struct), err_descr(NULL), max_refd_index(-1)
+: Base_Type(), val_ptr(new recordof_setof_struct), err_descr(NULL), refd_ind_ptr(NULL)
{
val_ptr->ref_count = 1;
val_ptr->n_elements = 0;
}
Record_Of_Type::Record_Of_Type(const Record_Of_Type& other_value)
-: Base_Type(other_value), val_ptr(NULL), err_descr(other_value.err_descr), max_refd_index(-1)
+: Base_Type(other_value), val_ptr(NULL), err_descr(other_value.err_descr), refd_ind_ptr(NULL)
{
if (!other_value.is_bound())
TTCN_error("Copying an unbound record of/set of value.");
// Increment ref_count only if val_ptr is not NULL
if (other_value.val_ptr != NULL) {
- if (other_value.refd_indices.empty()) {
+ if (NULL == other_value.refd_ind_ptr) {
val_ptr = other_value.val_ptr;
val_ptr->ref_count++;
}
int Record_Of_Type::get_nof_elements() const
{
int nof_elements = (val_ptr != NULL) ? val_ptr->n_elements : 0;
- if (!refd_indices.empty()) {
+ if (NULL != refd_ind_ptr) {
while (nof_elements > 0) {
if (is_elem_bound(nof_elements - 1)) {
break;
int Record_Of_Type::get_max_refd_index()
{
- if (refd_indices.empty()) {
+ if (NULL == refd_ind_ptr) {
return -1;
}
- if (-1 == max_refd_index) {
- for (size_t i = 0; i < refd_indices.size(); ++i) {
- if (refd_indices[i] > max_refd_index) {
- max_refd_index = refd_indices[i];
+ if (-1 == refd_ind_ptr->max_refd_index) {
+ for (size_t i = 0; i < refd_ind_ptr->refd_indices.size(); ++i) {
+ if (refd_ind_ptr->refd_indices[i] > refd_ind_ptr->max_refd_index) {
+ refd_ind_ptr->max_refd_index = refd_ind_ptr->refd_indices[i];
}
}
}
- return max_refd_index;
+ return refd_ind_ptr->max_refd_index;
}
bool Record_Of_Type::is_index_refd(int index)
{
- for (size_t i = 0; i < refd_indices.size(); ++i) {
- if (index == refd_indices[i]) {
+ if (NULL == refd_ind_ptr) {
+ return false;
+ }
+ for (size_t i = 0; i < refd_ind_ptr->refd_indices.size(); ++i) {
+ if (index == refd_ind_ptr->refd_indices[i]) {
return true;
}
}
TTCN_error("Assigning an unbound value of type %s.",
other_value->get_descriptor()->name);
if (this != other_recof) {
- if (refd_indices.empty() && other_recof->refd_indices.empty()) {
+ if (NULL == refd_ind_ptr && NULL == other_recof->refd_ind_ptr) {
clean_up();
val_ptr = other_recof->val_ptr;
val_ptr->ref_count++;
boolean Record_Of_Type::is_bound() const
{
- if (refd_indices.empty()) {
+ if (NULL == refd_ind_ptr) {
return (val_ptr != NULL);
}
return (get_nof_elements() != 0);
break;
}
sep_found=FALSE;
- if (refd_indices.empty()) {
+ if (NULL == refd_ind_ptr) {
val_ptr->value_elements = (Base_Type**)reallocate_pointers(
(void**)val_ptr->value_elements, val_ptr->n_elements, val_ptr->n_elements + 1);
val_ptr->value_elements[val_ptr->n_elements]=val;
}
return JSON_ERROR_FATAL;
}
- if (refd_indices.empty()) {
+ if (NULL == refd_ind_ptr) {
val_ptr->value_elements = (Base_Type**)reallocate_pointers(
(void**)val_ptr->value_elements, val_ptr->n_elements, val_ptr->n_elements + 1);
val_ptr->value_elements[val_ptr->n_elements] = val;
case TTCN_EncDec::CT_XER: {
TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
unsigned XER_coding=va_arg(pvar, unsigned);
- XER_encode(*(p_td.xer),p_buf, XER_coding, 0);
+ XER_encode(*(p_td.xer),p_buf, XER_coding, 0, 0);
p_buf.put_c('\n');
break;}
case TTCN_EncDec::CT_JSON: {
for (int success=reader.Read(); success==1; success=reader.Read()) {
if (reader.NodeType() == XML_READER_TYPE_ELEMENT) break;
}
- XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL);
+ XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL, 0);
size_t bytes = reader.ByteConsumed();
p_buf.set_pos(bytes);
break;}
static const universal_char tb = { 0,0,0,9 };
int Record_Of_Type::XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf,
- unsigned int flavor, int indent) const
+ unsigned int flavor, int indent, embed_values_enc_struct_t* emb_val) const
{
if (err_descr) {
- return XER_encode_negtest(err_descr, p_td, p_buf, flavor, indent);
+ return XER_encode_negtest(err_descr, p_td, p_buf, flavor, indent, emb_val);
}
if (val_ptr == 0) TTCN_error(
check_namespace_restrictions(p_td, (const char*)cs);
}
before.XER_encode(UNIVERSAL_CHARSTRING_xer_, p_buf,
- flavor | ANY_ATTRIBUTES, indent);
+ flavor | ANY_ATTRIBUTES, indent, 0);
p_buf.put_c('\'');
p_buf.put_c(' ');
UNIVERSAL_CHARSTRING after(len - j, (const universal_char*)(*elem) + j);
after.XER_encode(UNIVERSAL_CHARSTRING_xer_, p_buf,
- flavor | ANY_ATTRIBUTES, indent);
+ flavor | ANY_ATTRIBUTES, indent, 0);
// Put this attribute in a dummy element and walk through it to check its validity
TTCN_Buffer check_buf;
unsigned int sub_flavor = flavor | XER_RECOF | (p_td.xer_bits & (XER_LIST));
for (int i = 0; i < nof_elements; ++i) {
+ if (i > 0 && !own_tag && 0 != emb_val &&
+ emb_val->embval_index < emb_val->embval_array->size_of()) {
+ emb_val->embval_array->get_at(emb_val->embval_index)->XER_encode(
+ UNIVERSAL_CHARSTRING_xer_, p_buf, flavor | EMBED_VALUES, indent+1, 0);
+ ++emb_val->embval_index;
+ }
if (exer && (p_td.xer_bits & XER_LIST) && i>0) p_buf.put_c(' ');
get_at(i)->XER_encode(*get_elem_descr()->xer, p_buf,
- sub_flavor, indent+own_tag);
+ sub_flavor, indent+own_tag, emb_val);
}
if (indenting && nof_elements && !is_exerlist(flavor)) {
*/
int Record_Of_Type::encode_element(int i,
const Erroneous_values_t* ev, const Erroneous_descriptor_t* ed,
- TTCN_Buffer& p_buf, unsigned int sub_flavor, int indent) const
+ TTCN_Buffer& p_buf, unsigned int sub_flavor, int indent, embed_values_enc_struct_t* emb_val) const
{
int enc_len = p_buf.get_len();
TTCN_EncDec_ErrorContext ec;
if (ev->before->type_descr==NULL) TTCN_error(
"internal error: erroneous before type descriptor missing");
ev->before->errval->XER_encode(*ev->before->type_descr->xer,
- p_buf, sub_flavor, indent);
+ p_buf, sub_flavor, indent, 0);
}
}
if (ev->value->type_descr==NULL) TTCN_error(
"internal error: erroneous value type descriptor missing");
ev->value->errval->XER_encode(*ev->value->type_descr->xer,
- p_buf, sub_flavor, indent);
+ p_buf, sub_flavor, indent, 0);
}
} // else -> omit
} else {
ec.set_msg("Component #%d: ", i);
if (ed) {
- get_at(i)->XER_encode_negtest(ed, *get_elem_descr()->xer, p_buf, sub_flavor, indent);
+ get_at(i)->XER_encode_negtest(ed, *get_elem_descr()->xer, p_buf, sub_flavor, indent, emb_val);
} else {
// the "real" encoder
- get_at(i)->XER_encode(*get_elem_descr()->xer, p_buf, sub_flavor, indent);
+ get_at(i)->XER_encode(*get_elem_descr()->xer, p_buf, sub_flavor, indent, emb_val);
}
}
if (ev->after->type_descr==NULL) TTCN_error(
"internal error: erroneous after type descriptor missing");
ev->after->errval->XER_encode(*ev->after->type_descr->xer,
- p_buf, sub_flavor, indent);
+ p_buf, sub_flavor, indent, 0);
}
}
// XERSTUFF Record_Of_Type::XER_encode_negtest
int Record_Of_Type::XER_encode_negtest(const Erroneous_descriptor_t* p_err_descr,
- const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, unsigned flavor, int indent) const
+ const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, unsigned flavor, int indent,
+ embed_values_enc_struct_t* emb_val) const
{
if (val_ptr == 0) TTCN_error(
"Attempt to XER-encode an unbound record of type %s", get_descriptor()->name);
if (ev->before->type_descr==NULL) TTCN_error(
"internal error: erroneous before type descriptor missing");
else ev->before->errval->XER_encode(*ev->before->type_descr->xer,
- p_buf, flavor, indent);
+ p_buf, flavor, indent, 0);
}
}
if (ev->value->type_descr==NULL) TTCN_error(
"internal error: erroneous value type descriptor missing");
else ev->value->errval->XER_encode(*ev->value->type_descr->xer,
- p_buf, flavor, indent);
+ p_buf, flavor, indent, 0);
}
}
}
UNIVERSAL_CHARSTRING before(sp_at, (const universal_char*)(*elem));
before.XER_encode(UNIVERSAL_CHARSTRING_xer_, p_buf,
- flavor | ANY_ATTRIBUTES, indent);
+ flavor | ANY_ATTRIBUTES, indent, 0);
p_buf.put_c('\'');
p_buf.put_c(' ');
UNIVERSAL_CHARSTRING after(len - j, (const universal_char*)(*elem) + j);
after.XER_encode(UNIVERSAL_CHARSTRING_xer_, p_buf,
- flavor | ANY_ATTRIBUTES, indent);
+ flavor | ANY_ATTRIBUTES, indent, 0);
}
}
if (ev->after->type_descr==NULL) TTCN_error(
"internal error: erroneous after type descriptor missing");
else ev->after->errval->XER_encode(*ev->after->type_descr->xer,
- p_buf, flavor, indent);
+ p_buf, flavor, indent, 0);
}
}
}
for (int i = 0; i < nof_elements; ++i) {
if (i < p_err_descr->omit_before) continue;
+
+ if (0 != emb_val && i > 0 && !own_tag &&
+ emb_val->embval_index < emb_val->embval_array->size_of()) {
+ const Erroneous_values_t * ev0_i = NULL;
+ const Erroneous_descriptor_t* ed0_i = NULL;
+ if (emb_val->embval_err) {
+ ev0_i = emb_val->embval_err->next_field_err_values(emb_val->embval_index, emb_val->embval_err_val_idx);
+ ed0_i = emb_val->embval_err->next_field_emb_descr (emb_val->embval_index, emb_val->embval_err_descr_idx);
+ }
+ emb_val->embval_array->encode_element(emb_val->embval_index, ev0_i, ed0_i,
+ p_buf, flavor | EMBED_VALUES, indent + own_tag, 0);
+ ++emb_val->embval_index;
+ }
const Erroneous_values_t* err_vals =
p_err_descr->next_field_err_values(i, values_idx);
const Erroneous_descriptor_t* emb_descr =
p_err_descr->next_field_emb_descr (i, edescr_idx);
- encode_element(i, err_vals, emb_descr, p_buf, sub_flavor, indent+own_tag);
+ encode_element(i, err_vals, emb_descr, p_buf, sub_flavor, indent+own_tag, emb_val);
// omit_after value -1 becomes "very big"
if ((unsigned int)i >= (unsigned int)p_err_descr->omit_after) break;
}
int Record_Of_Type::XER_decode(const XERdescriptor_t& p_td,
- XmlReaderWrap& reader, unsigned int flavor)
+ XmlReaderWrap& reader, unsigned int flavor, embed_values_dec_struct_t* emb_val)
{
int exer = is_exer(flavor);
int xerbits = p_td.xer_bits;
// The call to the non-const operator[], I mean get_at(), creates
// a new element (because it is indexing one past the last element).
// Then we call its XER_decode with the temporary XML reader.
- get_at(get_nof_elements())->XER_decode(sub_xer, reader2, flavor);
+ get_at(get_nof_elements())->XER_decode(sub_xer, reader2, flavor, 0);
if (flavor & EXIT_ON_ERROR && !is_elem_bound(get_nof_elements() - 1)) {
if (1 == get_nof_elements()) {
// Failed to decode even the first element
}
ec_1.set_msg("%d: ", get_nof_elements());
/* The call to the non-const get_at() creates the element */
- get_at(get_nof_elements())->XER_decode(*get_elem_descr()->xer, reader, flavor);
+ get_at(get_nof_elements())->XER_decode(*get_elem_descr()->xer, reader, flavor, emb_val);
+ if (0 != emb_val && !own_tag && get_nof_elements() > 1) {
+ ++emb_val->embval_index;
+ }
}
}
else if (XML_READER_TYPE_END_ELEMENT == type) {
}
break;
}
+ else if (XML_READER_TYPE_TEXT == type && 0 != emb_val && !own_tag && get_nof_elements() > 0) {
+ UNIVERSAL_CHARSTRING emb_ustr((const char*)reader.Value());
+ emb_val->embval_array->get_at(emb_val->embval_index)->set_value(&emb_ustr);
+ success = reader.Read();
+ }
else {
success = reader.Read();
}
void Record_Of_Type::add_refd_index(int index)
{
- refd_indices.push_back(index);
+ if (NULL == refd_ind_ptr) {
+ refd_ind_ptr = new refd_index_struct;
+ refd_ind_ptr->max_refd_index = -1;
+ }
+ refd_ind_ptr->refd_indices.push_back(index);
if (index > get_max_refd_index()) {
- max_refd_index = index;
+ refd_ind_ptr->max_refd_index = index;
}
}
void Record_Of_Type::remove_refd_index(int index)
{
- for (size_t i = refd_indices.size(); i > 0; --i) {
- if (refd_indices[i - 1] == index) {
- refd_indices.erase_at(i - 1);
+ for (size_t i = refd_ind_ptr->refd_indices.size(); i > 0; --i) {
+ if (refd_ind_ptr->refd_indices[i - 1] == index) {
+ refd_ind_ptr->refd_indices.erase_at(i - 1);
break;
}
}
- if (get_max_refd_index() == index) {
- max_refd_index = -1;
+ if (refd_ind_ptr->refd_indices.empty()) {
+ delete refd_ind_ptr;
+ refd_ind_ptr = NULL;
+ }
+ else if (get_max_refd_index() == index) {
+ refd_ind_ptr->max_refd_index = -1;
}
}
case TTCN_EncDec::CT_XER: {
TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
unsigned XER_coding=va_arg(pvar, unsigned);
- XER_encode(*(p_td.xer),p_buf, XER_coding, 0);
+ XER_encode(*(p_td.xer),p_buf, XER_coding, 0, 0);
p_buf.put_c('\n');
break;}
case TTCN_EncDec::CT_JSON: {
for (int success=reader.Read(); success==1; success=reader.Read()) {
if (reader.NodeType() == XML_READER_TYPE_ELEMENT) break;
}
- XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL);
+ XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL, 0);
size_t bytes = reader.ByteConsumed();
p_buf.set_pos(bytes);
break;}
}
int Record_Type::XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf,
- unsigned int flavor, int indent) const
+ unsigned int flavor, int indent, embed_values_enc_struct_t*) const
{
if (err_descr) {
- return XER_encode_negtest(err_descr, p_td, p_buf, flavor, indent);
+ return XER_encode_negtest(err_descr, p_td, p_buf, flavor, indent, 0);
}
if (!is_bound()) {
TTCN_EncDec_ErrorContext::error
const Base_Type * const q_uri = get_at(0);
if (q_uri->is_present()) {
p_buf.put_s(11, (cbyte*)" xmlns:b0='");
- q_uri->XER_encode(*xer_descr(0), p_buf, flavor | XER_LIST, indent+1);
+ q_uri->XER_encode(*xer_descr(0), p_buf, flavor | XER_LIST, indent+1, 0);
p_buf.put_c('\'');
}
sub_len += 3;
}
const Base_Type* const q_name = get_at(1);
- sub_len += q_name->XER_encode(*xer_descr(1), p_buf, flavor | XER_LIST, indent+1);
+ sub_len += q_name->XER_encode(*xer_descr(1), p_buf, flavor | XER_LIST, indent+1, 0);
if (p_td.xer_bits & XER_ATTRIBUTE) p_buf.put_c('\'');
}
else { // not USE-QNAME
if (!exer && (p_td.xer_bits & EMBED_VALUES)) {
// The EMBED-VALUES member as an ordinary record of string
- sub_len += embed_values->XER_encode(*xer_descr(0), p_buf, flavor, indent+1);
+ sub_len += embed_values->XER_encode(*xer_descr(0), p_buf, flavor, indent+1, 0);
}
if (!exer && (p_td.xer_bits & USE_ORDER)) {
// The USE-ORDER member as an ordinary record of enumerated
- sub_len += use_order->XER_encode(*xer_descr(uo_index), p_buf, flavor, indent+1);
+ sub_len += use_order->XER_encode(*xer_descr(uo_index), p_buf, flavor, indent+1, 0);
}
if (exer && (indent==0 || (flavor & DEF_NS_SQUASHED))) // write namespaces for toplevel only
for (i = start_at; i < first_nonattr; ++i) {
boolean is_xer_attr_field = xer_descr(i)->xer_bits & XER_ATTRIBUTE;
ec_1.set_msg("%s': ", fld_name(i)); // attr
- int tmp_len = get_at(i)->XER_encode(*xer_descr(i), p_buf, flavor, indent+1);
+ int tmp_len = get_at(i)->XER_encode(*xer_descr(i), p_buf, flavor, indent+1, 0);
if (is_xer_attr_field && !exer) sub_len += tmp_len; /* do not add if attribute and EXER */
}
p_buf.put_s(start_tag_len , (cbyte*)">\n");
}
- int expected_embed = (field_cnt - first_nonattr + 1);
if (exer && (p_td.xer_bits & EMBED_VALUES)) {
- ec_1.set_msg("%s': ", fld_name(0));
- int num_opt;
- if ((p_td.xer_bits & USE_NIL) && !get_at(field_cnt-1)->ispresent()) {
- expected_embed = 0; //25.2.6 a
- }
- else if ((num_opt = optional_count())) {
- const int * optionals = get_optional_indexes();
- for (int opt_idx = 0; opt_idx < num_opt; ++opt_idx) {
- // skip optional attributes
- if (optionals[opt_idx] < start_at + num_attributes) continue;
- // reduce for each omitted member
- if (!get_at(optionals[opt_idx])->is_present()) --expected_embed;
- }
- }
- // Check the correct number of EMBED-VALUES (regular non-attributes + 1)
- if (embed_values->size_of() != expected_embed)
- TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT,
- "Wrong number %d of EMBED-VALUEs, expected %d",
- embed_values->size_of(), expected_embed);
/* write the first string */
- if (expected_embed > 0) {
+ if (embed_values->size_of() > 0) {
sub_len += embed_values->get_at(0)->XER_encode(UNIVERSAL_CHARSTRING_xer_,
- p_buf, flavor | EMBED_VALUES, indent+1);
+ p_buf, flavor | EMBED_VALUES, indent+1, 0);
}
}
* pseudo-members for USE-ORDER, etc.) */
// early_to_bed can only be true if exer is true (transitive through nil_attribute)
- if (!early_to_bed) for ( i = begin; i < end; ++i ) {
- const Base_Type *uoe = 0; // "useOrder enum"
- const Enum_Type *enm = 0; // the enum value selecting the field
- if (exer && use_order) {
- uoe = use_order->get_at(i - begin);
- enm = static_cast<const Enum_Type *>(uoe);
- }
-
- // "actual" index, may be perturbed by USE-ORDER
- int ai = !(exer && (p_td.xer_bits & USE_ORDER)) ? i :
- enm->as_int() + useorder_base;
- ec_1.set_msg("%s': ", ordered->fld_name(ai)); // non-attr
-
- const XERdescriptor_t& descr = *ordered->xer_descr(ai);
- sub_len += ordered->get_at(ai)->XER_encode(descr, p_buf,
- // Pass USE-NIL to the last field (except when USE-ORDER is also in effect,
- // because the tag-stripping effect of USE-NIL has been achieved
- // by encoding the sub-fields directly).
- flavor | ((exer && !use_order && (i == field_cnt-1)) ? (p_td.xer_bits & USE_NIL) : 0),
- indent+!omit_tag);
-
- // Now the next embed-values string (NOT affected by USE-ORDER!)
- if (exer && (p_td.xer_bits & EMBED_VALUES) && (i - begin + 1) < expected_embed) {
- embed_values->get_at(i - begin + 1)->XER_encode(UNIVERSAL_CHARSTRING_xer_
- , p_buf, flavor | EMBED_VALUES, indent+1);
- }
- } //for
+ if (!early_to_bed) {
+ embed_values_enc_struct_t* emb_val = 0;
+ if (exer && (p_td.xer_bits & EMBED_VALUES) && embed_values->size_of() > 1) {
+ emb_val = new embed_values_enc_struct_t;
+ emb_val->embval_array = embed_values;
+ emb_val->embval_index = 1;
+ emb_val->embval_err = 0;
+ }
+
+ for ( i = begin; i < end; ++i ) {
+ const Base_Type *uoe = 0; // "useOrder enum"
+ const Enum_Type *enm = 0; // the enum value selecting the field
+ if (exer && use_order) {
+ uoe = use_order->get_at(i - begin);
+ enm = static_cast<const Enum_Type *>(uoe);
+ }
+
+ // "actual" index, may be perturbed by USE-ORDER
+ int ai = !(exer && (p_td.xer_bits & USE_ORDER)) ? i :
+ enm->as_int() + useorder_base;
+ ec_1.set_msg("%s': ", ordered->fld_name(ai)); // non-attr
+
+ const XERdescriptor_t& descr = *ordered->xer_descr(ai);
+ sub_len += ordered->get_at(ai)->XER_encode(descr, p_buf,
+ // Pass USE-NIL to the last field (except when USE-ORDER is also in effect,
+ // because the tag-stripping effect of USE-NIL has been achieved
+ // by encoding the sub-fields directly).
+ flavor | ((exer && !use_order && (i == field_cnt-1)) ? (p_td.xer_bits & USE_NIL) : 0),
+ indent+!omit_tag, emb_val);
+
+ // Now the next embed-values string (NOT affected by USE-ORDER!)
+ if (exer && (p_td.xer_bits & EMBED_VALUES) && 0 != emb_val &&
+ emb_val->embval_index < embed_values->size_of()) {
+ embed_values->get_at(emb_val->embval_index)->XER_encode(UNIVERSAL_CHARSTRING_xer_
+ , p_buf, flavor | EMBED_VALUES, indent+1, 0);
+ ++emb_val->embval_index;
+ }
+ } //for
+
+ if (0 != emb_val) {
+ if (emb_val->embval_index < embed_values->size_of()) {
+ ec_1.set_msg("%s': ", fld_name(0));
+ TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT,
+ "Too many EMBED-VALUEs specified: %d (expected %d or less)",
+ embed_values->size_of(), emb_val->embval_index);
+ }
+ delete emb_val;
+ }
+ } // if (!early_to_bed)
} // if (QNAME)
if (!omit_tag) {
*/
int Record_Type::encode_field(int i,
const Erroneous_values_t* err_vals, const Erroneous_descriptor_t* emb_descr,
- TTCN_Buffer& p_buf, unsigned int sub_flavor, int indent) const
+ TTCN_Buffer& p_buf, unsigned int sub_flavor, int indent, embed_values_enc_struct_t* emb_val) const
{
int enc_len = 0;
TTCN_EncDec_ErrorContext ec;
if (err_vals->before->type_descr==NULL) TTCN_error(
"internal error: erroneous before typedescriptor missing");
enc_len += err_vals->before->errval->XER_encode(
- *err_vals->before->type_descr->xer, p_buf, sub_flavor, indent);
+ *err_vals->before->type_descr->xer, p_buf, sub_flavor, indent, 0);
}
}
if (err_vals->value->type_descr==NULL) TTCN_error(
"internal error: erroneous value typedescriptor missing");
enc_len += err_vals->value->errval->XER_encode(
- *err_vals->value->type_descr->xer, p_buf, sub_flavor, indent);
+ *err_vals->value->type_descr->xer, p_buf, sub_flavor, indent, 0);
}
} // else -> omit
} else {
ec.set_msg("Component %s: ", fld_name(i));
if (emb_descr) {
enc_len += get_at(i)->XER_encode_negtest(emb_descr, *xer_descr(i), p_buf,
- sub_flavor, indent);
+ sub_flavor, indent, emb_val);
} else {
// the "real" encoder
enc_len += get_at(i)->XER_encode(*xer_descr(i), p_buf,
- sub_flavor, indent);
+ sub_flavor, indent, emb_val);
}
}
if (err_vals->after->type_descr==NULL) TTCN_error(
"internal error: erroneous after typedescriptor missing");
enc_len += err_vals->after->errval->XER_encode(
- *err_vals->after->type_descr->xer, p_buf, sub_flavor, indent);
+ *err_vals->after->type_descr->xer, p_buf, sub_flavor, indent, 0);
}
}
// XERSTUFF Record_Type::XER_encode_negtest
int Record_Type::XER_encode_negtest(const Erroneous_descriptor_t* p_err_descr,
- const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, unsigned int flavor, int indent) const
+ const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, unsigned int flavor, int indent,
+ embed_values_enc_struct_t*) const
{
if (!is_bound()) {
TTCN_EncDec_ErrorContext::error
if (ev->before->type_descr==NULL) TTCN_error(
"internal error: erroneous before typedescriptor missing");
sub_len += ev->before->errval->XER_encode(
- *ev->before->type_descr->xer, p_buf, flavor, indent);
+ *ev->before->type_descr->xer, p_buf, flavor, indent, 0);
}
}
if (ev->value->type_descr==NULL) TTCN_error(
"internal error: erroneous value typedescriptor missing");
sub_len += ev->value->errval->XER_encode(
- *ev->value->type_descr->xer, p_buf, flavor, indent);
+ *ev->value->type_descr->xer, p_buf, flavor, indent, 0);
}
} // else -> omit
} else {
// the "real" encoder
if (q_uri->is_present()) {
p_buf.put_s(11, (cbyte*)" xmlns:b0='");
- sub_len += q_uri->XER_encode(*xer_descr(0), p_buf, flavor | XER_LIST, indent+1);
+ sub_len += q_uri->XER_encode(*xer_descr(0), p_buf, flavor | XER_LIST, indent+1, 0);
p_buf.put_c('\'');
}
}
if (ev->after->type_descr==NULL) TTCN_error(
"internal error: erroneous after typedescriptor missing");
sub_len += ev->after->errval->XER_encode(
- *ev->after->type_descr->xer, p_buf, flavor, indent);
+ *ev->after->type_descr->xer, p_buf, flavor, indent, 0);
}
}
if (ev->before->type_descr==NULL) TTCN_error(
"internal error: erroneous before typedescriptor missing");
sub_len += ev->before->errval->XER_encode(
- *ev->before->type_descr->xer, p_buf, flavor, indent);
+ *ev->before->type_descr->xer, p_buf, flavor, indent, 0);
}
}
if (ev->value->type_descr==NULL) TTCN_error(
"internal error: erroneous value typedescriptor missing");
sub_len += ev->value->errval->XER_encode(
- *ev->value->type_descr->xer, p_buf, flavor, indent);
+ *ev->value->type_descr->xer, p_buf, flavor, indent, 0);
}
} // else -> omit
} else {
sub_len += 3;
}
- sub_len += get_at(1)->XER_encode(*xer_descr(1), p_buf, flavor | XER_LIST, indent+1);
+ sub_len += get_at(1)->XER_encode(*xer_descr(1), p_buf, flavor | XER_LIST, indent+1, 0);
}
}
if (ev->after->type_descr==NULL) TTCN_error(
"internal error: erroneous after typedescriptor missing");
sub_len += ev->after->errval->XER_encode(
- *ev->after->type_descr->xer, p_buf, flavor, indent);
+ *ev->after->type_descr->xer, p_buf, flavor, indent, 0);
}
}
else { // not USE-QNAME
if (!exer && (p_td.xer_bits & EMBED_VALUES)) {
// The EMBED-VALUES member as an ordinary record of string
- sub_len += embed_values->XER_encode(*xer_descr(0), p_buf, flavor, indent+1);
+ sub_len += embed_values->XER_encode(*xer_descr(0), p_buf, flavor, indent+1, 0);
}
if (!exer && (p_td.xer_bits & USE_ORDER)) {
// The USE-ORDER member as an ordinary record of enumerated
- sub_len += use_order->XER_encode(*xer_descr(uo_index), p_buf, flavor, indent+1);
+ sub_len += use_order->XER_encode(*xer_descr(uo_index), p_buf, flavor, indent+1, 0);
}
if (exer && (indent==0 || (flavor & DEF_NS_SQUASHED))) // write namespaces for toplevel only
boolean is_xer_attr_field = xer_descr(i)->xer_bits & XER_ATTRIBUTE;
ec_1.set_msg("%s': ", fld_name(i)); // attr
- tmp_len = encode_field(i, ev, ed, p_buf, flavor, indent + !omit_tag);
+ tmp_len = encode_field(i, ev, ed, p_buf, flavor, indent + !omit_tag, 0);
if (is_xer_attr_field && !exer) sub_len += tmp_len; // do not add if attribute and EXER
int embed_values_val_idx = 0;
int embed_values_descr_idx = 0;
- int expected_embed = (field_cnt - first_nonattr + 1);
if (exer && (p_td.xer_bits & EMBED_VALUES)) {
ed0 = p_err_descr->next_field_emb_descr(0, edescr_idx);
- ec_1.set_msg("%s': ", fld_name(0));
- int num_opt;
- if ((p_td.xer_bits & USE_NIL) && !get_at(field_cnt-1)->ispresent()) {
- expected_embed = 0; //25.2.6 a
- }
- else if ((num_opt = optional_count()) > 0) {
- const int * optionals = get_optional_indexes();
- for (int opt_idx = 0; opt_idx < num_opt; ++opt_idx) {
- // skip optional attributes
- if (optionals[opt_idx] < start_at + num_attributes) continue;
- // reduce for each omitted member
- if (!get_at(optionals[opt_idx])->is_present()) --expected_embed;
- }
- }
- // Check the correct number of EMBED-VALUES (regular non-attributes + 1)
- if (embed_values->size_of() != expected_embed)
- TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT,
- "Wrong number %d of EMBED-VALUEs, expected %d",
- embed_values->size_of(), expected_embed);
// write the first string
- if (expected_embed > 0) {
+ if (embed_values->size_of() > 0) {
const Erroneous_values_t * ev0_0 = NULL;
const Erroneous_descriptor_t* ed0_0 = NULL;
if (ed0) {
ed0_0 = ed0->next_field_emb_descr (0, embed_values_descr_idx);
}
sub_len += embed_values->encode_element(0, ev0_0, ed0_0,
- p_buf, flavor | EMBED_VALUES, indent+!omit_tag);
+ p_buf, flavor | EMBED_VALUES, indent+!omit_tag, 0);
}
}
// fields of this record; and the USE_ORDER case (with or without USE-NIL).
//
// early_to_bed can only be true if exer is true (transitive through nil_attribute)
- if (!early_to_bed) for ( i = begin; i < end; ++i ) {
-
- const Base_Type *uoe = 0; // "useOrder enum"
- const Enum_Type *enm = 0; // the enum value selecting the field
-
- // "actual" index, may be perturbed by USE-ORDER.
- // We use this value to index the appropriate record.
- int ai = i;
-
- const Erroneous_values_t * ev = NULL;
- const Erroneous_descriptor_t* ed = NULL;
- if (exer && use_order) {
- // If USE-ORDER is in effect, it introduces a level of indirection
- // into the indexing of fields: "i" is used to select an element
- // of the use_order member (an enum), whose value is used to select
- // the field being encoded.
- uoe = use_order->get_at(i - begin);
- enm = static_cast<const Enum_Type *>(uoe);
- ai = enm->as_int() + useorder_base;
-
- // Because it is not guaranteed that ai will increase monotonically,
- // we can't use next_field_...().
- ev = p_err_descr->get_field_err_values(ai);
- ed = p_err_descr->get_field_emb_descr (ai);
- }
- else { // not USE-ORDER, sequential access
- ev = p_err_descr->next_field_err_values(ai, values_idx);
- ed = p_err_descr->next_field_emb_descr (ai, edescr_idx);
- }
- ec_1.set_msg("%s': ", ordered->fld_name(ai)); // non-attr
-
- if (ai < p_err_descr->omit_before) continue;
-
- // omit_after value -1 becomes "very big".
- if ((unsigned int)ai > (unsigned int)p_err_descr->omit_after) continue;
- // We can't skip all fields with break, because the next ai may be lower
- // than omit_after.
-
- sub_len += ordered->encode_field(ai, ev, ed, p_buf,
- // Pass USE-NIL to the last field (except when USE-ORDER is also in effect,
- // because the tag-stripping effect of USE-NIL has been achieved
- // by encoding the sub-fields directly).
- flavor | ((exer && !use_order && (i == field_cnt-1)) ? (p_td.xer_bits & USE_NIL) : 0),
- indent + !omit_tag);
-
- // Now the next embed-values string (NOT affected by USE-ORDER!)
- int i1 = i - begin + 1;
- if (exer && (p_td.xer_bits & EMBED_VALUES) && i1 < expected_embed) {
- const Erroneous_values_t * ev0_i = NULL;
- const Erroneous_descriptor_t* ed0_i = NULL;
- if (ed0) {
- ev0_i = ed0->next_field_err_values(i1, embed_values_val_idx);
- ed0_i = ed0->next_field_emb_descr (i1, embed_values_descr_idx);
+ if (!early_to_bed) {
+ embed_values_enc_struct_t* emb_val = 0;
+ if (exer && (p_td.xer_bits & EMBED_VALUES) && embed_values->size_of() > 1) {
+ emb_val = new embed_values_enc_struct_t;
+ emb_val->embval_array = embed_values;
+ emb_val->embval_index = 1;
+ emb_val->embval_err = ed0;
+ emb_val->embval_err_val_idx = embed_values_val_idx;
+ emb_val->embval_err_descr_idx = embed_values_descr_idx;
+ }
+
+ for ( i = begin; i < end; ++i ) {
+
+ const Base_Type *uoe = 0; // "useOrder enum"
+ const Enum_Type *enm = 0; // the enum value selecting the field
+
+ // "actual" index, may be perturbed by USE-ORDER.
+ // We use this value to index the appropriate record.
+ int ai = i;
+
+ const Erroneous_values_t * ev = NULL;
+ const Erroneous_descriptor_t* ed = NULL;
+ if (exer && use_order) {
+ // If USE-ORDER is in effect, it introduces a level of indirection
+ // into the indexing of fields: "i" is used to select an element
+ // of the use_order member (an enum), whose value is used to select
+ // the field being encoded.
+ uoe = use_order->get_at(i - begin);
+ enm = static_cast<const Enum_Type *>(uoe);
+ ai = enm->as_int() + useorder_base;
+
+ // Because it is not guaranteed that ai will increase monotonically,
+ // we can't use next_field_...().
+ ev = p_err_descr->get_field_err_values(ai);
+ ed = p_err_descr->get_field_emb_descr (ai);
+ }
+ else { // not USE-ORDER, sequential access
+ ev = p_err_descr->next_field_err_values(ai, values_idx);
+ ed = p_err_descr->next_field_emb_descr (ai, edescr_idx);
+ }
+ ec_1.set_msg("%s': ", ordered->fld_name(ai)); // non-attr
+
+ if (ai < p_err_descr->omit_before) continue;
+
+ // omit_after value -1 becomes "very big".
+ if ((unsigned int)ai > (unsigned int)p_err_descr->omit_after) continue;
+ // We can't skip all fields with break, because the next ai may be lower
+ // than omit_after.
+
+ sub_len += ordered->encode_field(ai, ev, ed, p_buf,
+ // Pass USE-NIL to the last field (except when USE-ORDER is also in effect,
+ // because the tag-stripping effect of USE-NIL has been achieved
+ // by encoding the sub-fields directly).
+ flavor | ((exer && !use_order && (i == field_cnt-1)) ? (p_td.xer_bits & USE_NIL) : 0),
+ indent + !omit_tag, emb_val);
+
+ // Now the next embed-values string (NOT affected by USE-ORDER!)
+ if (exer && (p_td.xer_bits & EMBED_VALUES) && 0 != emb_val &&
+ emb_val->embval_index < embed_values->size_of()) {
+ const Erroneous_values_t * ev0_i = NULL;
+ const Erroneous_descriptor_t* ed0_i = NULL;
+ if (ed0) {
+ ev0_i = ed0->next_field_err_values(emb_val->embval_index, emb_val->embval_err_val_idx);
+ ed0_i = ed0->next_field_emb_descr (emb_val->embval_index, emb_val->embval_err_descr_idx);
+ }
+ embed_values->encode_element(emb_val->embval_index, ev0_i, ed0_i,
+ p_buf, flavor | EMBED_VALUES, indent + !omit_tag, 0);
+ ++emb_val->embval_index;
+ }
+ } //for
+ if (0 != emb_val) {
+ if (emb_val->embval_index < embed_values->size_of()) {
+ ec_1.set_msg("%s': ", fld_name(0));
+ TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT,
+ "Too many EMBED-VALUEs specified: %d (expected %d or less)",
+ embed_values->size_of(), emb_val->embval_index);
}
- embed_values->encode_element(i1, ev0_i, ed0_i,
- p_buf, flavor | EMBED_VALUES, indent + !omit_tag);
+ delete emb_val;
}
- } //for
+ } // if (!early_to_bed)
} // if (QNAME)
return (int)p_buf.get_len() - encoded_length;
}
-int Record_Type::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, unsigned int flavor)
+int Record_Type::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
+ unsigned int flavor, embed_values_dec_struct_t*)
{
bound_flag = TRUE;
int exer = is_exer(flavor);
for (int k = 0; k < first_nonattr; ++k) {
if (xer_descr(k)->xer_bits & ANY_ATTRIBUTES) {
aa_index = k;
- static_cast<Record_Of_Type*>(get_at(aa_index))->set_size(0);
+ if (!get_at(aa_index)->is_optional()) {
+ static_cast<Record_Of_Type*>(get_at(aa_index))->set_size(0);
+ }
break; // there can be only one, 18.2.2
}
}
// First, the (would-be) attributes (unaffected by USE-ORDER)
for (i = 0; i < first_nonattr; i++) {
ec_1.set_msg("%s': ", fld_name(i));
- get_at(i)->XER_decode(*xer_descr(i), reader, flavor);
+ get_at(i)->XER_decode(*xer_descr(i), reader, flavor, 0);
} // next field
}
else if (own_tag || parent_tag) { // EXER and not UNTAGGED: do attributes
if (field_index != -1) {
// There is a field. Let it decode the attribute.
ec_1.set_msg("%s': ", fld_name(field_index));
- get_at(field_index)->XER_decode(*xer_descr(field_index), reader, flavor);
+ get_at(field_index)->XER_decode(*xer_descr(field_index), reader, flavor, 0);
continue;
}
TTCN_EncDec_ErrorContext ec_2("Attribute %d: ", num_aa);
// We have a component with ANY-ATTRIBUTE. It must be a record of
// UNIVERSAL_CHARSTRING. Add the attribute to it.
- Record_Of_Type *aa = static_cast<Record_Of_Type *>(get_at(aa_index));
+ Record_Of_Type *aa = 0;
+ if (get_at(aa_index)->is_optional()) {
+ if (num_aa == 0) {
+ get_at(aa_index)->set_to_present();
+ }
+ aa = static_cast<Record_Of_Type*>(get_at(aa_index)->get_opt_value());
+ }
+ else {
+ aa = static_cast<Record_Of_Type*>(get_at(aa_index));
+ }
UNIVERSAL_CHARSTRING *new_elem = static_cast<UNIVERSAL_CHARSTRING *>
(aa->get_at(num_aa++));
} // end if (own_tag)
/* * * * * * * * Non-attributes (elements) * * * * * * * * * * * */
- Record_Of_Type* embed_values = 0;
+ embed_values_dec_struct_t* emb_val = 0;
if (exer && (p_td.xer_bits & EMBED_VALUES)) {
- embed_values = static_cast<Record_Of_Type*>(get_at(0));
+ emb_val = new embed_values_dec_struct_t;
+ emb_val->embval_array = static_cast<Record_Of_Type*>(get_at(0));
+ emb_val->embval_array->set_size(0);
+ emb_val->embval_index = 0;
}
if (exer && (p_td.xer_bits & USE_ORDER)) {
int *seen = new int[end-begin];
int num_seen = 0;
int last_any_elem = begin - 1;
+ // The index of the latest embedded value can change outside of this function
+ // (if the field is a untagged record of), in this case the next value should
+ // be ignored, as it's already been handled by the record of
+ int last_embval_index = 0;
for (i = begin; i < end; i++) {
for (success = reader.Ok(); success == 1; success = reader.Read()) {
type = reader.NodeType();
- if (embed_values) {
- if (reader.NodeType()==XML_READER_TYPE_TEXT) {
- UNIVERSAL_CHARSTRING emb_ustr((const char*)reader.Value());
- embed_values->get_at(i-begin)->set_value(&emb_ustr);
- }
+ if (0 != emb_val && reader.NodeType()==XML_READER_TYPE_TEXT) {
+ UNIVERSAL_CHARSTRING emb_ustr((const char*)reader.Value());
+ emb_val->embval_array->get_at(emb_val->embval_index)->set_value(&emb_ustr);
}
// The non-attribute components must not be UNTAGGED
if (type == XML_READER_TYPE_ELEMENT) break;
// else if (type==XML_READER_TYPE_END_ELEMENT) panic?
}
+ if (0 != emb_val) {
+ if (last_embval_index == emb_val->embval_index) {
+ ++emb_val->embval_index;
+ }
+ last_embval_index = emb_val->embval_index;
+ }
if (success != 1) break;
const char *name = (const char *)reader.LocalName();
boolean field_name_found = false;
static_cast<Enum_Type*>(use_order->get_at(i - begin))
->from_int(in_dex);
Base_Type *b = jumbled->get_at(k);
- b->XER_decode(*jumbled->xer_descr(k), reader, flavor);
+ b->XER_decode(*jumbled->xer_descr(k), reader, flavor, emb_val);
field_name_found = true;
break;
}
static_cast<Enum_Type*>(use_order->get_at(i - begin))
->from_int(in_dex);
Base_Type *b = jumbled->get_at(k);
- b->XER_decode(*jumbled->xer_descr(k), reader, flavor);
+ b->XER_decode(*jumbled->xer_descr(k), reader, flavor, emb_val);
last_any_elem = k;
break;
}
}
}
} // next field
- if (embed_values) {
+ if (0 != emb_val) {
if (reader.NodeType()==XML_READER_TYPE_TEXT) {
UNIVERSAL_CHARSTRING emb_ustr((const char*)reader.Value());
- embed_values->get_at(i-begin)->set_value(&emb_ustr);
+ emb_val->embval_array->get_at(emb_val->embval_index)->set_value(&emb_ustr);
+ }
+ if (last_embval_index == emb_val->embval_index) {
+ ++emb_val->embval_index;
}
}
delete [] seen;
if (usenil_attribute) {
reader.MoveToElement(); // value absent, nothing more to do
} else {
- int emb_idx = 0;
+ // The index of the latest embedded value can change outside of this function
+ // (if the field is a untagged record of), in this case the next value should
+ // be ignored, as it's already been handled by the record of
+ // Omitted fields can also reset this value
+ int last_embval_index = 0;
for (; i<field_cnt; i++) {
- if (embed_values) {
+ if (0 != emb_val) {
if (reader.NodeType()==XML_READER_TYPE_TEXT) {
UNIVERSAL_CHARSTRING emb_ustr((const char*)reader.Value());
- embed_values->get_at(emb_idx)->set_value(&emb_ustr);
+ emb_val->embval_array->get_at(emb_val->embval_index)->set_value(&emb_ustr);
}
- emb_idx++;
+ if (last_embval_index == emb_val->embval_index) {
+ ++emb_val->embval_index;
+ }
+ last_embval_index = emb_val->embval_index;
}
ec_1.set_msg("%s': ", fld_name(i));
if (exer && i==field_cnt-1 && p_td.dfeValue && reader.IsEmptyElement()) {
if (i == field_cnt-1) new_flavor |= (p_td.xer_bits & USE_NIL);
if (tag_closed) new_flavor |= PARENT_CLOSED;
- get_at(i)->XER_decode(*xer_descr(i), reader, new_flavor);
+ get_at(i)->XER_decode(*xer_descr(i), reader, new_flavor, emb_val);
}
}
+ if (!get_at(i)->is_present()) {
+ // there was no new element, the last embedded value is for the next field
+ // (or the end of the record if this is the last field)
+ last_embval_index = -1;
+ }
} // next field
- if (embed_values) {
+ if (0 != emb_val) {
if (reader.NodeType()==XML_READER_TYPE_TEXT) {
UNIVERSAL_CHARSTRING emb_ustr((const char*)reader.Value());
- embed_values->get_at(emb_idx)->set_value(&emb_ustr);
+ emb_val->embval_array->get_at(emb_val->embval_index)->set_value(&emb_ustr);
+ }
+ if (last_embval_index == emb_val->embval_index) {
+ ++emb_val->embval_index;
}
}
}
} // if use-order
- if (embed_values) {
- // Set the embed_values member to the correct number of strings
- int num_embedded = 0; // if usenil_attribute
- if (!usenil_attribute) {
- num_embedded = field_cnt - first_nonattr + 1;
- const int num_opt = optional_count();
- const int * optionals = get_optional_indexes();
- for (int opt_idx = 0; opt_idx < num_opt; ++opt_idx) {
- // skip optional attributes
- if (optionals[opt_idx] < start_at + num_attributes) continue;
- // reduce for each omitted member
- if (!get_at(optionals[opt_idx])->is_present()) --num_embedded;
- }
- }
- embed_values->set_size(num_embedded);
+ if (0 != emb_val) {
static const UNIVERSAL_CHARSTRING emptystring(0, (const char*)NULL);
- for (int j = 0; j < num_embedded; ++j) {
- if (!embed_values->get_at(j)->is_bound()) embed_values->get_at(j)->set_value(&emptystring);
+ for (int j = 0; j < emb_val->embval_index; ++j) {
+ if (!emb_val->embval_array->get_at(j)->is_bound()) {
+ emb_val->embval_array->get_at(j)->set_value(&emptystring);
+ }
}
+ delete emb_val;
} // if embed-values
} // if use-qname
case TTCN_EncDec::CT_XER: {
TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
unsigned XER_coding=va_arg(pvar, unsigned);
- XER_encode(*(p_td.xer),p_buf, XER_coding, 0);
+ XER_encode(*(p_td.xer),p_buf, XER_coding, 0, 0);
p_buf.put_c('\n');
break;}
case TTCN_EncDec::CT_JSON: {
for (int success=reader.Read(); success==1; success=reader.Read()) {
if (reader.NodeType() == XML_READER_TYPE_ELEMENT) break;
}
- XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL);
+ XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL, 0);
size_t bytes = reader.ByteConsumed();
p_buf.set_pos(bytes);
break;}
}
int Empty_Record_Type::XER_encode(const XERdescriptor_t& p_td,
- TTCN_Buffer& p_buf, unsigned int flavor, int indent) const
+ TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const
{
int encoded_length=(int)p_buf.get_len();
int indenting = !is_canonical(flavor);
}
int Empty_Record_Type::XER_decode(const XERdescriptor_t& p_td,
- XmlReaderWrap& reader, unsigned int flavor)
+ XmlReaderWrap& reader, unsigned int flavor, embed_values_dec_struct_t*)
{
int exer = is_exer(flavor);
bound_flag = true;
# cp asciiart/*.txt $(ETCDIR)/asciiart
mkdir -p $(ETCDIR)/scripts
cp scripts/*.py $(ETCDIR)/scripts
+ cp scripts/ttcn3_archive.pl $(BINDIR)
endif
--- /dev/null
+###############################################################################
+# Copyright (c) 2000-2014 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
+###############################################################################
+#!/usr/bin/perl
+###############################################################################
+# This script is intended to archive the project hierarchy from a TPD file structure
+###############################################################################
+use 5.010;
+use strict;
+use warnings;
+use Cwd;
+use File::Copy;
+
+my $ttcn3_dir = $ENV{'TTCN3_DIR'};
+my $bindir = $ttcn3_dir . "/bin";
+my $home = cwd();
+my @list = readFile();
+my $tpd = getTPDFileName(\@list);
+chomp ($tpd);
+if (-l $tpd) #get the path if it is a symlink
+{
+ $tpd = `readlink $tpd`;
+ chomp ($tpd);
+}
+my $root = getPathToRootDir(\@list); # get the workspace directory of the OS
+chomp ($root);
+chdir ($root) or die "cannot change: $!\n";
+my $cutstring = cwd; # this is string generated from the the absolut path to the workspace
+my $archiveDir = getArchiveDir(\@list); #directory to place the archive
+$archiveDir = $home . "/" . $archiveDir;
+chomp ($archiveDir);
+my $createDir = "mkdir -p " . $archiveDir;
+my $res = system($createDir);
+my $backupFileName = createBackupFileName();
+my $backupfile = $archiveDir . "/" . $backupFileName;
+if ($res != 0) { die (" creating directory " . $archiveDir ." failed\n"); }
+my $archive = $bindir . "/" . "ttcn3_makefilegen" ." -V -P " . $cutstring . " -t " . $tpd . " | xargs tar cfz ". $archiveDir . "/" . $backupFileName . " 2> /dev/null";
+system($archive); #running it
+if (-e $backupfile) { print ("archiving succeeded\n"); }
+else { print ("archiving failed\n"); }
+chdir ($home) or die "cannot change: $!\n";
+############################################################
+sub readFile
+{
+ my $makefile = "Makefile";
+ open ( FILE, "<", $makefile ) or die ( "failed to open file: $home\/$makefile\n" );
+ my @lines = <FILE>;
+ close FILE;
+ return @lines;
+}
+############################################################
+sub getPathToRootDir #get the relative path to OS workspace
+{
+ my @list = @{$_[0]};
+ my $search = qr/^ROOT_DIR =/s;
+ my $offset = 0;
+ my $line;
+ for my $i ( 0 .. $#list )
+ {
+ if ( $list[$i] =~ $search )
+ {
+ $line = $list[$i];
+ my $dot = '.';
+ $offset = index($list[$i], $dot);
+ last;
+ }
+ }
+ if ($offset == 0) { die ( "no ROOT_DIR variable was found in the Makefile\n" ); }
+ my $path = substr $line, $offset;
+ return $path;
+}
+############################################################
+sub getTPDFileName # TPD filename what the Makefile is created from
+{
+ my @list = @{$_[0]};
+ my $search = qr/^TPD =/s;
+ my $offset = 0;
+ my $line;
+ for my $i ( 0 .. $#list )
+ {
+ if ( $list[$i] =~ $search )
+ {
+ $line = $list[$i];
+ my $assign = '=';
+ $offset = index($list[$i], $assign);
+ last;
+ }
+ }
+ if ($offset == 0) { die ( "no TPD variable was found in the Makefile\n" ); }
+ my $file = substr $line, $offset + 1;
+ $file =~ s/^\s+|\s+$//; # remove heading and traling whitespaces
+ return $file;
+}
+############################################################
+sub getArchiveDir # the name of the archive directory
+{
+ my @list = @{$_[0]};
+ my $search = qr/^ARCHIVE_DIR =/s;
+ my $offset = 0;
+ my $line;
+ for my $i ( 0 .. $#list )
+ {
+ if ( $list[$i] =~ $search )
+ {
+ $line = $list[$i];
+ my $assign = '=';
+ $offset = index($list[$i], $assign);
+ last;
+ }
+ }
+ if ($offset == 0) { die ( "no ARCHIVE_DIR variable was found in the Makefile\n" ); }
+ my $dir = substr $line, $offset + 1;
+ $dir =~ s/^\s+|\s+$//; # remove heading and trailing whitespaces
+ return $dir;
+}
+############################################################
+sub getExecutableName # the name of the target executable
+{
+ my @list = @{$_[0]};
+ my $search = qr/^EXECUTABLE =/s;
+ my $offset = 0;
+ my $line;
+ for my $i ( 0 .. $#list )
+ {
+ if ( $list[$i] =~ $search )
+ {
+ $line = $list[$i];
+ my $assign = '=';
+ $offset = index($list[$i], $assign);
+ last;
+ }
+ }
+ if ($offset == 0) { die ( "no EXCUTABLE variable was found in the Makefile\n" ); }
+ my $exec = substr $line, $offset + 1;
+ $exec =~ s/^\s+|\s+$//; # remove heading and trailing whitespaces
+ return $exec;
+}
+############################################################
+sub createBackupFileName
+{
+ my $backupFile = getExecutableName(\@list);
+ my $dot = '.';
+ my $result = index($backupFile, $dot);
+ if ($result > -1)
+ {
+ $backupFile = substr $backupFile, 0, $result;
+ }
+ chomp ($backupFile);
+ my $date = `date '+%y%m%d-%H%M'`;
+ chomp ($date);
+ my $baseName = $backupFile . "-" . $date . ".tgz";
+ chomp ($baseName);
+ return $baseName;
+}
+############################################################
\ No newline at end of file
</xs:restriction>
</xs:simpleType>
</xs:element>
- <xs:element name="rerquiredConfiguration" minOccurs="1" maxOccurs="1">
- <xs:simpleType>
- <xs:restriction base="xs:normalizedString">
- <xs:minLength value="1" />
- </xs:restriction>
- </xs:simpleType>
- </xs:element>
+ <xs:choice>
+ <xs:element name="requiredConfiguration" minOccurs="1" maxOccurs="1">
+ <xs:simpleType>
+ <xs:restriction base="xs:normalizedString">
+ <xs:minLength value="1" />
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+ <xs:element name="rerquiredConfiguration" minOccurs="1" maxOccurs="1">
+ <xs:simpleType>
+ <xs:restriction base="xs:normalizedString">
+ <xs:minLength value="1" />
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+ </xs:choice>
</xs:sequence>
</xs:complexType>
<xs:complexType name="TopLevelProjectType">
<!--
This is an extra indirection level. It adds the "version" attribute to
- ProjecType and the optional element "PackedReferencedProjects"
+ ProjectType and the optional element "PackedReferencedProjects"
-->
<xs:complexContent>
<xs:extension base="ProjectType">
error: at or before token `permutation': syntax error, unexpected PermutationKeyword
<END_RESULT>
-<END_TC>
-:exmp
-*---------------------------------------------------------------------*
-:h3. Component mapping: invalid ports
-.*---------------------------------------------------------------------*
-:xmp tab=0.
-
-<TC -Component mapping: invalid port >
-
-<COMPILE>
-
-<MODULE TTCN test test.ttcn >
-module test {
-
-type port P message {
- inout charstring;
-} with { extension "internal" }
-
-type component MTCType
-{
- port P MyPCO_PT1;
-}
-
-function akarmi () runs on MTCType {
-map(mtc:MyPCO_PT, system:MyPCO_PT2);
-
-}
-
-testcase tc_akarmi () runs on MTCType {
-map(mtc:MyPCO_PT, system:MyPCO_PT2);
-
-}
-
-}
-<END_MODULE>
-
-<RESULT COUNT 2>
-Component type `@test.MTCType' does not have port with name `MyPCO_PT'
-<END_RESULT>
-<RESULT COUNT 1>
-Component type `@test.MTCType' does not have port with name `MyPCO_PT2'
-<END_RESULT>
-
<END_TC>
:exmp
<END_TC>
:exmp.
+*-----------------------------------------------------------*
+:h3.Adhoc:: HT23335: Type Infinity is not a valid value for type `integer' which as subtype (-1..65535)
+.*-----------------------------------------------------------*
+:xmp tab=0.
+<TC - HT23335: Type Infinity is not a valid value for type `integer' which as subtype (-1..65535)>
+
+<COMPILE>
+<VERDICT_LEAF FAIL>
+<MODULE TTCN Temp Temp.ttcn>
+module Temp {
+const integer limes_i := 65535;
+const float limes_f2 := 65535.0;
+const float limes_f1 := -1.0;
+type record MyRecI {
+ integer inum (-1..limes_i)
+};
+type record MyRecF {
+ float fnum (limes_f1..limes_f2)
+};
+
+template MyRecI t1 := { inum := (0..infinity) };
+template MyRecF t2 := { fnum := (-infinity..0.0) };
+
+}
+<END_MODULE>
+<RESULT IF_FAIL COUNT 2>
+(?im)\Infinity is not a valid value for type\b
+<END_RESULT>
+<END_TC>
+:exmp.
+
:etext.
%x SC_blockcomment SC_DEFINE SC_CSTRING SC_ORDERED_INCLUDE
%s SC_MODULE_PARAMETERS SC_LOGGING SC_TESTPORT_PARAMETERS SC_EXECUTE SC_GROUPS
-%s SC_COMPONENTS SC_EXTERNAL_COMMANDS SC_MAIN_CONTROLLER SC_INCLUDE
+%s SC_COMPONENTS SC_EXTERNAL_COMMANDS SC_MAIN_CONTROLLER SC_INCLUDE SC_PROFILER
%%
int comment_caller = INITIAL;
}
}
+<*>"["{WS}PROFILER{WS}"]" {
+ if (YY_START!=SC_blockcomment) {
+ BEGIN(SC_PROFILER);
+ RETURN(ProfilerKeyword);
+ }
+}
+
<*>"["{WS}TESTPORT_PARAMETERS{WS}"]" {
if (YY_START!=SC_blockcomment) {
BEGIN(SC_TESTPORT_PARAMETERS);
infinity RETURN(InfinityKeyword);
}
-<SC_MODULE_PARAMETERS,SC_LOGGING>
+<SC_MODULE_PARAMETERS,SC_LOGGING,SC_PROFILER>
{
true |
false RETURN(BooleanValue);
[Dd]elete RETURN(Delete);
}
+<SC_PROFILER>
+{
+[Dd]isable[Pp]rofiler return DisableProfilerKeyword;
+[Dd]isable[Cc]overage return DisableCoverageKeyword;
+[Dd]ata[Bb]ase[Ff]ile return DatabaseFileKeyword;
+[Aa]ggregate[Dd]ata return AggregateDataKeyword;
+[Ss]tatistics[Ff]ile return StatisticsFileKeyword;
+[Dd]isable[Ss]tatistics return DisableStatisticsKeyword;
+}
+
<SC_EXECUTE>control RETURN(ControlKeyword);
<SC_EXTERNAL_COMMANDS>
char *str_val;
BIGNUM *int_val;
double float_val;
+ boolean bool_val;
cf_timestamp_format ts_val;
execute_list_item execute_item_val;
}
%token ModuleParametersKeyword
%token LoggingKeyword
+%token ProfilerKeyword
%token TestportParametersKeyword
%token ExecuteKeyword
%token ExternalCommandsKeyword
%token Re_try /* Retry clashes with an enum in Qt */
%token Delete
+%token DisableProfilerKeyword "DisableProfiler"
+%token DisableCoverageKeyword "DisableCoverage"
+%token DatabaseFileKeyword "DatabaseFile"
+%token AggregateDataKeyword "AggregateData"
+%token StatisticsFileKeyword "StatisticsFile"
+%token DisableStatisticsKeyword "DisableStatistics"
+
%type <int_val> IntegerValue
%type <float_val> FloatValue KillTimerValue
%type <str_val> HostName StringValue LogFileName
Section:
ModuleParametersSection
| LoggingSection
+ | ProfilerSection
| TestportParametersSection
| ExecuteSection
| ExternalCommandsSection
| Detailed
;
+/*********************** [PROFILER] ********************************/
+
+ProfilerSection:
+ ProfilerKeyword ProfilerSettings
+;
+
+ProfilerSettings:
+ /* empty */
+| ProfilerSettings ProfilerSetting optSemiColon
+;
+
+ProfilerSetting:
+ DisableProfilerSetting
+| DisableCoverageSetting
+| DatabaseFileSetting
+| AggregateDataSetting
+| StatisticsFileSetting
+| DisableStatisticsSetting
+;
+
+DisableProfilerSetting:
+ DisableProfilerKeyword AssignmentChar BooleanValue
+;
+
+DisableCoverageSetting:
+ DisableCoverageKeyword AssignmentChar BooleanValue
+;
+
+DatabaseFileSetting:
+ DatabaseFileKeyword AssignmentChar StringValue { Free($3); }
+;
+
+AggregateDataSetting:
+ AggregateDataKeyword AssignmentChar BooleanValue
+;
+
+StatisticsFileSetting:
+ StatisticsFileKeyword AssignmentChar StringValue { Free($3); }
+;
+
+DisableStatisticsSetting:
+ DisableStatisticsKeyword AssignmentChar BooleanValue
+;
+
/******************* [TESTPORT_PARAMETERS] section *******************/
TestportParametersSection:
CHECK_DECODE(exer_dec_emb_any, str_emb_any, EmbedAnyElem, c_emb_any);
}
+// EMBED-VALUES with untagged array
+// the values are also embedded between the array elements, not just the fields of the record
+type record Inner {
+ integer num,
+ charstring str
+}
+
+type record length (1..infinity) of Inner RoInner;
+
+type record Outer {
+ record of universal charstring embed_values,
+ integer attr,
+ octetstring bytes,
+ RoInner stuff
+} with {
+ variant "embedValues";
+ variant(attr) "attribute";
+ variant(bytes) "name as 'Bytes'";
+ variant(stuff) "untagged";
+}
+
+DECLARE_EXER_ENCODERS(Outer, emb_outer);
+
+const Outer c_emb_array := {
+ embed_values := { "one", "two", "three", "four", "five", "six" },
+ attr := 48,
+ bytes := 'DEADBEEF'O,
+ stuff := { { 3, "abc" }, { 4, "def" }, { -6, "red" }, { 118, "blue" } }
+}
+
+const Outer c_emb_array_w_holes := {
+ embed_values := { "one", "", "three", "", "five" },
+ attr := 48,
+ bytes := 'DEADBEEF'O,
+ stuff := { { 3, "abc" }, { 4, "def" }, { -6, "red" }, { 118, "blue" } }
+}
+
+const universal charstring str_emb_array :=
+"<Outer attr='48'>one" &
+"<Bytes>DEADBEEF</Bytes>two" &
+"<Inner><num>3</num><str>abc</str></Inner>three" &
+"<Inner><num>4</num><str>def</str></Inner>four" &
+"<Inner><num>-6</num><str>red</str></Inner>five" &
+"<Inner><num>118</num><str>blue</str></Inner>six</Outer>\n";
+
+const universal charstring str_emb_array_w_holes :=
+"<Outer attr='48'>one" &
+"<Bytes>DEADBEEF</Bytes>" &
+"<Inner><num>3</num><str>abc</str></Inner>three" &
+"<Inner><num>4</num><str>def</str></Inner>" &
+"<Inner><num>-6</num><str>red</str></Inner>five" &
+"<Inner><num>118</num><str>blue</str></Inner></Outer>\n";
+
+testcase encode_emb_array() runs on EMB
+{
+ CHECK_METHOD(exer_enc_emb_outer, c_emb_array, str_emb_array);
+ CHECK_METHOD(exer_enc_emb_outer, c_emb_array_w_holes, str_emb_array_w_holes);
+}
+
+testcase decode_emb_array() runs on EMB
+{
+ CHECK_DECODE(exer_dec_emb_outer, str_emb_array, Outer, c_emb_array);
+ CHECK_DECODE(exer_dec_emb_outer, str_emb_array_w_holes, Outer, c_emb_array_w_holes);
+}
+
control {
execute(encode_emb());
execute(decode_emb());
execute(decode_emb_all());
execute(encode_emb_any());
execute(decode_emb_any());
+ //execute(encode_emb_array()); - this functionality was temporarily removed in RT1
+ //execute(decode_emb_array());
}
}
XDIRS := $(wildcard $(SHADOWED)) xsdConverter \
HM60295 HN15589 HQ30408 HR49727 $(RT2_ONLY) \
-XmlWorkflow
+XmlWorkflow tpdValidTest
# List of fake targets:
.PHONY: all dep clean run $(XDIRS) $(addsuffix /, $(XDIRS)) profile
--- /dev/null
+###############################################################################
+# Copyright (c) 2000-2014 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
+###############################################################################
+
+dep clean distclean:
+
+all run:
+ ./tpdValidTest.sh >&2
--- /dev/null
+#!/bin/bash
+###############################################################################
+# Copyright (c) 2000-2014 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
+###############################################################################
+
+TPD_DIR="$WORKSPACE/titan_eclipse/Semantic_Analizer_Tests/tpdTest/"
+XSD_DIR="$TTCN3_DIR/etc/xsd/"
+XSD="TPD.xsd"
+
+find $TPD_DIR -type f -name *.tpd | xargs -I {} xmllint --noout --schema $XSD_DIR/$XSD {}
+
+if [ $? -ne 0 ]; then
+ echo "Not every .tpd is valid! Overall verdict: fail"
+ exit 1
+else
+ echo "Every .tpd is valid! Overall verdict: pass"
+ exit 0
+fi
--- /dev/null
+###############################################################################
+# Copyright (c) 2000-2015 Ericsson Telecom AB
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+###############################################################################
+TOPDIR := ../..
+include $(TOPDIR)/Makefile.regression
+
+.PHONY: all clean dep
+
+TTCN3_LIB = ttcn3$(RT2_SUFFIX)$(DYNAMIC_SUFFIX)
+
+EXTRA_COMPILER_FLAGS = -p -V 63
+
+TTCN3_MODULES = Test1.ttcn Test2.ttcn
+
+GENERATED_SOURCES = $(TTCN3_MODULES:.ttcn=.cc)
+GENERATED_HEADERS = $(GENERATED_SOURCES:.cc=.hh)
+ifdef CODE_SPLIT
+GENERATED_SOURCES := $(foreach file, $(GENERATED_SOURCES:.cc=), $(addprefix $(file), .cc _seq.cc _set.cc _seqof.cc _setof.cc _union.cc))
+endif
+
+OBJECTS = $(GENERATED_SOURCES:.cc=.o)
+
+TARGET = HT48786$(EXESUFFIX)
+
+all: $(TARGET)
+
+$(TARGET): $(GENERATED_SOURCES) $(USER_SOURCES)
+ $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $@ $^ -L$(TTCN3_DIR)/lib -l$(TTCN3_LIB) \
+ -L$(OPENSSL_DIR)/lib -lcrypto $($(PLATFORM)_LIBS)
+
+# an extra compilation is tested (with only parsing and maximum verbosity level)
+$(GENERATED_SOURCES) $(GENERATED_HEADERS): $(TTCN3_MODULES)
+ $(TTCN3_COMPILER) $(EXTRA_COMPILER_FLAGS) $(COMPILER_FLAGS) $^
+ $(TTCN3_COMPILER) $(COMPILER_FLAGS) $^
+
+clean distclean:
+ $(RM) $(TARGET) $(OBJECTS) $(GENERATED_HEADERS) \
+ $(GENERATED_SOURCES) compile *.log
+
+dep: $(GENERATED_SOURCES)
+ makedepend $(CPPFLAGS) $(GENERATED_SOURCES)
--- /dev/null
+///////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2000-2015 Ericsson Telecom AB
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// which accompanies this distribution, and is available at
+// http://www.eclipse.org/legal/epl-v10.html
+///////////////////////////////////////////////////////////////////////////////
+module Test1
+{
+
+type component EMPTY_CT
+{
+}
+
+type record Union
+{
+ record of integer record_of_integer,
+ charstring string
+};
+
+testcase TC_1() runs on EMPTY_CT
+{
+ var boolean b := false;
+ var Union u1 := {
+ record_of_integer := {
+ str2int("2"),
+ str2int("3")
+ }
+ };
+}
+
+control {
+ execute(TC_1());
+}
+
+}
--- /dev/null
+///////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2000-2015 Ericsson Telecom AB
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// which accompanies this distribution, and is available at
+// http://www.eclipse.org/legal/epl-v10.html
+///////////////////////////////////////////////////////////////////////////////
+
+module Test2 {
+
+type record of integer Record1;
+type record of Record1 Record2;
+
+function f1() {
+ var Record2 r1, r2;
+ r1 := {{1, 2}};
+ r2 := valueof(r1);
+ r2 := valueof({{1, 2}});
+}
+
+}
centralstorage mfgen-tpd \
openType optionalAssignCompare portConstructor \
isbound namedActualParameters assignmentNotation \
- attribQualif
+ attribQualif HT48786
all dep clean distclean:
for dir in $(CODIRS); do $(MAKE) -C $$dir $@ || exit; done
-t ../HelloTpd.tpd -b notexisting 2>&1 | tee ../output
CheckHelloTpd: BuildHelloTpd
- if [ `grep -c "error: The active build configuration named 'notexisting' does not exist" ./HelloTpd/output` -ne 1 ] \
- || [ `grep -c "error: Failed to process ../HelloTpd.tpd" ./HelloTpd/output` -ne 1 ]; \
+ if [ `grep -c "error: The active build configuration named 'notexisting' does not exist" ./HelloTpd/output` -ne 1 ]; \
then exit 1; fi
clean:
-L a.ttcn && ${MAKEPROG}
CheckLibraryL: BuildLibraryL
- if [ ! -f ./bin/a.a ]; then exit 1; fi
+ if [ ! -f ./bin/liba.a ]; then exit 1; fi
if [ -f ./bin/a ]; then exit 1; fi
# ttcn3_makefilegen -L; make executable
-L a.ttcn && ${MAKEPROG} executable
CheckLibrary3L: BuildLibrary3L
- if [ -f ./bin3/a.a ]; then exit 1; fi
+ if [ -f ./bin3/liba.a ]; then exit 1; fi
if [ ! -f ./bin3/a ]; then exit 1; fi
# ttcn3_makefilegen -L; make library
-L a.ttcn && ${MAKEPROG} library
CheckLibrary2L: BuildLibrary2L
- if [ ! -f ./bin2/a.a ]; then exit 1; fi
+ if [ ! -f ./bin2/liba.a ]; then exit 1; fi
if [ -f ./bin2/a ]; then exit 1; fi
# ttcn3_makefilegen -L; make run
-L a.ttcn && ${MAKEPROG} all
CheckLibrary4L: BuildLibrary4L
- if [ ! -f ./bin4/a.a ]; then exit 1; fi
+ if [ ! -f ./bin4/liba.a ]; then exit 1; fi
if [ -f ./bin4/a ]; then exit 1; fi
#### Without -L ####
a.ttcn && ${MAKEPROG}
CheckLibrary: BuildLibrary
- if [ -f ./bin/a.a ]; then exit 1; fi
+ if [ -f ./bin/liba.a ]; then exit 1; fi
if [ ! -f ./bin/a ]; then exit 1; fi
# ttcn3_makefilegen; make executable
a.ttcn && ${MAKEPROG} executable
CheckLibrary3: BuildLibrary3
- if [ -f ./bin3/a.a ]; then exit 1; fi
+ if [ -f ./bin3/liba.a ]; then exit 1; fi
if [ ! -f ./bin3/a ]; then exit 1; fi
# ttcn3_makefilegen; make library
a.ttcn && ${MAKEPROG} library
CheckLibrary2: BuildLibrary2
- if [ ! -f ./bin2/a.a ]; then exit 1; fi
+ if [ ! -f ./bin2/liba.a ]; then exit 1; fi
if [ -f ./bin2/a ]; then exit 1; fi
# ttcn3_makefilegen; make all
a.ttcn && ${MAKEPROG} all
CheckLibrary4: BuildLibrary4
- if [ -f ./bin4/a.a ]; then exit 1; fi
+ if [ -f ./bin4/liba.a ]; then exit 1; fi
if [ ! -f ./bin4/a ]; then exit 1; fi
###############################
a.ttcn && ${MAKEPROG}
Check_dynamic: Build_dynamic
- if [ ! -f ./bin_dynamic/a_lib.so ]; then exit 1; fi
+ if [ ! -f ./bin_dynamic/liba.so ]; then exit 1; fi
if [ -f ./bin_dynamic/a ]; then exit 1; fi
# ttcn3_makefilegen -L -l; make library
a.ttcn && ${MAKEPROG} library
Check_dynamic2: Build_dynamic2
- if [ ! -f ./bin_dynamic2/a_lib.so ]; then exit 1; fi
+ if [ ! -f ./bin_dynamic2/liba.so ]; then exit 1; fi
if [ -f ./bin_dynamic2/a ]; then exit 1; fi
# ttcn3_makefilegen -L -l; make executable
a.ttcn && ${MAKEPROG} executable
Check_dynamic3: Build_dynamic3
- if [ ! -f ./bin_dynamic3/a_lib.so ]; then exit 1; fi
+ if [ ! -f ./bin_dynamic3/liba.so ]; then exit 1; fi
if [ -f ./bin_dynamic3/a.so ]; then exit 1; fi
if [ ! -f ./bin_dynamic3/a ]; then exit 1; fi
a.ttcn && ${MAKEPROG}
Check_dynamic4: Build_dynamic4
- if [ -f ./bin_dynamic4/a_lib.so ]; then exit 1; fi
+ if [ -f ./bin_dynamic4/liba.so ]; then exit 1; fi
if [ ! -f ./bin_dynamic4/a ]; then exit 1; fi
# ttcn3_makefilegen -l; make library
a.ttcn && ${MAKEPROG} library
Check_dynamic5: Build_dynamic5
- if [ ! -f ./bin_dynamic5/a_lib.so ]; then exit 1; fi
+ if [ ! -f ./bin_dynamic5/liba.so ]; then exit 1; fi
if [ -f ./bin_dynamic5/a ]; then exit 1; fi
# ttcn3_makefilegen -l; make executable
a.ttcn && ${MAKEPROG} executable
Check_dynamic6: Build_dynamic6
- if [ -f ./bin_dynamic6/a_lib.so ]; then exit 1; fi
+ if [ -f ./bin_dynamic6/liba.so ]; then exit 1; fi
if [ ! -f ./bin_dynamic6/a ]; then exit 1; fi
b.ttcn ../central_storage/central.ttcn && ${MAKEPROG}
Check_dynamic_central: Build_dynamic_central
- if [ ! -f ./bin_central/b_lib.so ]; then exit 1; fi
+ if [ ! -f ./bin_central/libb.so ]; then exit 1; fi
if [ -f ./bin_central/b ]; then exit 1; fi
# ttcn3_makefilegen -c -l; make
CheckHelloTpd: BuildHelloTpd
if [ -f HelloTpd/bin/HelloTpd_test.exe ]; then exit 1; fi
- if [ ! -f HelloTpd/bin/HelloTpd_test.a ]; then exit 1; fi
+ if [ ! -f HelloTpd/bin/libHelloTpd_test.a ]; then exit 1; fi
# the default target is executable in the tpd file
# check if the command line option overrides the one defined in the tpd
CheckHelloTpd2: BuildHelloTpd2
if [ -f HelloTpd2/bin/HelloTpd_test.exe ]; then exit 1; fi
- if [ ! -f HelloTpd2/bin/HelloTpd_test.a ]; then exit 1; fi
+ if [ ! -f HelloTpd2/bin/libHelloTpd_test.a ]; then exit 1; fi
clean:
-rm -rf bin*
external function f_enc_stuff(in Stuff x) return octetstring
with { extension "prototype(convert) encode(JSON)" }
+external function f_enc_hpt(in HasPardType x) return octetstring
+ with { extension "prototype(convert) encode(JSON)" }
+
// for ASN.1 types
external function f_enc_seqofint(in SeqOfInt x) return octetstring
with { extension "prototype(convert) encode(JSON)" }
external function f_enc_complex(in ComplexSet x) return octetstring
with { extension "prototype(convert) encode(JSON)" }
+
+external function f_enc_obj(in Object x) return octetstring
+ with { extension "prototype(convert) encode(JSON)" }
+
+external function f_enc_null(in HasNull x) return octetstring
+ with { extension "prototype(convert) encode(JSON)" }
//=================== Decoders =====================================
external function f_dec_def(in octetstring x) return RecDef
with { extension "prototype(convert) decode(JSON)" }
+external function f_dec_hpt(in octetstring x) return HasPardType
+ with { extension "prototype(convert) decode(JSON)" }
+
// for ASN.1 types
external function f_dec_seqofint(in octetstring x) return SeqOfInt
with { extension "prototype(convert) decode(JSON)" }
external function f_dec_complex(in octetstring x) return ComplexSet
with { extension "prototype(convert) decode(JSON)" }
+
+external function f_dec_obj(in octetstring x) return Object
+ with { extension "prototype(convert) decode(JSON)" }
+
+external function f_dec_null(in octetstring x) return HasNull
+ with { extension "prototype(convert) decode(JSON)" }
//============== Internal Functions ====================
-- Type definitions --
----------------------
+-- Sequence of
SeqOfInt ::= SEQUENCE OF INTEGER
+-- Sequence
SeqProduct ::= SEQUENCE {
name UniversalString,
price REAL,
available BOOLEAN
}
+-- Choice
Number ::= CHOICE {
decimal INTEGER,
binary BIT STRING,
hexadecimal OCTET STRING
}
+-- Choice containing all string types
AnyString ::= CHOICE {
generalstr GeneralString,
numericstr NumericString,
visiblestr VisibleString
}
+-- Sequence of strings
ManyStrings ::= SEQUENCE OF AnyString
+-- Set containing all of the above
ComplexSet ::= SET {
product SeqProduct,
numbers SET OF Number,
strings ManyStrings
}
+Priority ::= ENUMERATED { low, normal, medium, high, urgent }
+
+Conditionality ::= ENUMERATED { optional, conditional, mandatory }
+
+ProtocolElem-ID ::= INTEGER (0..65535)
+
+-- IOC
+PROTOCOL-ELEMS ::= CLASS
+{
+ &id ProtocolElem-ID UNIQUE,
+ &priority Priority,
+ &Value,
+ &conditionality Conditionality
+}
+WITH SYNTAX
+{
+ ID &id
+ PRIORITY &priority
+ TYPE &Value
+ CONDITIONALITY &conditionality
+}
+
+-- parameterized type
+ProtocolElem-Field {PROTOCOL-ELEMS : ElemsSetParam} ::= SEQUENCE
+{
+ id PROTOCOL-ELEMS.&id ({ElemsSetParam}),
+ priority PROTOCOL-ELEMS.&priority ({ElemsSetParam}{@id}),
+ val PROTOCOL-ELEMS.&Value ({ElemsSetParam}{@id})
+}
+
+
+-- Information objects
+ies-Set-Element-1 PROTOCOL-ELEMS ::=
+{
+ ID 0
+ PRIORITY low
+ TYPE INTEGER
+ CONDITIONALITY mandatory
+}
+
+ies-Set-Element-2 PROTOCOL-ELEMS ::=
+{
+ ID 1
+ PRIORITY high
+ TYPE IA5String
+ CONDITIONALITY optional
+}
+-- Information Object Set
+Elems-Set PROTOCOL-ELEMS ::= { ies-Set-Element-1 | ies-Set-Element-2 }
+
+
+-- instantiation
+ProtocolElem-Field1 ::= ProtocolElem-Field {{Elems-Set}}
+
+ProtocolElem-Field2 ::= ProtocolElem-Field {{ies-Set-Element-2 }}
+
+-- Choice containing NULL
+Price ::= CHOICE
+{
+ value REAL,
+ invaluable NULL
+}
+
+-- Sequence containing an object identifier and an ANY type
+Object ::= SEQUENCE
+{
+ id OBJECT IDENTIFIER,
+ data ANY
+}
+
+-- Sequence containing an optional NULL field
+HasNull ::= SEQUENCE
+{
+ theNull NULL OPTIONAL
+}
+
+
-- Values and their encoding --
-------------------------------
c-set-val-str VisibleString ::= "{""product"":{""name"":""Headset"",""price"":28.500000,""available"":false},""numbers"":[{""hexadecimal"":""16678D""},{""decimal"":12}],""strings"":[{""printablestr"":""first""},{""numericstr"":""2""}]}"
+-- Object
+c-obj Object ::= {
+ id { joint-iso-itu-t remote-operations(4) informationObjects(5) version1(0) },
+ data 'DEADBEEF'H
+}
+
+c-obj-str VisibleString ::= "{""id"":""2.4.5.0"",""data"":""DEADBEEF""}"
+
+-- HasNull
+c-null HasNull ::= { theNull NULL }
+c-not-null HasNull ::= {}
+
+c-null-str VisibleString ::= "{""theNull"":null}"
+c-not-null-str VisibleString ::= "{}"
+
END
f_bool2verdict(match(f_dec_complex(os), c_set_val));
}
+// ====== Special ASN.1 types ======
+// record containing an open type and a possible NULL value
+testcase tc_asn_open_type_and_null() runs on MTC {
+ var HasPardType x := {
+ pard := {
+ id := 0,
+ priority := low,
+ val := { iNTEGER := 19 }
+ },
+ buul := true,
+ price := { invaluable := NULL }
+ };
+ var octetstring os := char2oct("{\"pard\":{\"id\":0,\"priority\":\"low\",\"val\":{\"iNTEGER\":19}},\"buul\":true,\"price\":{\"invaluable\":null}}");
+ f_check_encoding(encoded := f_enc_hpt(x), expected := os);
+ f_bool2verdict(match(f_dec_hpt(os), x));
+}
+
+// SEQUENCE containing an object identifier and an ANY type
+testcase tc_asn_objid_and_any() runs on MTC {
+ var octetstring os := char2oct(c_obj_str);
+ f_check_encoding(encoded:= f_enc_obj(c_obj), expected := os);
+ f_bool2verdict(match(f_dec_obj(os), c_obj));
+}
+
+testcase tc_asn_optional_null() runs on MTC {
+ var octetstring os := char2oct(c_null_str);
+ f_check_encoding(encoded:= f_enc_null(c_null), expected := os);
+ f_bool2verdict(match(f_dec_null(os), c_null));
+ os := char2oct(c_not_null_str);
+ f_check_encoding(encoded:= f_enc_null(c_not_null), expected := os);
+ f_bool2verdict(match(f_dec_null(os), c_not_null));
+}
//=========================================================================
// Control
execute(tc_asn_choice());
execute(tc_asn_strings());
execute(tc_asn_complex());
+
+ execute(tc_asn_open_type_and_null());
+ execute(tc_asn_objid_and_any());
+ execute(tc_asn_optional_null());
}
******************************************************************************/
module Types {
+import from JsonData all;
+
const integer c_imported_i :=11;
type component MTC {}
variant(b) "JSON:default(false)";
}
+type record HasPardType {
+ ProtocolElem_Field1 pard,
+ boolean buul,
+ Price price
+}
} with {
encode "JSON";
TTCN3_LIB = ttcn3$(RT2_SUFFIX)$(DYNAMIC_SUFFIX)
-TTCN3_MODULES = TrecofOper.ttcn TrecofParamRef.ttcn
+TTCN3_MODULES = TrecofOper.ttcn
+ifdef RT2
+TTCN3_MODULES += TrecofParamRef.ttcn
ASN1_MODULES = BerType.asn
+CFG_FILE = config_rt2.cfg
+else
+ASN1_MODULES =
+CFG_FILE = config.cfg
+endif
GENERATED_SOURCES = $(TTCN3_MODULES:.ttcn=.cc) $(ASN1_MODULES:.asn=.cc)
GENERATED_HEADERS = $(GENERATED_SOURCES:.cc=.hh)
dep: $(GENERATED_SOURCES)
makedepend $(CPPFLAGS) $(GENERATED_SOURCES)
-run: $(TARGET) config.cfg
+run: $(TARGET) $(CFG_FILE)
./$^
.NOTPARALLEL:
ConsoleMask := TTCN_WARNING | TTCN_ERROR | TTCN_TESTCASE | TTCN_STATISTICS
[EXECUTE]
TrecofOper
-TrecofParamRef
--- /dev/null
+###############################################################################
+# Copyright (c) 2000-2015 Ericsson Telecom AB
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+###############################################################################
+[MODULE_PARAMETERS]
+[LOGGING]
+Logfile := "recofOper.log"
+FileMask := LOG_ALL
+ConsoleMask := TTCN_WARNING | TTCN_ERROR | TTCN_TESTCASE | TTCN_STATISTICS
+[EXECUTE]
+TrecofOper
+TrecofParamRef
--- /dev/null
+/******************************************************************************
+ * Copyright (c) 2000-2015 Ericsson Telecom AB
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ ******************************************************************************/
+
+// This module compares two JSON schemas generated by the TITAN compiler
+module CompareSchemas {
+
+//////////////////////////////////////
+// JSON schema container data types //
+//////////////////////////////////////
+
+// top level object
+type record JsonSchema {
+ DefSchemas defs,
+ RefSchemas refs
+}
+
+// definitions section:
+type set of DefSchema DefSchemas;
+
+type record DefSchema {
+ charstring moduleName,
+ charstring typeName,
+ TypeSchema schema
+}
+
+type set of TypeSchemaElement TypeSchema;
+
+type record TypeSchemaElement {
+ ElemKey key,
+ ElemValue val
+}
+
+type enumerated ElemKey {
+ Ref, Type, SubType, Pattern, OriginalName, UnusedAlias, MinItems, MaxItems, // strVal
+ AdditionalProperties, OmitAsNull, // boolVal
+ Default, // strVal or boolVal
+ Enum, NumericValues, Required, FieldOrder, // strArrayVal
+ Items, // typeVal
+ AnyOf, // typeArrayVal
+ Properties // fieldSetVal
+}
+
+type union ElemValue {
+ charstring strVal,
+ boolean boolVal,
+ record of charstring strArrayVal,
+ TypeSchema typeVal,
+ record of TypeSchema typeArrayVal,
+ set of FieldValue fieldSetVal
+}
+
+type record FieldValue {
+ charstring fieldName,
+ TypeSchema schema
+}
+
+// references/functions section:
+type set of RefSchema RefSchemas;
+
+type record RefSchema {
+ charstring ref,
+ EncDecData enc optional,
+ EncDecData dec optional
+}
+
+type record EncDecData {
+ PrototypeData prototype,
+ ErrorBehaviorData eb optional,
+ charstring printing optional
+}
+
+type record of charstring PrototypeData;
+
+type record of ErrorBehaviorElem ErrorBehaviorData;
+
+type record ErrorBehaviorElem {
+ charstring errorType,
+ charstring errorBehavior
+}
+
+//////////////////////////////////
+// Import and compare functions //
+//////////////////////////////////
+
+// Imports a JSON schema from the given file and stores it in the specified container.
+// Throws a Dynamic Testcase Error if the file cannot be read or does not have the correct format.
+// The resulting JsonSchema should not have any unbound fields.
+external function f_ext_import_schema(in charstring file, out JsonSchema schema);
+
+// Compares the two schemas found in the files specified by the parameters.
+// Returns true if they are equal.
+function f_compare_schemas(in charstring schema_file1, in charstring schema_file2) return boolean
+{
+ // read the schemas from the files
+ var JsonSchema schema1;
+ f_ext_import_schema(schema_file1, schema1);
+ var JsonSchema schema2;
+ f_ext_import_schema(schema_file2, schema2);
+
+ // log both schemas (good luck digging through these...)
+ //log("Generated (", schema_file1, "): ", schema1);
+ //log("Expected (", schema_file2, "): ", schema2);
+
+ // set the verdict depending on their equality
+ if (match(schema1, schema2)) {
+ return true;
+ }
+ log(match(schema1, schema2));
+ return false;
+}
+
+}
"General_Types" : {
"BIT1" : {
"type" : "string",
+ "subType" : "bitstring",
"pattern" : "^[01]*$"
},
"BIT10" : {
"type" : "string",
+ "subType" : "bitstring",
"pattern" : "^[01]*$"
},
"BIT11" : {
"type" : "string",
+ "subType" : "bitstring",
"pattern" : "^[01]*$"
},
"BIT12" : {
"type" : "string",
+ "subType" : "bitstring",
"pattern" : "^[01]*$"
},
"BIT12n" : {
"type" : "string",
+ "subType" : "bitstring",
"pattern" : "^[01]*$"
},
"BIT14" : {
"type" : "string",
+ "subType" : "bitstring",
"pattern" : "^[01]*$"
},
"BIT14_24n" : {
"type" : "string",
+ "subType" : "bitstring",
"pattern" : "^[01]*$"
},
"BIT14n" : {
"type" : "string",
+ "subType" : "bitstring",
"pattern" : "^[01]*$"
},
"BIT15" : {
"type" : "string",
+ "subType" : "bitstring",
"pattern" : "^[01]*$"
},
"BIT15n" : {
"type" : "string",
+ "subType" : "bitstring",
"pattern" : "^[01]*$"
},
"BIT15np" : {
"type" : "string",
+ "subType" : "bitstring",
"pattern" : "^[01]*$"
},
"BIT16" : {
"type" : "string",
+ "subType" : "bitstring",
"pattern" : "^[01]*$"
},
"BIT16_BO_LAST" : {
"type" : "string",
+ "subType" : "bitstring",
"pattern" : "^[01]*$"
},
"BIT16n" : {
"type" : "string",
+ "subType" : "bitstring",
"pattern" : "^[01]*$"
},
"BIT1n" : {
"type" : "string",
+ "subType" : "bitstring",
"pattern" : "^[01]*$"
},
"BIT1np" : {
"type" : "string",
+ "subType" : "bitstring",
"pattern" : "^[01]*$"
},
"BIT2" : {
"type" : "string",
+ "subType" : "bitstring",
"pattern" : "^[01]*$"
},
"BIT24" : {
"type" : "string",
+ "subType" : "bitstring",
"pattern" : "^[01]*$"
},
"BIT2n" : {
"type" : "string",
+ "subType" : "bitstring",
"pattern" : "^[01]*$"
},
"BIT2np" : {
"type" : "string",
+ "subType" : "bitstring",
"pattern" : "^[01]*$"
},
"BIT3" : {
"type" : "string",
+ "subType" : "bitstring",
"pattern" : "^[01]*$"
},
"BIT31" : {
"type" : "string",
+ "subType" : "bitstring",
"pattern" : "^[01]*$"
},
"BIT32_BO_LAST" : {
"type" : "string",
+ "subType" : "bitstring",
"pattern" : "^[01]*$"
},
"BIT3n" : {
"type" : "string",
+ "subType" : "bitstring",
"pattern" : "^[01]*$"
},
"BIT3np" : {
"type" : "string",
+ "subType" : "bitstring",
"pattern" : "^[01]*$"
},
"BIT4" : {
"type" : "string",
+ "subType" : "bitstring",
"pattern" : "^[01]*$"
},
"BIT4n" : {
"type" : "string",
+ "subType" : "bitstring",
"pattern" : "^[01]*$"
},
"BIT4np" : {
"type" : "string",
+ "subType" : "bitstring",
"pattern" : "^[01]*$"
},
"BIT5" : {
"type" : "string",
+ "subType" : "bitstring",
"pattern" : "^[01]*$"
},
"BIT56" : {
"type" : "string",
+ "subType" : "bitstring",
"pattern" : "^[01]*$"
},
"BIT56n" : {
"type" : "string",
+ "subType" : "bitstring",
"pattern" : "^[01]*$"
},
"BIT5n" : {
"type" : "string",
+ "subType" : "bitstring",
"pattern" : "^[01]*$"
},
"BIT5np" : {
"type" : "string",
+ "subType" : "bitstring",
"pattern" : "^[01]*$"
},
"BIT6" : {
"type" : "string",
+ "subType" : "bitstring",
"pattern" : "^[01]*$"
},
"BIT6_BO_LAST" : {
"type" : "string",
+ "subType" : "bitstring",
"pattern" : "^[01]*$"
},
"BIT6n" : {
"type" : "string",
+ "subType" : "bitstring",
"pattern" : "^[01]*$"
},
"BIT6np" : {
"type" : "string",
+ "subType" : "bitstring",
"pattern" : "^[01]*$"
},
"BIT7" : {
"type" : "string",
+ "subType" : "bitstring",
"pattern" : "^[01]*$"
},
"BIT7n" : {
"type" : "string",
+ "subType" : "bitstring",
"pattern" : "^[01]*$"
},
"BIT7np" : {
"type" : "string",
+ "subType" : "bitstring",
"pattern" : "^[01]*$"
},
"BIT8" : {
"type" : "string",
+ "subType" : "bitstring",
"pattern" : "^[01]*$"
},
"BIT8n" : {
"type" : "string",
+ "subType" : "bitstring",
"pattern" : "^[01]*$"
},
"BIT9" : {
"type" : "string",
+ "subType" : "bitstring",
"pattern" : "^[01]*$"
},
"BIT9n" : {
"type" : "string",
+ "subType" : "bitstring",
"pattern" : "^[01]*$"
},
"CHAR4" : {
},
"Dummy" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"HEX0_16" : {
"type" : "string",
+ "subType" : "hexstring",
"pattern" : "^[0-9A-Fa-f]*$"
},
"HEX0_18n" : {
"type" : "string",
+ "subType" : "hexstring",
"pattern" : "^[0-9A-Fa-f]*$"
},
"HEX1" : {
"type" : "string",
+ "subType" : "hexstring",
"pattern" : "^[0-9A-Fa-f]*$"
},
"HEX15n" : {
"type" : "string",
+ "subType" : "hexstring",
"pattern" : "^[0-9A-Fa-f]*$"
},
"HEX16n" : {
"type" : "string",
+ "subType" : "hexstring",
"pattern" : "^[0-9A-Fa-f]*$"
},
"HEX1_20n" : {
"type" : "string",
+ "subType" : "hexstring",
"pattern" : "^[0-9A-Fa-f]*$"
},
"HEX1_32" : {
"type" : "string",
+ "subType" : "hexstring",
"pattern" : "^[0-9A-Fa-f]*$"
},
"HEX1_34n" : {
"type" : "string",
+ "subType" : "hexstring",
"pattern" : "^[0-9A-Fa-f]*$"
},
"HEX24n" : {
"type" : "string",
+ "subType" : "hexstring",
"pattern" : "^[0-9A-Fa-f]*$"
},
"HEX4n" : {
"type" : "string",
+ "subType" : "hexstring",
"pattern" : "^[0-9A-Fa-f]*$"
},
"HEX5_16" : {
"type" : "string",
+ "subType" : "hexstring",
"pattern" : "^[0-9A-Fa-f]*$"
},
"HEX6n" : {
"type" : "string",
+ "subType" : "hexstring",
"pattern" : "^[0-9A-Fa-f]*$"
},
"HEX8n" : {
"type" : "string",
+ "subType" : "hexstring",
"pattern" : "^[0-9A-Fa-f]*$"
},
"INT1" : {
},
"OCT0" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT0n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT1" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT10" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT100n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT10n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT11" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT11n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT12" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT128n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT12n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT13" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT13n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT14" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT14n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT15" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT15n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT16" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT16n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT17" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT17n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT18" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT18n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT19" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT19n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT1List" : {
},
"OCT1_112n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT1_12" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT1_127n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT1_128n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT1_12n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT1_15n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT1_16n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT1_172n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT1_18n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT1_20n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT1_24n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT1_260" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT1_32" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT1_32n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT1_34n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT1_3n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT1_46n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT1_4n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT1_50" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT1_50n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT1_5n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT1_6n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT1_7n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT1_8" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT1_8n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT1n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT2" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT20" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT20n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT28n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT2List" : {
},
"OCT2n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT3" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT32" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT32n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT34" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT34n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT3List" : {
},
"OCT3_14n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT3_17n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT3_5n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT3_7n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT3_8" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT3_8n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT3n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT4" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT46" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT46n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT4List" : {
},
"OCT4_8n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT4n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT5" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT500n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT50n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT5List" : {
},
"OCT5n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT6" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT69n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT6List" : {
},
"OCT6n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT7" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT7List" : {
},
"OCT7n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT8" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT8n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT9" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCT9n" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCTN" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"OCTNn" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"ProtocolList" : {
"bssmap",
"ranap",
"dtap"
+ ],
+ "numericValues" : [
+ 0,
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9
]
}
}
},
"anyOf" : [
+ {
+ "$ref" : "#/definitions/General_Types/OCT7n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT8n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT9n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/BIT2n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/BIT3n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/BIT4n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/BIT5n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/BIT6n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/BIT7n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/BIT8n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/BIT9n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/BIT12n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/BIT14n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/BIT15n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/BIT16n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/BIT56n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/BIT14_24n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/BIT1np"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/BIT2np"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/BIT11"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/BIT3np"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/BIT4np"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/BIT5np"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/BIT6np"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/BIT7np"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/BIT15np"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/BIT1"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/BIT2"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/BIT3"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/BIT4"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/BIT1n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/BIT5"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/BIT6"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/BIT7"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/BIT8"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/BIT9"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/BIT10"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT46n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/BIT12"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/BIT14"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/BIT15"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/BIT16"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/BIT24"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/BIT31"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/BIT56"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT0n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT1n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT2n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT3n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT4n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT5n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT6n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT10n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT11n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT12n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT13n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT14n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT15n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT16n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT17n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT18n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT19n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT20n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT28n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT32n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT34n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT6"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT50n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT69n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT100n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT128n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT500n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCTNn"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT1_3n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT1_4n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT1_5n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT1_6n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT1_7n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT1_8n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT1_12n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT1_15n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT1_16n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT1_18n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT1_20n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT1_24n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT1_32n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT1_34n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT1_46n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT1_50n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT1_112n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT1_127n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT1_128n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT1_172n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT3_5n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT3_7n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT3_8n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT3_14n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT3_17n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT4_8n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/CHAR4"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/HEX4n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/HEX6n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/HEX8n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/HEX15n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/HEX16n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/HEX24n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/HEX0_18n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/HEX1_20n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/HEX1_34n"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/INT3nb"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/INT4nb"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/INT5nb"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/INT8nb"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/INT2nbp"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/INT1nbp"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/INT3nbp"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/INT5nbp"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/INT9nbp"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/INT13nbp"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/INT15nbp"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/BIT6_BO_LAST"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/BIT16_BO_LAST"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/BIT32_BO_LAST"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/Dummy"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT0"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT1"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT2"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT3"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT4"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT5"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT7"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT8"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT9"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT10"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT11"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT12"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT13"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT14"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT15"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT16"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT17"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT18"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT19"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT20"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT32"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT34"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT46"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT1_260"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT1_8"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT1_12"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT1_32"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT1_50"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT3_8"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCTN"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/HEX1"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/HEX0_16"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/HEX5_16"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/HEX1_32"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/INT1"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/LIN1"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/LIN2"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/LIN2_BO_LAST"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/LIN3_BO_LAST"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/LIN4_BO_LAST"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/INT1b"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/INT2b"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/INT3b"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/INT4b"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/INT5b"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/INT6b"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/INT7b"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/INT11b_BO_LAST"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/INT12b_BO_LAST"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/INT13b_BO_LAST"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/INT14b_BO_LAST"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/INT20b_BO_LAST"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/INT31b_BO_LAST"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/Integers"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/Integer_array"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/Protocols"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT1List"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT2List"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT3List"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT4List"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT5List"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT6List"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/OCT7List"
+ },
+ {
+ "$ref" : "#/definitions/General_Types/ProtocolList"
+ }
]
}
--- /dev/null
+/******************************************************************************
+ * Copyright (c) 2000-2015 Ericsson Telecom AB
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ ******************************************************************************/
+
+module Main
+{
+
+import from PDU_Definitions all;
+
+type record HasPardType {
+ ProtocolElem_Field1 pard,
+ boolean buul,
+ Price price
+}
+
+external function f_enc_hpt(in HasPardType x) return octetstring
+ with { extension "prototype(convert) encode(JSON) printing(pretty)" }
+
+external function f_dec_hpt(in octetstring x) return HasPardType
+ with { extension "prototype(convert) decode(JSON)" }
+
+external function f_enc_pard(in ProtocolElem_Field1 x) return octetstring
+ with { extension "prototype(convert) encode(JSON) printing(pretty)" }
+
+external function f_enc_obj(in Object x) return octetstring
+ with { extension "prototype(convert) encode(JSON)" }
+
+external function f_dec_obj(in octetstring x) return Object
+ with { extension "prototype(convert) decode(JSON)" }
+
+} with {
+ encode "JSON"
+}
--- /dev/null
+{
+ "definitions" : {
+ "Main" : {
+ "HasPardType" : {
+ "type" : "object",
+ "subType" : "record",
+ "properties" : {
+ "pard" : {
+ "$ref" : "#/definitions/PDU_Definitions/ProtocolElem_Field1"
+ },
+ "buul" : {
+ "type" : "boolean"
+ },
+ "price" : {
+ "$ref" : "#/definitions/PDU_Definitions/Price"
+ }
+ },
+ "additionalProperties" : false,
+ "fieldOrder" : [
+ "pard",
+ "buul",
+ "price"
+ ],
+ "required" : [
+ "pard",
+ "buul",
+ "price"
+ ]
+ }
+ },
+ "PDU_Definitions" : {
+ "Priority" : {
+ "enum" : [
+ "low",
+ "normal",
+ "medium",
+ "high",
+ "urgent"
+ ],
+ "numericValues" : [
+ 0,
+ 1,
+ 2,
+ 3,
+ 4
+ ]
+ },
+ "Conditionality" : {
+ "enum" : [
+ "optional_",
+ "conditional",
+ "mandatory"
+ ],
+ "numericValues" : [
+ 0,
+ 1,
+ 2
+ ]
+ },
+ "ProtocolElem_ID" : {
+ "type" : "integer"
+ },
+ "ProtocolElem_Field2" : {
+ "type" : "object",
+ "subType" : "record",
+ "properties" : {
+ "id" : {
+ "$ref" : "#/definitions/PDU_Definitions/ProtocolElem_ID"
+ },
+ "priority" : {
+ "$ref" : "#/definitions/PDU_Definitions/Priority"
+ },
+ "val" : {
+ "anyOf" : [
+ {
+ "type" : "object",
+ "properties" : {
+ "iA5String" : {
+ "type" : "string",
+ "subType" : "charstring"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "iA5String"
+ ]
+ }
+ ]
+ }
+ },
+ "additionalProperties" : false,
+ "fieldOrder" : [
+ "id",
+ "priority",
+ "val"
+ ],
+ "required" : [
+ "id",
+ "priority",
+ "val"
+ ]
+ },
+ "ProtocolElem_Field1" : {
+ "type" : "object",
+ "subType" : "record",
+ "properties" : {
+ "id" : {
+ "$ref" : "#/definitions/PDU_Definitions/ProtocolElem_ID"
+ },
+ "priority" : {
+ "$ref" : "#/definitions/PDU_Definitions/Priority"
+ },
+ "val" : {
+ "anyOf" : [
+ {
+ "type" : "object",
+ "properties" : {
+ "iNTEGER" : {
+ "type" : "integer"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "iNTEGER"
+ ]
+ },
+ {
+ "type" : "object",
+ "properties" : {
+ "iA5String" : {
+ "type" : "string",
+ "subType" : "charstring"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "iA5String"
+ ]
+ }
+ ]
+ }
+ },
+ "additionalProperties" : false,
+ "fieldOrder" : [
+ "id",
+ "priority",
+ "val"
+ ],
+ "required" : [
+ "id",
+ "priority",
+ "val"
+ ]
+ },
+ "Price" : {
+ "anyOf" : [
+ {
+ "type" : "object",
+ "properties" : {
+ "value_" : {
+ "anyOf" : [
+ {
+ "type" : "number"
+ },
+ {
+ "enum" : [
+ "not_a_number",
+ "infinity",
+ "-infinity"
+ ]
+ }
+ ]
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "value_"
+ ]
+ },
+ {
+ "type" : "object",
+ "properties" : {
+ "invaluable" : {
+ "type" : "null"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "invaluable"
+ ]
+ }
+ ]
+ },
+ "Object" : {
+ "type" : "object",
+ "subType" : "record",
+ "properties" : {
+ "id" : {
+ "type" : "string",
+ "subType" : "objid",
+ "pattern" : "^[0-2][.][1-3]?[0-9]([.][0-9]|([1-9][0-9]+))*$"
+ },
+ "data" : {
+ "type" : "string",
+ "subType" : "octetstring",
+ "pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
+ }
+ },
+ "additionalProperties" : false,
+ "fieldOrder" : [
+ "id",
+ "data"
+ ],
+ "required" : [
+ "id",
+ "data"
+ ]
+ },
+ "HasNull" : {
+ "type" : "object",
+ "subType" : "record",
+ "properties" : {
+ "theNull" : {
+ "type" : "null"
+ }
+ },
+ "additionalProperties" : false
+ }
+ }
+ },
+ "anyOf" : [
+ {
+ "$ref" : "#/definitions/Main/HasPardType",
+ "decoding" : {
+ "prototype" : [
+ "convert",
+ "f_dec_hpt",
+ "x"
+ ]
+ },
+ "encoding" : {
+ "prototype" : [
+ "convert",
+ "f_enc_hpt",
+ "x"
+ ],
+ "printing" : "pretty"
+ }
+ },
+ {
+ "$ref" : "#/definitions/PDU_Definitions/ProtocolElem_Field1",
+ "encoding" : {
+ "prototype" : [
+ "convert",
+ "f_enc_pard",
+ "x"
+ ],
+ "printing" : "pretty"
+ }
+ },
+ {
+ "$ref" : "#/definitions/PDU_Definitions/Object",
+ "decoding" : {
+ "prototype" : [
+ "convert",
+ "f_dec_obj",
+ "x"
+ ]
+ },
+ "encoding" : {
+ "prototype" : [
+ "convert",
+ "f_enc_obj",
+ "x"
+ ]
+ }
+ }
+ ]
+}
TTCN3_LIB = ttcn3$(RT2_SUFFIX)$(DYNAMIC_SUFFIX)
-TTCN3_MODULES = PIPEasp_PortType.ttcn PIPEasp_Types.ttcn PIPEasp_Templates.ttcn Shell.ttcn Testcases.ttcn
+TTCN3_MODULES = PIPEasp_PortType.ttcn PIPEasp_Types.ttcn PIPEasp_Templates.ttcn Shell.ttcn Testcases.ttcn CompareSchemas.ttcn
ASN1_MODULES =
GENERATED_SOURCES := $(foreach file, $(GENERATED_SOURCES:.cc=), $(addprefix $(file), .cc _seq.cc _set.cc _seqof.cc _setof.cc _union.cc))
endif
-USER_SOURCES = PIPEasp_PT.cc
+USER_SOURCES = PIPEasp_PT.cc f_ext_import_schema.cc
USER_HEADERS = $(USER_SOURCES:.cc=.hh)
OBJECTS = $(GENERATED_SOURCES:.cc=.o) $(USER_SOURCES:.cc=.o)
TARGET = ttcn2json$(EXESUFFIX)
-TEMP_FILES = General_Types.json one.json two.json three.json
+TEMP_FILES = General_Types.json one.json two.json three.json Main.json
all: $(TARGET)
--- /dev/null
+-------------------------------------------------------------------------------
+-- Copyright (c) 2000-2015 Ericsson Telecom AB
+-- All rights reserved. This program and the accompanying materials
+-- are made available under the terms of the Eclipse Public License v1.0
+-- which accompanies this distribution, and is available at
+-- http://www.eclipse.org/legal/epl-v10.html
+-------------------------------------------------------------------------------
+
+MiniRanap
+
+-- This module contains a simplified version of the type DirectTransferInformationList-RANAP-RelocInf
+-- from the RANAP protocol module and any elements needed to recreate it.
+-- Used for tesing the JSON schema generator on an ASN.1 ellipsis type
+
+DEFINITIONS
+
+AUTOMATIC TAGS ::=
+
+BEGIN
+
+IMPORTS ;
+
+-- RANAP-CommonDataTypes
+Criticality ::= ENUMERATED { reject, ignore, notify }
+
+Presence ::= ENUMERATED { optionalValue, conditional, mandatory }
+
+ProtocolIE-ID ::= INTEGER (0..65535)
+
+-- RANAP-Containers
+RANAP-PROTOCOL-IES ::= CLASS {
+ &id ProtocolIE-ID UNIQUE,
+ &criticality Criticality,
+ &Value,
+ &presence Presence
+}
+WITH SYNTAX {
+ ID &id
+ CRITICALITY &criticality
+ TYPE &Value
+ PRESENCE &presence
+}
+
+ProtocolIE-ContainerList {INTEGER : lowerBound, INTEGER : upperBound, RANAP-PROTOCOL-IES : IEsSetParam} ::=
+ SEQUENCE (SIZE (lowerBound..upperBound)) OF
+ ProtocolIE-Container {{IEsSetParam}}
+
+ProtocolIE-Container {RANAP-PROTOCOL-IES : IEsSetParam} ::=
+ SEQUENCE (SIZE (0..maxProtocolIEs)) OF
+ ProtocolIE-Field {{IEsSetParam}}
+
+ProtocolIE-Field {RANAP-PROTOCOL-IES : IEsSetParam} ::= SEQUENCE {
+ id RANAP-PROTOCOL-IES.&id ({IEsSetParam}),
+ criticality RANAP-PROTOCOL-IES.&criticality ({IEsSetParam}{@id}),
+ valueField RANAP-PROTOCOL-IES.&Value ({IEsSetParam}{@id})
+}
+
+-- RANAP-PDU-Contents
+DirectTransfer-IE-ContainerList { RANAP-PROTOCOL-IES : IEsSetParam } ::=
+ ProtocolIE-ContainerList { 1, maxNrOfDTs, {IEsSetParam} }
+
+DirectTransferInformationList-RANAP-RelocInf ::=
+ DirectTransfer-IE-ContainerList { {DirectTransferInformationItemIEs-RANAP-RelocInf} }
+
+DirectTransferInformationItemIEs-RANAP-RelocInf RANAP-PROTOCOL-IES ::= {
+ { ID id-DirectTransferInformationItem-RANAP-RelocInf
+ CRITICALITY ignore TYPE INTEGER --DirectTransferInformationItem-RANAP-RelocInf
+ PRESENCE mandatory },
+ ...
+}
+
+-- RABAP-Constants
+maxNrOfDTs INTEGER ::= 15
+
+id-DirectTransferInformationItem-RANAP-RelocInf INTEGER ::= 80
+
+maxProtocolIEs INTEGER ::= 65535
+
+END
+
--- /dev/null
+{
+ "definitions" : {
+ "MiniRanap" : {
+ "Criticality" : {
+ "enum" : [
+ "reject",
+ "ignore",
+ "notify"
+ ],
+ "numericValues" : [
+ 0,
+ 1,
+ 2
+ ]
+ },
+ "DirectTransferInformationList_RANAP_RelocInf" : {
+ "type" : "array",
+ "subType" : "record of",
+ "items" : {
+ "type" : "array",
+ "subType" : "record of",
+ "items" : {
+ "type" : "object",
+ "subType" : "record",
+ "properties" : {
+ "id" : {
+ "$ref" : "#/definitions/MiniRanap/ProtocolIE_ID"
+ },
+ "criticality" : {
+ "$ref" : "#/definitions/MiniRanap/Criticality"
+ },
+ "valueField" : {
+ "anyOf" : [
+ {
+ "type" : "object",
+ "properties" : {
+ "iNTEGER" : {
+ "type" : "integer"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "iNTEGER"
+ ]
+ }
+ ]
+ }
+ },
+ "additionalProperties" : false,
+ "fieldOrder" : [
+ "id",
+ "criticality",
+ "valueField"
+ ],
+ "required" : [
+ "id",
+ "criticality",
+ "valueField"
+ ]
+ }
+ }
+ },
+ "Presence" : {
+ "enum" : [
+ "optionalValue",
+ "conditional",
+ "mandatory"
+ ],
+ "numericValues" : [
+ 0,
+ 1,
+ 2
+ ]
+ },
+ "ProtocolIE_ID" : {
+ "type" : "integer"
+ }
+ }
+ },
+ "anyOf" : [
+ {
+ "$ref" : "#/definitions/MiniRanap/Criticality"
+ },
+ {
+ "$ref" : "#/definitions/MiniRanap/Presence"
+ },
+ {
+ "$ref" : "#/definitions/MiniRanap/ProtocolIE_ID"
+ },
+ {
+ "$ref" : "#/definitions/MiniRanap/DirectTransferInformationList_RANAP_RelocInf"
+ }
+ ]
+}
--- /dev/null
+------------------------------------------------------------------------------
+-- Copyright (c) 2000-2015 Ericsson Telecom AB
+-- All rights reserved. This program and the accompanying materials
+-- are made available under the terms of the Eclipse Public License v1.0
+-- which accompanies this distribution, and is available at
+-- http://www.eclipse.org/legal/epl-v10.html
+------------------------------------------------------------------------------
+
+--
+-- Based on definitions used in S1AP
+--
+
+PDU-Definitions DEFINITIONS ::=
+BEGIN
+
+Priority ::= ENUMERATED { low, normal, medium, high, urgent }
+
+Conditionality ::= ENUMERATED { optional, conditional, mandatory }
+
+ProtocolElem-ID ::= INTEGER (0..65535)
+
+
+--IOC
+PROTOCOL-ELEMS ::= CLASS
+{
+ &id ProtocolElem-ID UNIQUE,
+ &priority Priority,
+ &Value,
+ &conditionality Conditionality
+}
+WITH SYNTAX
+{
+ ID &id
+ PRIORITY &priority
+ TYPE &Value
+ CONDITIONALITY &conditionality
+}
+
+--parameterized type
+ProtocolElem-Field {PROTOCOL-ELEMS : ElemsSetParam} ::= SEQUENCE
+{
+ id PROTOCOL-ELEMS.&id ({ElemsSetParam}),
+ priority PROTOCOL-ELEMS.&priority ({ElemsSetParam}{@id}),
+ val PROTOCOL-ELEMS.&Value ({ElemsSetParam}{@id})
+}
+
+
+--Information objects
+ies-Set-Element-1 PROTOCOL-ELEMS ::=
+{
+ ID 0
+ PRIORITY low
+ TYPE INTEGER
+ CONDITIONALITY mandatory
+}
+
+ies-Set-Element-2 PROTOCOL-ELEMS ::=
+{
+ ID 1
+ PRIORITY high
+ TYPE IA5String
+ CONDITIONALITY optional
+}
+--Information Object Set
+Elems-Set PROTOCOL-ELEMS ::= { ies-Set-Element-1 | ies-Set-Element-2 }
+
+
+--instantiation
+ProtocolElem-Field1 ::= ProtocolElem-Field {{Elems-Set}}
+
+ProtocolElem-Field2 ::= ProtocolElem-Field {{ies-Set-Element-2 }}
+
+--Choice containing NULL
+Price ::= CHOICE
+{
+ value REAL,
+ invaluable NULL
+}
+
+--Sequence containing an object identifier and an ANY type
+Object ::= SEQUENCE
+{
+ id OBJECT IDENTIFIER,
+ data ANY
+}
+
+--Sequence containing an optional NULL field
+HasNull ::= SEQUENCE
+{
+ theNull NULL OPTIONAL
+}
+
+END
module Testcases {
import from Shell all;
+import from CompareSchemas all;
function f_test_ttcn2json(in charstring p_args, in charstring p_gen_file_name, in charstring p_exp_file_name,
in integer p_exp_result) runs on Shell_CT
var charstring v_cmd := "compiler --ttcn2json " & p_args;
f_shellCommandWithVerdict(v_cmd, "", p_exp_result);
- /* The generated schema cannot be checked this way, as different platforms generate the parts of the schema
- in a different order
if (getverdict == pass) {
- f_compareFiles(p_gen_file_name, p_exp_file_name, 0);
- if (getverdict == fail) {
- action("Generated and expected files do not match");
+ if (f_compare_schemas(p_gen_file_name, p_exp_file_name) == false) {
+ setverdict(fail, "Generated and expected files do not match");
}
}
else {
action("Command ", v_cmd, " failed");
- }*/
+ }
+
}
testcase tc_t2j_one() runs on Shell_CT
{
- f_test_ttcn2json("one.ttcn two.ttcn three.ttcn zero.asn", "one.json", "one_e.json",
+ f_test_ttcn2json("-f one.ttcn two.ttcn three.ttcn zero.asn", "one.json", "one_e.json",
c_shell_successWithWarning);
}
testcase tc_t2j_two() runs on Shell_CT
{
- f_test_ttcn2json("one.ttcn two.ttcn three.ttcn zero.asn - two.json", "two.json", "one_e.json",
+ f_test_ttcn2json("-jf one.ttcn two.ttcn three.ttcn zero.asn - two.json", "two.json", "two_e.json",
c_shell_successWithWarning);
}
testcase tc_t2j_three() runs on Shell_CT
{
- f_test_ttcn2json("-T one.ttcn -T two.ttcn -T three.ttcn -A zero.asn - three.json", "three.json", "one_e.json",
+ f_test_ttcn2json("-j -T one.ttcn -T two.ttcn -T three.ttcn -A zero.asn - three.json", "three.json", "three_e.json",
c_shell_successWithWarning);
}
c_shell_successWithoutWarningAndError);
}
+testcase tc_t2j_main_asn() runs on Shell_CT
+{
+ f_test_ttcn2json("-f Main.ttcn PDU_Definitions.asn", "Main.json", "Main_e.json",
+ c_shell_successWithoutWarningAndError);
+}
+
+testcase tc_t2j_mini_ranap() runs on Shell_CT
+{
+ f_test_ttcn2json("MiniRanap.asn", "MiniRanap.json", "MiniRanap_e.json",
+ c_shell_successWithoutWarningAndError);
+}
+
control {
execute(tc_t2j_one());
execute(tc_t2j_two());
execute(tc_t2j_three());
execute(tc_t2j_general_types());
+ execute(tc_t2j_main_asn());
+ execute(tc_t2j_mini_ranap());
}
}
--- /dev/null
+/******************************************************************************
+ * Copyright (c) 2000-2015 Ericsson Telecom AB
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ ******************************************************************************/
+
+#include "f_ext_import_schema.hh"
+#include <stdio.h>
+#include <string.h>
+
+namespace CompareSchemas {
+
+#define IMPORT_FORMAT_ERROR(cond, comment) \
+ if (cond) { \
+ TTCN_error("Invalid format for file '%s' (%s). JSON schema could not be imported.", file_name, comment); \
+ }
+
+ElemKey get_elem_key(const char* value, size_t value_len, const char* file_name)
+{
+ if (4 == value_len && 0 == strncmp(value, "$ref", value_len)) {
+ return ElemKey::Ref;
+ }
+ if (4 == value_len && 0 == strncmp(value, "type", value_len)) {
+ return ElemKey::Type;
+ }
+ if (7 == value_len && 0 == strncmp(value, "subType", value_len)) {
+ return ElemKey::SubType;
+ }
+ if (7 == value_len && 0 == strncmp(value, "pattern", value_len)) {
+ return ElemKey::Pattern;
+ }
+ if (12 == value_len && 0 == strncmp(value, "originalName", value_len)) {
+ return ElemKey::OriginalName;
+ }
+ if (11 == value_len && 0 == strncmp(value, "unusedAlias", value_len)) {
+ return ElemKey::UnusedAlias;
+ }
+ if (20 == value_len && 0 == strncmp(value, "additionalProperties", value_len)) {
+ return ElemKey::AdditionalProperties;
+ }
+ if (10 == value_len && 0 == strncmp(value, "omitAsNull", value_len)) {
+ return ElemKey::OmitAsNull;
+ }
+ if (7 == value_len && 0 == strncmp(value, "default", value_len)) {
+ return ElemKey::Default;
+ }
+ if (8 == value_len && 0 == strncmp(value, "minItems", value_len)) {
+ return ElemKey::MinItems;
+ }
+ if (8 == value_len && 0 == strncmp(value, "maxItems", value_len)) {
+ return ElemKey::MaxItems;
+ }
+ if (4 == value_len && 0 == strncmp(value, "enum", value_len)) {
+ return ElemKey::Enum;
+ }
+ if (13 == value_len && 0 == strncmp(value, "numericValues", value_len)) {
+ return ElemKey::NumericValues;
+ }
+ if (5 == value_len && 0 == strncmp(value, "items", value_len)) {
+ return ElemKey::Items;
+ }
+ if (5 == value_len && 0 == strncmp(value, "anyOf", value_len)) {
+ return ElemKey::AnyOf;
+ }
+ if (8 == value_len && 0 == strncmp(value, "required", value_len)) {
+ return ElemKey::Required;
+ }
+ if (10 == value_len && 0 == strncmp(value, "fieldOrder", value_len)) {
+ return ElemKey::FieldOrder;
+ }
+ if (10 == value_len && 0 == strncmp(value, "properties", value_len)) {
+ return ElemKey::Properties;
+ }
+ // throw the DTE if it didn't return until now
+ IMPORT_FORMAT_ERROR(true, "unknown type element key");
+}
+
+TypeSchema extract_type_schema(JSON_Tokenizer& json, const char* file_name)
+{
+ json_token_t token = JSON_TOKEN_NONE;
+ char* value = NULL;
+ size_t value_len = 0;
+
+ // type schema object start
+ json.get_next_token(&token, NULL, NULL);
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_OBJECT_START != token, "missing type object start");
+
+ // type schema elements
+ TypeSchema type_schema;
+ int elem_index = 0;
+ json.get_next_token(&token, &value, &value_len);
+ while(JSON_TOKEN_NAME == token) {
+ type_schema[elem_index].key() = get_elem_key(value, value_len, file_name);
+ switch(type_schema[elem_index].key()) {
+ case ElemKey::Ref:
+ case ElemKey::Type:
+ case ElemKey::SubType:
+ case ElemKey::Pattern:
+ case ElemKey::OriginalName:
+ case ElemKey::UnusedAlias:
+ case ElemKey::MinItems:
+ case ElemKey::MaxItems:
+ case ElemKey::AdditionalProperties:
+ case ElemKey::OmitAsNull:
+ case ElemKey::Default: {
+ // string or boolean value
+ json.get_next_token(&token, &value, &value_len);
+ switch (token) {
+ case JSON_TOKEN_STRING:
+ case JSON_TOKEN_NUMBER: {
+ CHARSTRING str_val(value_len, value);
+ type_schema[elem_index].val().strVal() = str_val;
+ break; }
+ case JSON_TOKEN_LITERAL_FALSE:
+ type_schema[elem_index].val().boolVal() = FALSE;
+ break;
+ case JSON_TOKEN_LITERAL_TRUE:
+ type_schema[elem_index].val().boolVal() = TRUE;
+ break;
+ default:
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_LITERAL_FALSE != token, "string or boolean value expected");
+ }
+ break; }
+
+ case ElemKey::Enum:
+ case ElemKey::NumericValues:
+ case ElemKey::Required:
+ case ElemKey::FieldOrder: {
+ // string array value
+ json.get_next_token(&token, NULL, NULL);
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_ARRAY_START != token, "missing string array start");
+ json.get_next_token(&token, &value, &value_len);
+ int string_index = 0;
+ while (JSON_TOKEN_STRING == token || JSON_TOKEN_NUMBER == token) {
+ CHARSTRING str_val(value_len, value);
+ type_schema[elem_index].val().strArrayVal()[string_index] = str_val;
+
+ // next string
+ ++string_index;
+ json.get_next_token(&token, &value, &value_len);
+ }
+
+ // string array end
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_ARRAY_END != token, "missing string array end");
+ break; }
+
+ case ElemKey::Items: {
+ // type schema value
+ type_schema[elem_index].val().typeVal() = extract_type_schema(json, file_name);
+ break; }
+
+ case ElemKey::AnyOf: {
+ // type schema array value
+ json.get_next_token(&token, NULL, NULL);
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_ARRAY_START != token, "missing type array start");
+ int type_index = 0;
+ size_t buf_pos = json.get_buf_pos();
+ json.get_next_token(&token, NULL, NULL);
+ while (JSON_TOKEN_OBJECT_START == token) {
+ // revert this extraction, the type schema extractor will read the "{" again
+ json.set_buf_pos(buf_pos);
+ type_schema[elem_index].val().typeArrayVal()[type_index] = extract_type_schema(json, file_name);
+
+ // next type schema
+ ++type_index;
+ buf_pos = json.get_buf_pos();
+ json.get_next_token(&token, NULL, NULL);
+ }
+
+ // type schema array end
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_ARRAY_END != token, "missing type array end");
+ break; }
+
+ case ElemKey::Properties: {
+ // field set value
+ json.get_next_token(&token, NULL, NULL);
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_OBJECT_START != token, "missing field set start");
+ int field_index = 0;
+ json.get_next_token(&token, &value, &value_len);
+ while(JSON_TOKEN_NAME == token) {
+ // store field name and schema
+ CHARSTRING field_name(value_len, value);
+ type_schema[elem_index].val().fieldSetVal()[field_index].fieldName() = field_name;
+ type_schema[elem_index].val().fieldSetVal()[field_index].schema() = extract_type_schema(json, file_name);
+
+ // next field
+ ++field_index;
+ json.get_next_token(&token, &value, &value_len);
+ }
+
+ // field set value end
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_OBJECT_END != token, "missing field set end");
+ break; }
+ default:
+ break;
+ }
+
+ // next schema element
+ ++elem_index;
+ json.get_next_token(&token, &value, &value_len);
+ }
+
+ // type schema object end
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_OBJECT_END != token, "missing type object end");
+ return type_schema;
+}
+
+EncDecData extract_enc_dec_data(JSON_Tokenizer& json, const char* file_name)
+{
+ // initialize (error behavior and printing data might not appear in the schema)
+ json_token_t token = JSON_TOKEN_NONE;
+ char* value = NULL;
+ size_t value_len = 0;
+ EncDecData data;
+ data.eb() = OMIT_VALUE;
+ data.printing() = OMIT_VALUE;
+
+ // enc/dec data start
+ json.get_next_token(&token, NULL, NULL);
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_OBJECT_START != token, "missing enc/dec data start");
+ json.get_next_token(&token, &value, &value_len);
+ while(JSON_TOKEN_NAME == token) {
+ if (9 == value_len && 0 == strncmp(value, "prototype", value_len)) {
+ // prototype (string array)
+ json.get_next_token(&token, NULL, NULL);
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_ARRAY_START != token, "missing prototype array start");
+ json.get_next_token(&token, &value, &value_len);
+ int pt_index = 0;
+ while(JSON_TOKEN_STRING == token) {
+ CHARSTRING pt_str(value_len, value);
+ data.prototype()[pt_index] = pt_str;
+
+ // next prototype element
+ ++pt_index;
+ json.get_next_token(&token, &value, &value_len);
+ }
+
+ // prototype end
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_ARRAY_END != token, "missing prototype array end");
+ }
+ else if (13 == value_len && 0 == strncmp(value, "errorBehavior", value_len)) {
+ // error behavior (object)
+ json.get_next_token(&token, NULL, NULL);
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_OBJECT_START != token, "missing error behavior start");
+ json.get_next_token(&token, &value, &value_len);
+ int eb_index = 0;
+ while(JSON_TOKEN_NAME == token) {
+ // store the key-value pair
+ CHARSTRING error_type(value_len, value);
+ json.get_next_token(&token, &value, &value_len);
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_STRING != token, "expected error behavior string");
+ CHARSTRING error_behavior(value_len, value);
+ data.eb()()[eb_index].errorType() = error_type;
+ data.eb()()[eb_index].errorBehavior() = error_behavior;
+
+ // next pair
+ ++eb_index;
+ json.get_next_token(&token, &value, &value_len);
+ }
+
+ // error behavior end
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_OBJECT_END != token, "missing error behavior end");
+ }
+ else if (8 == value_len && 0 == strncmp(value, "printing", value_len)) {
+ json.get_next_token(&token, &value, &value_len);
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_STRING != token, "expected printing string");
+ CHARSTRING printing_str(value_len, value);
+ data.printing()() = printing_str;
+ }
+ else {
+ // invalid key
+ IMPORT_FORMAT_ERROR(true, "invalid enc/dec data key");
+ }
+
+ // next key-value pair
+ json.get_next_token(&token, &value, &value_len);
+ }
+
+ // enc/dec data end
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_OBJECT_END != token, "missing enc/dec data end");
+ return data;
+}
+
+RefSchema extract_ref_schema(JSON_Tokenizer& json, const char* file_name)
+{
+ // initialize (set optional fields to "omit")
+ json_token_t token = JSON_TOKEN_NONE;
+ char* value = NULL;
+ size_t value_len = 0;
+ RefSchema ref_schema;
+ ref_schema.enc() = OMIT_VALUE;
+ ref_schema.dec() = OMIT_VALUE;
+
+ // read reference data
+ json.get_next_token(&token, &value, &value_len);
+ while(JSON_TOKEN_NAME == token) {
+ if (4 == value_len && 0 == strncmp(value, "$ref", value_len)) {
+ // reference
+ json.get_next_token(&token, &value, &value_len);
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_STRING != token, "missing reference string");
+ CHARSTRING ref_str(value_len, value);
+ ref_schema.ref() = ref_str;
+ }
+ else if (8 == value_len && 0 == strncmp(value, "encoding", value_len)) {
+ // encoding function
+ ref_schema.enc()() = extract_enc_dec_data(json, file_name);
+ }
+ else if (8 == value_len && 0 == strncmp(value, "decoding", value_len)) {
+ // encoding function
+ ref_schema.dec()() = extract_enc_dec_data(json, file_name);
+ }
+ else {
+ // invalid key
+ IMPORT_FORMAT_ERROR(true, "invalid reference/function data key");
+ }
+
+ // next key-value pair
+ json.get_next_token(&token, &value, &value_len);
+ }
+
+ // reference & function info end
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_OBJECT_END != token, "missing reference/function data end");
+ return ref_schema;
+}
+
+void f__ext__import__schema(const CHARSTRING& file, JsonSchema& schema)
+{
+ // need a null-terminated string for fopen
+ char* file_name = mcopystrn((const char*)file, file.lengthof());
+ FILE* fp = fopen(file_name, "r");
+ try {
+ if (NULL == fp) {
+ TTCN_error("Could not open file '%s' for reading. JSON schema could not be imported.", file_name);
+ }
+
+ // get the file size
+ fseek(fp, 0, SEEK_END);
+ int file_size = ftell(fp);
+ rewind(fp);
+
+ // read the entire file into a character buffer
+ char* buffer = (char*)Malloc(file_size);
+ fread(buffer, 1, file_size, fp);
+ fclose(fp);
+
+ // initialize a JSON tokenizer with the buffer
+ JSON_Tokenizer json(buffer, file_size);
+ Free(buffer);
+
+ // extract tokens and store the schema in the JsonSchema parameter
+ // throw a DTE if the file format is invalid
+ json_token_t token = JSON_TOKEN_NONE;
+ char* value = NULL;
+ size_t value_len = 0;
+
+ // top level object
+ json.get_next_token(&token, NULL, NULL);
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_OBJECT_START != token, "missing top level object start");
+
+ // definitions
+ json.get_next_token(&token, &value, &value_len);
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_NAME != token || value_len != 11 ||
+ 0 != strncmp(value, "definitions", value_len), "missing definitions key");
+
+ // module list
+ json.get_next_token(&token, NULL, NULL);
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_OBJECT_START != token, "missing module list start");
+ json.get_next_token(&token, &value, &value_len);
+ int type_index = 0;
+ while (JSON_TOKEN_NAME == token) {
+ // extract module name, it will be inserted later
+ CHARSTRING module_name(value_len, value);
+
+ // type list
+ json.get_next_token(&token, NULL, NULL);
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_OBJECT_START != token, "missing type list start");
+ json.get_next_token(&token, &value, &value_len);
+ while (JSON_TOKEN_NAME == token) {
+ // extract type name
+ CHARSTRING type_name(value_len, value);
+
+ // extract type schema
+ TypeSchema type_schema = extract_type_schema(json, file_name);
+
+ // store definition data
+ schema.defs()[type_index].moduleName() = module_name;
+ schema.defs()[type_index].typeName() = type_name;
+ schema.defs()[type_index].schema() = type_schema;
+
+ // next type
+ ++type_index;
+ json.get_next_token(&token, &value, &value_len);
+ }
+
+ // end of type list
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_OBJECT_END != token, "missing type list end");
+
+ // next module
+ json.get_next_token(&token, &value, &value_len);
+ }
+
+ // end of module list
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_OBJECT_END != token, "missing module list end");
+
+ if (0 == type_index) {
+ // no definitions, don't leave the field unbound
+ schema.defs().set_size(0);
+ }
+
+ // top level anyOf
+ json.get_next_token(&token, &value, &value_len);
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_NAME != token || value_len != 5 ||
+ 0 != strncmp(value, "anyOf", value_len), "missing anyOf key");
+
+ // reference & function info array
+ json.get_next_token(&token, NULL, NULL);
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_ARRAY_START != token, "missing reference/function list start");
+ json.get_next_token(&token, NULL, NULL);
+ int ref_index = 0;
+ while (JSON_TOKEN_OBJECT_START == token) {
+
+ // extract reference schema
+ schema.refs()[ref_index] = extract_ref_schema(json, file_name);
+
+ // next reference
+ ++ref_index;
+ json.get_next_token(&token, NULL, NULL);
+ }
+
+ // end of reference & function info array
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_ARRAY_END != token, "missing reference/function list end");
+
+ if (0 == ref_index) {
+ // no references, don't leave the field unbound
+ schema.refs().set_size(0);
+ }
+
+ // end of top level object
+ json.get_next_token(&token, NULL, NULL);
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_OBJECT_END != token, "missing top level object end");
+
+ // end of the schema
+ json.get_next_token(&token, NULL, NULL);
+ IMPORT_FORMAT_ERROR(JSON_TOKEN_NONE != token, "expected end of file");
+ }
+ catch (...) {
+ Free(file_name);
+ throw;
+ }
+ Free(file_name);
+}
+
+}
+
--- /dev/null
+/******************************************************************************
+ * Copyright (c) 2000-2015 Ericsson Telecom AB
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ ******************************************************************************/
+
+#ifndef f_ext_import_schema_HH
+#define f_ext_import_schema_HH
+
+#include "CompareSchemas.hh"
+
+namespace CompareSchemas {
+
+/** Imports a JSON schema from a given file to the specified container.
+ * Throws a Dynamic Testcase Error on failure.
+ *
+ * @param file source file name
+ * @param schema JSON schema container (defined in CompareSchemas.ttcn)
+ */
+extern void f__ext__import__schema(const CHARSTRING& file, JsonSchema& schema);
+
+}
+
+#endif
+
"Short",
"Medium",
"Tall"
+ ],
+ "numericValues" : [
+ 0,
+ 1,
+ 2
]
},
"Rec" : {
"properties" : {
"os" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
},
"buul" : {
"properties" : {
"bytes" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
}
},
"Thin",
"Medium",
"Wide"
+ ],
+ "numericValues" : [
+ 0,
+ 1,
+ 2
]
},
"anytype" : {
"properties" : {
"bitstring" : {
"type" : "string",
+ "subType" : "bitstring",
"pattern" : "^[01]*$"
}
},
"subType" : "record of",
"items" : {
"type" : "string",
+ "subType" : "bitstring",
"pattern" : "^[01]*$"
}
},
"subType" : "record of",
"items" : {
"type" : "string",
+ "subType" : "hexstring",
"pattern" : "^[0-9A-Fa-f]*$"
}
},
"subType" : "set of",
"items" : {
"type" : "string",
+ "subType" : "octetstring",
"pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
}
},
"Small",
"Medium",
"Large"
+ ],
+ "numericValues" : [
+ 0,
+ 1,
+ 2
]
},
"filled" : {
}
},
"Zero" : {
+ "SeqOfInt" : {
+ "type" : "array",
+ "subType" : "record of",
+ "items" : {
+ "type" : "integer"
+ }
+ },
+ "SeqProduct" : {
+ "type" : "object",
+ "subType" : "record",
+ "properties" : {
+ "name" : {
+ "type" : "string",
+ "subType" : "universal charstring"
+ },
+ "price" : {
+ "anyOf" : [
+ {
+ "type" : "number"
+ },
+ {
+ "enum" : [
+ "not_a_number",
+ "infinity",
+ "-infinity"
+ ]
+ }
+ ]
+ },
+ "id" : {
+ "anyOf" : [
+ {
+ "type" : "null"
+ },
+ {
+ "type" : "string",
+ "subType" : "octetstring",
+ "pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
+ }
+ ],
+ "omitAsNull" : false
+ },
+ "available" : {
+ "type" : "boolean"
+ }
+ },
+ "additionalProperties" : false,
+ "fieldOrder" : [
+ "name",
+ "price",
+ "id",
+ "available"
+ ],
+ "required" : [
+ "name",
+ "price",
+ "available"
+ ]
+ },
+ "Number" : {
+ "anyOf" : [
+ {
+ "type" : "object",
+ "properties" : {
+ "decimal" : {
+ "type" : "integer"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "decimal"
+ ]
+ },
+ {
+ "type" : "object",
+ "properties" : {
+ "binary" : {
+ "type" : "string",
+ "subType" : "bitstring",
+ "pattern" : "^[01]*$"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "binary"
+ ]
+ },
+ {
+ "type" : "object",
+ "properties" : {
+ "hexadecimal" : {
+ "type" : "string",
+ "subType" : "octetstring",
+ "pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "hexadecimal"
+ ]
+ }
+ ]
+ },
"AnyString" : {
"anyOf" : [
{
}
]
},
- "Big_Choice" : {
- "anyOf" : [
- {
- "type" : "object",
- "properties" : {
- "numbers" : {
- "type" : "array",
- "subType" : "set of",
- "items" : {
- "$ref" : "#/definitions/Zero/Number"
- }
- }
- },
- "additionalProperties" : false,
- "required" : [
- "numbers"
- ]
- },
- {
- "type" : "object",
- "properties" : {
- "strings" : {
- "$ref" : "#/definitions/Zero/ManyStrings"
- }
- },
- "additionalProperties" : false,
- "required" : [
- "strings"
- ]
- }
- ]
+ "ManyStrings" : {
+ "type" : "array",
+ "subType" : "record of",
+ "items" : {
+ "$ref" : "#/definitions/Zero/AnyString"
+ }
},
"Big_Set" : {
"type" : "object",
"blue",
"green",
"yellow"
+ ],
+ "numericValues" : [
+ 0,
+ 1,
+ 2,
+ 3
]
}
},
"color"
]
},
- "ManyStrings" : {
- "type" : "array",
- "subType" : "record of",
- "items" : {
- "$ref" : "#/definitions/Zero/AnyString"
- }
- },
- "Number" : {
+ "Big_Choice" : {
"anyOf" : [
{
"type" : "object",
"properties" : {
- "decimal" : {
- "type" : "integer"
- }
- },
- "additionalProperties" : false,
- "required" : [
- "decimal"
- ]
- },
- {
- "type" : "object",
- "properties" : {
- "binary" : {
- "type" : "string",
- "pattern" : "^[01]*$"
+ "numbers" : {
+ "type" : "array",
+ "subType" : "set of",
+ "items" : {
+ "$ref" : "#/definitions/Zero/Number"
+ }
}
},
"additionalProperties" : false,
"required" : [
- "binary"
+ "numbers"
]
},
{
"type" : "object",
"properties" : {
- "hexadecimal" : {
- "type" : "string",
- "pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
+ "strings" : {
+ "$ref" : "#/definitions/Zero/ManyStrings"
}
},
"additionalProperties" : false,
"required" : [
- "hexadecimal"
+ "strings"
]
}
]
},
+ "Season" : {
+ "enum" : [
+ "spring",
+ "summer",
+ "fall",
+ "winter"
+ ],
+ "numericValues" : [
+ 1,
+ 2,
+ 3,
+ 4
+ ]
+ },
"SelectionType" : {
"type" : "array",
"subType" : "set of",
"$ref" : "#/definitions/Zero/Number"
}
},
- "SeqOfInt" : {
- "type" : "array",
- "subType" : "record of",
- "items" : {
- "type" : "integer"
- }
+ "NullType" : {
+ "type" : "null"
},
- "SeqProduct" : {
- "type" : "object",
- "subType" : "record",
- "properties" : {
- "name" : {
- "type" : "string",
- "subType" : "universal charstring"
- },
- "price" : {
- "anyOf" : [
- {
- "type" : "number"
- },
- {
- "enum" : [
- "not_a_number",
- "infinity",
- "-infinity"
- ]
- }
- ]
- },
- "id" : {
- "anyOf" : [
- {
- "type" : "null"
- },
- {
- "type" : "string",
- "pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
- }
- ],
- "omitAsNull" : false
- },
- "available" : {
- "type" : "boolean"
- }
- },
- "additionalProperties" : false,
- "fieldOrder" : [
- "name",
- "price",
- "id",
- "available"
- ],
- "required" : [
- "name",
- "price",
- "available"
- ]
+ "ObjIdType" : {
+ "type" : "string",
+ "subType" : "objid",
+ "pattern" : "^[0-2][.][1-3]?[0-9]([.][0-9]|([1-9][0-9]+))*$"
+ },
+ "RelObjIdType" : {
+ "type" : "string",
+ "subType" : "objid",
+ "pattern" : "^[0-2][.][1-3]?[0-9]([.][0-9]|([1-9][0-9]+))*$"
}
}
},
--- /dev/null
+{
+ "definitions" : {
+ "one" : {
+ "HasAny" : {
+ "type" : "object",
+ "subType" : "record",
+ "properties" : {
+ "num" : {
+ "type" : "integer"
+ },
+ "at" : {
+ "$ref" : "#/definitions/one/anytype"
+ }
+ },
+ "additionalProperties" : false,
+ "fieldOrder" : [
+ "num",
+ "at"
+ ],
+ "required" : [
+ "num",
+ "at"
+ ]
+ },
+ "Height" : {
+ "enum" : [
+ "Short",
+ "Medium",
+ "Tall"
+ ],
+ "numericValues" : [
+ 0,
+ 1,
+ 2
+ ]
+ },
+ "Rec" : {
+ "type" : "object",
+ "subType" : "record",
+ "properties" : {
+ "num" : {
+ "type" : "integer",
+ "default" : 0
+ },
+ "str" : {
+ "type" : "string",
+ "subType" : "universal charstring",
+ "default" : "empty"
+ }
+ },
+ "additionalProperties" : false,
+ "fieldOrder" : [
+ "num",
+ "str"
+ ],
+ "required" : [
+ "num",
+ "str"
+ ]
+ },
+ "Set" : {
+ "type" : "object",
+ "subType" : "set",
+ "properties" : {
+ "os" : {
+ "type" : "string",
+ "subType" : "octetstring",
+ "pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
+ },
+ "buul" : {
+ "anyOf" : [
+ {
+ "type" : "null"
+ },
+ {
+ "type" : "boolean"
+ }
+ ],
+ "omitAsNull" : true
+ },
+ "verd" : {
+ "anyOf" : [
+ {
+ "type" : "null"
+ },
+ {
+ "enum" : [
+ "none",
+ "pass",
+ "inconc",
+ "fail",
+ "error"
+ ]
+ }
+ ],
+ "omitAsNull" : false
+ },
+ "numbr" : {
+ "anyOf" : [
+ {
+ "type" : "number"
+ },
+ {
+ "enum" : [
+ "not_a_number",
+ "infinity",
+ "-infinity"
+ ]
+ }
+ ],
+ "default" : "-infinity"
+ }
+ },
+ "additionalProperties" : false,
+ "fieldOrder" : [
+ "os",
+ "buul",
+ "verd",
+ "numbr"
+ ],
+ "required" : [
+ "os",
+ "numbr"
+ ]
+ },
+ "Uni" : {
+ "anyOf" : [
+ {
+ "type" : "object",
+ "properties" : {
+ "numbr" : {
+ "anyOf" : [
+ {
+ "type" : "number"
+ },
+ {
+ "enum" : [
+ "not_a_number",
+ "infinity",
+ "-infinity"
+ ]
+ }
+ ]
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "numbr"
+ ]
+ },
+ {
+ "type" : "object",
+ "properties" : {
+ "bytes" : {
+ "type" : "string",
+ "subType" : "octetstring",
+ "pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "bytes"
+ ]
+ }
+ ]
+ },
+ "Width" : {
+ "enum" : [
+ "Thin",
+ "Medium",
+ "Wide"
+ ],
+ "numericValues" : [
+ 0,
+ 1,
+ 2
+ ]
+ },
+ "anytype" : {
+ "anyOf" : [
+ {
+ "type" : "object",
+ "properties" : {
+ "integer" : {
+ "type" : "integer"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "integer"
+ ]
+ },
+ {
+ "type" : "object",
+ "properties" : {
+ "boolean" : {
+ "type" : "boolean"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "boolean"
+ ]
+ },
+ {
+ "type" : "object",
+ "properties" : {
+ "bitstring" : {
+ "type" : "string",
+ "subType" : "bitstring",
+ "pattern" : "^[01]*$"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "bitstring"
+ ]
+ }
+ ]
+ }
+ },
+ "two" : {
+ "Ints" : {
+ "type" : "array",
+ "subType" : "record of",
+ "items" : {
+ "type" : "integer"
+ }
+ },
+ "PosInt" : {
+ "type" : "integer"
+ }
+ },
+ "three" : {
+ "Barrels" : {
+ "type" : "object",
+ "subType" : "set",
+ "properties" : {
+ "numBarrels" : {
+ "type" : "integer"
+ },
+ "barrelType" : {
+ "type" : "object",
+ "subType" : "record",
+ "properties" : {
+ "size" : {
+ "enum" : [
+ "Small",
+ "Medium",
+ "Large"
+ ],
+ "numericValues" : [
+ 0,
+ 1,
+ 2
+ ]
+ },
+ "filled" : {
+ "type" : "boolean"
+ }
+ },
+ "additionalProperties" : false,
+ "fieldOrder" : [
+ "size",
+ "filled"
+ ],
+ "required" : [
+ "size",
+ "filled"
+ ]
+ }
+ },
+ "additionalProperties" : false,
+ "fieldOrder" : [
+ "numBarrels",
+ "barrelType"
+ ],
+ "required" : [
+ "numBarrels",
+ "barrelType"
+ ]
+ },
+ "Nums" : {
+ "type" : "array",
+ "subType" : "set of",
+ "items" : {
+ "type" : "object",
+ "subType" : "record",
+ "properties" : {
+ "number" : {
+ "originalName" : "num",
+ "type" : "integer"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "number"
+ ]
+ }
+ },
+ "Numz" : {
+ "type" : "object",
+ "subType" : "record",
+ "properties" : {
+ "nums" : {
+ "$ref" : "#/definitions/three/Nums"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "nums"
+ ]
+ },
+ "Rex" : {
+ "type" : "array",
+ "subType" : "record of",
+ "items" : {
+ "$ref" : "#/definitions/one/Rec"
+ }
+ },
+ "Stuff" : {
+ "type" : "array",
+ "subType" : "record of",
+ "items" : {
+ "$ref" : "#/definitions/three/Thing"
+ }
+ },
+ "Thing" : {
+ "anyOf" : [
+ {
+ "originalName" : "b",
+ "type" : "boolean"
+ },
+ {
+ "originalName" : "i",
+ "unusedAlias" : "int",
+ "type" : "integer"
+ },
+ {
+ "originalName" : "cs",
+ "unusedAlias" : "str",
+ "type" : "string",
+ "subType" : "charstring"
+ },
+ {
+ "originalName" : "rec",
+ "type" : "object",
+ "subType" : "record",
+ "properties" : {
+ "num" : {
+ "type" : "integer"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "num"
+ ]
+ }
+ ]
+ }
+ },
+ "Zero" : {
+ "AnyString" : {
+ "anyOf" : [
+ {
+ "type" : "object",
+ "properties" : {
+ "generalstr" : {
+ "type" : "string",
+ "subType" : "universal charstring"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "generalstr"
+ ]
+ },
+ {
+ "type" : "object",
+ "properties" : {
+ "numericstr" : {
+ "type" : "string",
+ "subType" : "charstring"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "numericstr"
+ ]
+ },
+ {
+ "type" : "object",
+ "properties" : {
+ "utf8str" : {
+ "type" : "string",
+ "subType" : "universal charstring"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "utf8str"
+ ]
+ },
+ {
+ "type" : "object",
+ "properties" : {
+ "printablestr" : {
+ "type" : "string",
+ "subType" : "charstring"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "printablestr"
+ ]
+ },
+ {
+ "type" : "object",
+ "properties" : {
+ "universalstr" : {
+ "type" : "string",
+ "subType" : "universal charstring"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "universalstr"
+ ]
+ },
+ {
+ "type" : "object",
+ "properties" : {
+ "bmpstr" : {
+ "type" : "string",
+ "subType" : "universal charstring"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "bmpstr"
+ ]
+ },
+ {
+ "type" : "object",
+ "properties" : {
+ "graphicstr" : {
+ "type" : "string",
+ "subType" : "universal charstring"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "graphicstr"
+ ]
+ },
+ {
+ "type" : "object",
+ "properties" : {
+ "ia5str" : {
+ "type" : "string",
+ "subType" : "charstring"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "ia5str"
+ ]
+ },
+ {
+ "type" : "object",
+ "properties" : {
+ "teletexstr" : {
+ "type" : "string",
+ "subType" : "universal charstring"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "teletexstr"
+ ]
+ },
+ {
+ "type" : "object",
+ "properties" : {
+ "videotexstr" : {
+ "type" : "string",
+ "subType" : "universal charstring"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "videotexstr"
+ ]
+ },
+ {
+ "type" : "object",
+ "properties" : {
+ "visiblestr" : {
+ "type" : "string",
+ "subType" : "charstring"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "visiblestr"
+ ]
+ }
+ ]
+ },
+ "Big_Choice" : {
+ "anyOf" : [
+ {
+ "type" : "object",
+ "properties" : {
+ "numbers" : {
+ "type" : "array",
+ "subType" : "set of",
+ "items" : {
+ "$ref" : "#/definitions/Zero/Number"
+ }
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "numbers"
+ ]
+ },
+ {
+ "type" : "object",
+ "properties" : {
+ "strings" : {
+ "$ref" : "#/definitions/Zero/ManyStrings"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "strings"
+ ]
+ }
+ ]
+ },
+ "Big_Set" : {
+ "type" : "object",
+ "subType" : "set",
+ "properties" : {
+ "product" : {
+ "$ref" : "#/definitions/Zero/SeqProduct"
+ },
+ "numbers" : {
+ "type" : "array",
+ "subType" : "set of",
+ "items" : {
+ "$ref" : "#/definitions/Zero/Number"
+ }
+ },
+ "strings" : {
+ "$ref" : "#/definitions/Zero/ManyStrings"
+ },
+ "color" : {
+ "enum" : [
+ "red",
+ "blue",
+ "green",
+ "yellow"
+ ],
+ "numericValues" : [
+ 0,
+ 1,
+ 2,
+ 3
+ ]
+ }
+ },
+ "additionalProperties" : false,
+ "fieldOrder" : [
+ "product",
+ "numbers",
+ "strings",
+ "color"
+ ],
+ "required" : [
+ "product",
+ "numbers",
+ "strings",
+ "color"
+ ]
+ },
+ "ManyStrings" : {
+ "type" : "array",
+ "subType" : "record of",
+ "items" : {
+ "$ref" : "#/definitions/Zero/AnyString"
+ }
+ },
+ "NullType" : {
+ "type" : "null"
+ },
+ "Number" : {
+ "anyOf" : [
+ {
+ "type" : "object",
+ "properties" : {
+ "decimal" : {
+ "type" : "integer"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "decimal"
+ ]
+ },
+ {
+ "type" : "object",
+ "properties" : {
+ "binary" : {
+ "type" : "string",
+ "subType" : "bitstring",
+ "pattern" : "^[01]*$"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "binary"
+ ]
+ },
+ {
+ "type" : "object",
+ "properties" : {
+ "hexadecimal" : {
+ "type" : "string",
+ "subType" : "octetstring",
+ "pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "hexadecimal"
+ ]
+ }
+ ]
+ },
+ "ObjIdType" : {
+ "type" : "string",
+ "subType" : "objid",
+ "pattern" : "^[0-2][.][1-3]?[0-9]([.][0-9]|([1-9][0-9]+))*$"
+ },
+ "RelObjIdType" : {
+ "type" : "string",
+ "subType" : "objid",
+ "pattern" : "^[0-2][.][1-3]?[0-9]([.][0-9]|([1-9][0-9]+))*$"
+ },
+ "Season" : {
+ "enum" : [
+ "spring",
+ "summer",
+ "fall",
+ "winter"
+ ],
+ "numericValues" : [
+ 1,
+ 2,
+ 3,
+ 4
+ ]
+ },
+ "SelectionType" : {
+ "type" : "array",
+ "subType" : "set of",
+ "items" : {
+ "$ref" : "#/definitions/Zero/Number"
+ }
+ },
+ "SeqOfInt" : {
+ "type" : "array",
+ "subType" : "record of",
+ "items" : {
+ "type" : "integer"
+ }
+ },
+ "SeqProduct" : {
+ "type" : "object",
+ "subType" : "record",
+ "properties" : {
+ "name" : {
+ "type" : "string",
+ "subType" : "universal charstring"
+ },
+ "price" : {
+ "anyOf" : [
+ {
+ "type" : "number"
+ },
+ {
+ "enum" : [
+ "not_a_number",
+ "infinity",
+ "-infinity"
+ ]
+ }
+ ]
+ },
+ "id" : {
+ "anyOf" : [
+ {
+ "type" : "null"
+ },
+ {
+ "type" : "string",
+ "subType" : "octetstring",
+ "pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
+ }
+ ],
+ "omitAsNull" : false
+ },
+ "available" : {
+ "type" : "boolean"
+ }
+ },
+ "additionalProperties" : false,
+ "fieldOrder" : [
+ "name",
+ "price",
+ "id",
+ "available"
+ ],
+ "required" : [
+ "name",
+ "price",
+ "available"
+ ]
+ }
+ }
+ },
+ "anyOf" : [
+ {
+ "$ref" : "#/definitions/two/Ints",
+ "decoding" : {
+ "prototype" : [
+ "fast",
+ "f_dec_ints",
+ "os",
+ "x"
+ ]
+ },
+ "encoding" : {
+ "prototype" : [
+ "fast",
+ "f_enc_ints",
+ "eents",
+ "octus"
+ ],
+ "printing" : "pretty"
+ }
+ },
+ {
+ "$ref" : "#/definitions/one/Rec",
+ "decoding" : {
+ "prototype" : [
+ "convert",
+ "f_dec_rec",
+ "octie"
+ ],
+ "errorBehavior" : {
+ "ALL" : "WARNING",
+ "INVAL_MSG" : "ERROR"
+ }
+ },
+ "encoding" : {
+ "prototype" : [
+ "convert",
+ "f_enc_rec",
+ "x"
+ ]
+ }
+ },
+ {
+ "$ref" : "#/definitions/one/Set"
+ },
+ {
+ "$ref" : "#/definitions/one/Uni"
+ },
+ {
+ "$ref" : "#/definitions/one/HasAny"
+ },
+ {
+ "$ref" : "#/definitions/one/Height"
+ },
+ {
+ "$ref" : "#/definitions/one/Width"
+ },
+ {
+ "$ref" : "#/definitions/one/anytype"
+ },
+ {
+ "$ref" : "#/definitions/three/Thing"
+ },
+ {
+ "$ref" : "#/definitions/three/Stuff"
+ },
+ {
+ "$ref" : "#/definitions/three/Barrels"
+ },
+ {
+ "$ref" : "#/definitions/two/PosInt"
+ },
+ {
+ "$ref" : "#/definitions/Zero/SeqOfInt"
+ },
+ {
+ "$ref" : "#/definitions/Zero/SeqProduct"
+ },
+ {
+ "$ref" : "#/definitions/Zero/Number"
+ },
+ {
+ "$ref" : "#/definitions/three/Nums"
+ },
+ {
+ "$ref" : "#/definitions/three/Numz"
+ },
+ {
+ "$ref" : "#/definitions/three/Rex"
+ },
+ {
+ "$ref" : "#/definitions/Zero/AnyString"
+ },
+ {
+ "$ref" : "#/definitions/Zero/ManyStrings"
+ },
+ {
+ "$ref" : "#/definitions/Zero/Big_Set",
+ "decoding" : {
+ "prototype" : [
+ "convert",
+ "f_dec_bigset",
+ "os"
+ ]
+ },
+ "encoding" : {
+ "prototype" : [
+ "convert",
+ "f_enc_bigset",
+ "x"
+ ]
+ }
+ },
+ {
+ "$ref" : "#/definitions/Zero/Big_Choice"
+ },
+ {
+ "$ref" : "#/definitions/Zero/Season"
+ },
+ {
+ "$ref" : "#/definitions/Zero/SelectionType"
+ },
+ {
+ "$ref" : "#/definitions/Zero/NullType"
+ },
+ {
+ "$ref" : "#/definitions/Zero/ObjIdType"
+ },
+ {
+ "$ref" : "#/definitions/Zero/RelObjIdType"
+ }
+ ]
+}
******************************************************************************/
module two {
- type record of integer Ints;
+ type record of integer Ints with { encode "JSON" };
type set of universal charstring Strings;
//type record of integer Rec;
-} with { encode "JSON" }
+}
--- /dev/null
+{
+ "definitions" : {
+ "one" : {
+ "HasAny" : {
+ "type" : "object",
+ "subType" : "record",
+ "properties" : {
+ "num" : {
+ "type" : "integer"
+ },
+ "at" : {
+ "$ref" : "#/definitions/one/anytype"
+ }
+ },
+ "additionalProperties" : false,
+ "fieldOrder" : [
+ "num",
+ "at"
+ ],
+ "required" : [
+ "num",
+ "at"
+ ]
+ },
+ "Height" : {
+ "enum" : [
+ "Short",
+ "Medium",
+ "Tall"
+ ],
+ "numericValues" : [
+ 0,
+ 1,
+ 2
+ ]
+ },
+ "Rec" : {
+ "type" : "object",
+ "subType" : "record",
+ "properties" : {
+ "num" : {
+ "type" : "integer",
+ "default" : 0
+ },
+ "str" : {
+ "type" : "string",
+ "subType" : "universal charstring",
+ "default" : "empty"
+ }
+ },
+ "additionalProperties" : false,
+ "fieldOrder" : [
+ "num",
+ "str"
+ ],
+ "required" : [
+ "num",
+ "str"
+ ]
+ },
+ "Set" : {
+ "type" : "object",
+ "subType" : "set",
+ "properties" : {
+ "os" : {
+ "type" : "string",
+ "subType" : "octetstring",
+ "pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
+ },
+ "buul" : {
+ "anyOf" : [
+ {
+ "type" : "null"
+ },
+ {
+ "type" : "boolean"
+ }
+ ],
+ "omitAsNull" : true
+ },
+ "verd" : {
+ "anyOf" : [
+ {
+ "type" : "null"
+ },
+ {
+ "enum" : [
+ "none",
+ "pass",
+ "inconc",
+ "fail",
+ "error"
+ ]
+ }
+ ],
+ "omitAsNull" : false
+ },
+ "numbr" : {
+ "anyOf" : [
+ {
+ "type" : "number"
+ },
+ {
+ "enum" : [
+ "not_a_number",
+ "infinity",
+ "-infinity"
+ ]
+ }
+ ],
+ "default" : "-infinity"
+ }
+ },
+ "additionalProperties" : false,
+ "fieldOrder" : [
+ "os",
+ "buul",
+ "verd",
+ "numbr"
+ ],
+ "required" : [
+ "os",
+ "numbr"
+ ]
+ },
+ "Uni" : {
+ "anyOf" : [
+ {
+ "type" : "object",
+ "properties" : {
+ "numbr" : {
+ "anyOf" : [
+ {
+ "type" : "number"
+ },
+ {
+ "enum" : [
+ "not_a_number",
+ "infinity",
+ "-infinity"
+ ]
+ }
+ ]
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "numbr"
+ ]
+ },
+ {
+ "type" : "object",
+ "properties" : {
+ "bytes" : {
+ "type" : "string",
+ "subType" : "octetstring",
+ "pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "bytes"
+ ]
+ }
+ ]
+ },
+ "Width" : {
+ "enum" : [
+ "Thin",
+ "Medium",
+ "Wide"
+ ],
+ "numericValues" : [
+ 0,
+ 1,
+ 2
+ ]
+ },
+ "anytype" : {
+ "anyOf" : [
+ {
+ "type" : "object",
+ "properties" : {
+ "integer" : {
+ "type" : "integer"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "integer"
+ ]
+ },
+ {
+ "type" : "object",
+ "properties" : {
+ "boolean" : {
+ "type" : "boolean"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "boolean"
+ ]
+ },
+ {
+ "type" : "object",
+ "properties" : {
+ "bitstring" : {
+ "type" : "string",
+ "subType" : "bitstring",
+ "pattern" : "^[01]*$"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "bitstring"
+ ]
+ }
+ ]
+ }
+ },
+ "two" : {
+ "Ints" : {
+ "type" : "array",
+ "subType" : "record of",
+ "items" : {
+ "type" : "integer"
+ }
+ },
+ "PosInt" : {
+ "type" : "integer"
+ }
+ },
+ "three" : {
+ "Barrels" : {
+ "type" : "object",
+ "subType" : "set",
+ "properties" : {
+ "numBarrels" : {
+ "type" : "integer"
+ },
+ "barrelType" : {
+ "type" : "object",
+ "subType" : "record",
+ "properties" : {
+ "size" : {
+ "enum" : [
+ "Small",
+ "Medium",
+ "Large"
+ ],
+ "numericValues" : [
+ 0,
+ 1,
+ 2
+ ]
+ },
+ "filled" : {
+ "type" : "boolean"
+ }
+ },
+ "additionalProperties" : false,
+ "fieldOrder" : [
+ "size",
+ "filled"
+ ],
+ "required" : [
+ "size",
+ "filled"
+ ]
+ }
+ },
+ "additionalProperties" : false,
+ "fieldOrder" : [
+ "numBarrels",
+ "barrelType"
+ ],
+ "required" : [
+ "numBarrels",
+ "barrelType"
+ ]
+ },
+ "Nums" : {
+ "type" : "array",
+ "subType" : "set of",
+ "items" : {
+ "type" : "object",
+ "subType" : "record",
+ "properties" : {
+ "number" : {
+ "originalName" : "num",
+ "type" : "integer"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "number"
+ ]
+ }
+ },
+ "Numz" : {
+ "type" : "object",
+ "subType" : "record",
+ "properties" : {
+ "nums" : {
+ "$ref" : "#/definitions/three/Nums"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "nums"
+ ]
+ },
+ "Rex" : {
+ "type" : "array",
+ "subType" : "record of",
+ "items" : {
+ "$ref" : "#/definitions/one/Rec"
+ }
+ },
+ "Stuff" : {
+ "type" : "array",
+ "subType" : "record of",
+ "items" : {
+ "$ref" : "#/definitions/three/Thing"
+ }
+ },
+ "Thing" : {
+ "anyOf" : [
+ {
+ "originalName" : "b",
+ "type" : "boolean"
+ },
+ {
+ "originalName" : "i",
+ "unusedAlias" : "int",
+ "type" : "integer"
+ },
+ {
+ "originalName" : "cs",
+ "unusedAlias" : "str",
+ "type" : "string",
+ "subType" : "charstring"
+ },
+ {
+ "originalName" : "rec",
+ "type" : "object",
+ "subType" : "record",
+ "properties" : {
+ "num" : {
+ "type" : "integer"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "num"
+ ]
+ }
+ ]
+ }
+ },
+ "Zero" : {
+ "AnyString" : {
+ "anyOf" : [
+ {
+ "type" : "object",
+ "properties" : {
+ "generalstr" : {
+ "type" : "string",
+ "subType" : "universal charstring"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "generalstr"
+ ]
+ },
+ {
+ "type" : "object",
+ "properties" : {
+ "numericstr" : {
+ "type" : "string",
+ "subType" : "charstring"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "numericstr"
+ ]
+ },
+ {
+ "type" : "object",
+ "properties" : {
+ "utf8str" : {
+ "type" : "string",
+ "subType" : "universal charstring"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "utf8str"
+ ]
+ },
+ {
+ "type" : "object",
+ "properties" : {
+ "printablestr" : {
+ "type" : "string",
+ "subType" : "charstring"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "printablestr"
+ ]
+ },
+ {
+ "type" : "object",
+ "properties" : {
+ "universalstr" : {
+ "type" : "string",
+ "subType" : "universal charstring"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "universalstr"
+ ]
+ },
+ {
+ "type" : "object",
+ "properties" : {
+ "bmpstr" : {
+ "type" : "string",
+ "subType" : "universal charstring"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "bmpstr"
+ ]
+ },
+ {
+ "type" : "object",
+ "properties" : {
+ "graphicstr" : {
+ "type" : "string",
+ "subType" : "universal charstring"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "graphicstr"
+ ]
+ },
+ {
+ "type" : "object",
+ "properties" : {
+ "ia5str" : {
+ "type" : "string",
+ "subType" : "charstring"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "ia5str"
+ ]
+ },
+ {
+ "type" : "object",
+ "properties" : {
+ "teletexstr" : {
+ "type" : "string",
+ "subType" : "universal charstring"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "teletexstr"
+ ]
+ },
+ {
+ "type" : "object",
+ "properties" : {
+ "videotexstr" : {
+ "type" : "string",
+ "subType" : "universal charstring"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "videotexstr"
+ ]
+ },
+ {
+ "type" : "object",
+ "properties" : {
+ "visiblestr" : {
+ "type" : "string",
+ "subType" : "charstring"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "visiblestr"
+ ]
+ }
+ ]
+ },
+ "Big_Choice" : {
+ "anyOf" : [
+ {
+ "type" : "object",
+ "properties" : {
+ "numbers" : {
+ "type" : "array",
+ "subType" : "set of",
+ "items" : {
+ "$ref" : "#/definitions/Zero/Number"
+ }
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "numbers"
+ ]
+ },
+ {
+ "type" : "object",
+ "properties" : {
+ "strings" : {
+ "$ref" : "#/definitions/Zero/ManyStrings"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "strings"
+ ]
+ }
+ ]
+ },
+ "Big_Set" : {
+ "type" : "object",
+ "subType" : "set",
+ "properties" : {
+ "product" : {
+ "$ref" : "#/definitions/Zero/SeqProduct"
+ },
+ "numbers" : {
+ "type" : "array",
+ "subType" : "set of",
+ "items" : {
+ "$ref" : "#/definitions/Zero/Number"
+ }
+ },
+ "strings" : {
+ "$ref" : "#/definitions/Zero/ManyStrings"
+ },
+ "color" : {
+ "enum" : [
+ "red",
+ "blue",
+ "green",
+ "yellow"
+ ],
+ "numericValues" : [
+ 0,
+ 1,
+ 2,
+ 3
+ ]
+ }
+ },
+ "additionalProperties" : false,
+ "fieldOrder" : [
+ "product",
+ "numbers",
+ "strings",
+ "color"
+ ],
+ "required" : [
+ "product",
+ "numbers",
+ "strings",
+ "color"
+ ]
+ },
+ "ManyStrings" : {
+ "type" : "array",
+ "subType" : "record of",
+ "items" : {
+ "$ref" : "#/definitions/Zero/AnyString"
+ }
+ },
+ "NullType" : {
+ "type" : "null"
+ },
+ "Number" : {
+ "anyOf" : [
+ {
+ "type" : "object",
+ "properties" : {
+ "decimal" : {
+ "type" : "integer"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "decimal"
+ ]
+ },
+ {
+ "type" : "object",
+ "properties" : {
+ "binary" : {
+ "type" : "string",
+ "subType" : "bitstring",
+ "pattern" : "^[01]*$"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "binary"
+ ]
+ },
+ {
+ "type" : "object",
+ "properties" : {
+ "hexadecimal" : {
+ "type" : "string",
+ "subType" : "octetstring",
+ "pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
+ }
+ },
+ "additionalProperties" : false,
+ "required" : [
+ "hexadecimal"
+ ]
+ }
+ ]
+ },
+ "ObjIdType" : {
+ "type" : "string",
+ "subType" : "objid",
+ "pattern" : "^[0-2][.][1-3]?[0-9]([.][0-9]|([1-9][0-9]+))*$"
+ },
+ "RelObjIdType" : {
+ "type" : "string",
+ "subType" : "objid",
+ "pattern" : "^[0-2][.][1-3]?[0-9]([.][0-9]|([1-9][0-9]+))*$"
+ },
+ "Season" : {
+ "enum" : [
+ "spring",
+ "summer",
+ "fall",
+ "winter"
+ ],
+ "numericValues" : [
+ 1,
+ 2,
+ 3,
+ 4
+ ]
+ },
+ "SelectionType" : {
+ "type" : "array",
+ "subType" : "set of",
+ "items" : {
+ "$ref" : "#/definitions/Zero/Number"
+ }
+ },
+ "SeqOfInt" : {
+ "type" : "array",
+ "subType" : "record of",
+ "items" : {
+ "type" : "integer"
+ }
+ },
+ "SeqProduct" : {
+ "type" : "object",
+ "subType" : "record",
+ "properties" : {
+ "name" : {
+ "type" : "string",
+ "subType" : "universal charstring"
+ },
+ "price" : {
+ "anyOf" : [
+ {
+ "type" : "number"
+ },
+ {
+ "enum" : [
+ "not_a_number",
+ "infinity",
+ "-infinity"
+ ]
+ }
+ ]
+ },
+ "id" : {
+ "anyOf" : [
+ {
+ "type" : "null"
+ },
+ {
+ "type" : "string",
+ "subType" : "octetstring",
+ "pattern" : "^([0-9A-Fa-f][0-9A-Fa-f])*$"
+ }
+ ],
+ "omitAsNull" : false
+ },
+ "available" : {
+ "type" : "boolean"
+ }
+ },
+ "additionalProperties" : false,
+ "fieldOrder" : [
+ "name",
+ "price",
+ "id",
+ "available"
+ ],
+ "required" : [
+ "name",
+ "price",
+ "available"
+ ]
+ }
+ }
+ },
+ "anyOf" : [
+ {
+ "$ref" : "#/definitions/two/Ints",
+ "decoding" : {
+ "prototype" : [
+ "fast",
+ "f_dec_ints",
+ "os",
+ "x"
+ ]
+ },
+ "encoding" : {
+ "prototype" : [
+ "fast",
+ "f_enc_ints",
+ "eents",
+ "octus"
+ ],
+ "printing" : "pretty"
+ }
+ },
+ {
+ "$ref" : "#/definitions/one/Rec",
+ "decoding" : {
+ "prototype" : [
+ "convert",
+ "f_dec_rec",
+ "octie"
+ ],
+ "errorBehavior" : {
+ "ALL" : "WARNING",
+ "INVAL_MSG" : "ERROR"
+ }
+ },
+ "encoding" : {
+ "prototype" : [
+ "convert",
+ "f_enc_rec",
+ "x"
+ ]
+ }
+ },
+ {
+ "$ref" : "#/definitions/Zero/Big_Set",
+ "decoding" : {
+ "prototype" : [
+ "convert",
+ "f_dec_bigset",
+ "os"
+ ]
+ },
+ "encoding" : {
+ "prototype" : [
+ "convert",
+ "f_enc_bigset",
+ "x"
+ ]
+ }
+ }
+ ]
+}
strings ManyStrings
}
+Season ::= ENUMERATED {
+ spring (1), summer (2), fall (3), winter (4)
+}
+
SelectionType ::= numbers < Big-Choice
--- non-encodable types
NullType ::= NULL
ObjIdType ::= OBJECT IDENTIFIER
RelObjIdType ::= RELATIVE-OID
+-- non-encodable types
+
EmbPdvType ::= EMBEDDED PDV
ExtType ::= EXTERNAL
.SUFFIXES: .tex .labels .dvi .ps .pdf
+DOC2PDF_JAR := ../../titan_playground/jar/doc2pdf.jar
+WARNING_TXT := warning.txt
TITAN_DOCS := apiguide.doc userguide.doc installationguide.doc referenceguide.doc releasenotes.doc
-
TITAN_PDFS := $(TITAN_DOCS:.doc=.pdf)
ifeq ($(GEN_PDF), yes)
-install: $(TITAN_PDFS)
+# Install with error handling: Tries to create PDFs and copy the available documents to $(DOCDIR).
+# On success (PDF files are successfully created), the PDF files are copied to the $(DOCDIR) directory.
+# On failure (if doc2pdf.jar is not available or install_pdf exits with error, so PDFs are not created), the DOC files are copied to the $(DOCDIR) directory instead of the PDF files.
+install:
+ { make test_doc2pdf_jar && make install_pdf; } || make install_error_handling
+
+# Checks if $(DOC2PDF_JAR) is present, and exit with error if not.
+test_doc2pdf_jar:
+ @{ test -f $(DOC2PDF_JAR) && echo "$(DOC2PDF_JAR) is present .. OK"; } || { echo "ERROR: $(DOC2PDF_JAR) is missing" && false; };
+
+# Install PDFs normal case: PDFs are created and copied to the $(DOCDIR) directory.
+# PDF creation may fail if doc2pdf.jar fails, which can happen for example if the server, that converts from DOC to PDF, is not available. In this case the target exits with error.
+install_pdf: $(TITAN_PDFS)
ifdef MINGW
$(info Skipped ${CURDIR} for MinGW)
else
cp $(TITAN_PDFS) $(DOCDIR)
endif
+# Copies DOC files to $(DOCDIR) instead of the PDF files, because PDF creation failed. Also a $(WARNING_TXT) is created
+install_error_handling:
+ @echo "Error handling: DOC files are copied to $(DOCDIR) instead of PDF files"
+ifdef MINGW
+$(info Skipped ${CURDIR} for MinGW)
+else
+ mkdir -p $(DOCDIR)
+ cp $(TITAN_DOCS) $(DOCDIR)
+ @echo "Creating $(WARNING_TXT)"
+ @echo "DOC files are copied to $(DOCDIR) instead of PDF files." >$(WARNING_TXT)
+ @echo "It is because $(DOC2PDF_JAR) is missing or failed, which can happen for example if the server, that converts from DOC to PDF, is not available." >>$(WARNING_TXT)
+ cp $(WARNING_TXT) $(DOCDIR)
+endif
+
+# Converts DOC to PDF
+# $@ : target name, for example: apiguide.pdf
+# $(basename $@) : target name without extension, for example: apiguide
%.pdf : %.doc
- @for doc in $(TITAN_DOCS:.doc=); do \
- java -jar ../../titan_playground/jar/doc2pdf.jar $(addsuffix .doc, $$doc) $(addsuffix .pdf, $$doc) || exit; \
- done
+ @java -jar $(DOC2PDF_JAR) $(basename $@).doc $@ || { echo "ERROR: doc2pdf.jar failed with $(basename $@).doc" && false; }
else
+# GEN_PDF == no
install:
endif
distclean:clean
dep:
+