Add Misc_Helpers.ttcn to centralize TTCN3 shutdown handling

This function can now be called from anywhere to try and safely shutdown
a testcase. It is not optimal as we can't call "all component.stop" from
outside the mtc, but without any proper and orderly shutdown handling of
all our emulation components I believe this is the best we can do.

To use it:

import from Misc_Helpers all;

in your module and then call

Misc_Helpers.f_shutdown(__BFILE__, __LINE__);

You can also pass the function a verdict and a message and it will take care
of calling setverdict, but beware of the following:

While setverdict would accept any number of arguments as log message
and convert them to a log string f_shutdown expects one charstring.
It's possible to use the log2str function to use the log arguments in
setverdict for f_shutdown, for example

setverdict(fail, "Template didn't match: ", tmpl_foo);
would become
Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Template didn't match: ", tmpl_foo));

Change-Id: I84d1aa6732f6b748d2bfdeac8f6309023717f267
diff --git a/library/Misc_Helpers.ttcn b/library/Misc_Helpers.ttcn
new file mode 100644
index 0000000..1ca6491
--- /dev/null
+++ b/library/Misc_Helpers.ttcn
@@ -0,0 +1,28 @@
+module Misc_Helpers {
+
+/* Try to properly shutdown a testcase.
+ * The reliable method to stop a testcase without running into dynamic
+ * testcase errors due to unconnected ports receiving messages is to call
+ * all component.stop before terminating. However, this can only be called
+ * from the mtc! So in case we want to terminate from a component that is not
+ * the mtc we try to do the next best thing which is calling mtc.stop and
+ * hoping for the best.
+ */
+function f_shutdown(charstring file, integer line, verdicttype verdict := none,
+			charstring text := "") {
+	if (verdict != none) {
+		text := file & ":" & int2str(line) & " : " & text
+		setverdict(verdict, text);
+	}
+
+	log("Stopping testcase execution from ", file, ":", line)
+	if (self == mtc) {
+		/* Properly stop all ports before disconnecting them. This avoids
+		 * running into the dynamic testcase error due to messages arriving on
+		 * unconnected ports. */
+		all component.stop;
+	}
+	mtc.stop
+}
+
+}