-///////////////////////////////////////////////////////////////////////////////
-// 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
-///////////////////////////////////////////////////////////////////////////////
+/******************************************************************************
+ * Copyright (c) 2000-2016 Ericsson Telecom AB
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *
+ * Baji, Laszlo
+ * Balasko, Jeno
+ * Baranyi, Botond
+ * Beres, Szabolcs
+ * Cserveni, Akos
+ * Czerman, Oliver
+ * Delic, Adam
+ * Feher, Csaba
+ * Forstner, Matyas
+ * Gecse, Roland
+ * Kovacs, Ferenc
+ * Raduly, Csaba
+ * Szabados, Kristof
+ * Szabo, Janos Zoltan – initial implementation
+ * Szalai, Gabor
+ * Zalanyi, Balazs Andor
+ * Pandi, Krisztian
+ *
+ ******************************************************************************/
#include <set>
#include <string>
#include <sstream>
#include "../common/version.h"
#include "CodeGenHelper.hh"
#include <limits.h>
+#include "ttcn3/profiler.h"
reffer::reffer(const char*) {}
// =================================
// ===== Modules
// =================================
+
+ vector<Modules::type_enc_t> Modules::delayed_type_enc_v;
Modules::Modules()
: Node(), mods_v(), mods_m()
mods_v[i]->chk_recursive(checked_modules);
}
checked_modules.clear();
+ // run delayed Type::chk_coding() calls
+ if (!delayed_type_enc_v.empty()) {
+ for (size_t i = 0; i < delayed_type_enc_v.size(); ++i) {
+ delayed_type_enc_v[i]->t->chk_coding(delayed_type_enc_v[i]->enc, true);
+ delete delayed_type_enc_v[i];
+ }
+ delayed_type_enc_v.clear();
+ }
}
void Modules::chk_top_level_pdus()
mods_v[i]->generate_json_schema(json, json_refs);
}
}
+
+ void Modules::delay_type_encode_check(Type* p_type, bool p_encode)
+ {
+ type_enc_t* elem = new type_enc_t;
+ elem->t = p_type;
+ elem->enc = p_encode;
+ delayed_type_enc_v.add(elem);
+ }
// =================================
}
// pre_init function
bool has_pre_init = false;
- if (output->functions.pre_init) {
+ bool profiled = MOD_TTCN == get_moduletype() && is_file_profiled(get_filename());
+ bool debugged = debugger_active && MOD_TTCN == get_moduletype();
+ // always generate pre_init_module if the file is profiled
+ if (output->functions.pre_init || profiled || debugged) {
output->source.static_function_prototypes =
mputstr(output->source.static_function_prototypes,
"static void pre_init_module();\n");
mputprintf(effective_module_functions, "%s\"%s\"",
(effective_module_functions ? ", " : ""), get_modid().get_dispname().c_str());
}
- if (profiler_enabled && MOD_TTCN == get_moduletype()) {
+ if (profiled) {
output->source.static_function_bodies = mputprintf(output->source.static_function_bodies,
+ "%s::init_ttcn3_profiler();\n"
"TTCN3_Stack_Depth stack_depth;\n"
- "ttcn3_prof.enter_function(\"%s\", 0, \"%s\");\n",
- get_filename(), get_modid().get_dispname().c_str());
+ "ttcn3_prof.execute_line(\"%s\", 0);\n", get_modid().get_name().c_str(), get_filename());
+ }
+ if (debugged) {
+ output->source.static_function_bodies = mputprintf(output->source.static_function_bodies,
+ "%s::init_ttcn3_debugger();\n", get_modid().get_name().c_str());
}
}
output->source.static_function_bodies =
mputprintf(effective_module_functions, "%s\"%s\"",
(effective_module_functions ? ", " : ""), get_modid().get_dispname().c_str());
}
- if (profiler_enabled && MOD_TTCN == get_moduletype()) {
+ if (MOD_TTCN == get_moduletype() && is_file_profiled(get_filename())) {
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());
+ "ttcn3_prof.execute_line(\"%s\", 0);\n", get_filename());
}
}
output->source.static_function_bodies =
output->functions.set_param = NULL;
has_set_param = true;
} else has_set_param = false;
+ // get_param function
+ bool has_get_param;
+ if (output->functions.get_param) {
+ output->source.static_function_prototypes = mputstr(output->source.static_function_prototypes,
+ "static Module_Param* get_module_param(Module_Param_Name& param_name);\n");
+ output->source.static_function_bodies = mputstr(output->source.static_function_bodies,
+ "static Module_Param* get_module_param(Module_Param_Name& param_name)\n"
+ "{\n"
+ "const char* const par_name = param_name.get_current_name();\n");
+ output->source.static_function_bodies =
+ mputstr(output->source.static_function_bodies, output->functions.get_param);
+ output->source.static_function_bodies =
+ mputstr(output->source.static_function_bodies, "return NULL;\n"
+ "}\n\n");
+ Free(output->functions.get_param);
+ output->functions.get_param = NULL;
+ has_get_param = true;
+ } else has_get_param = false;
// log_param function
bool has_log_param;
if (output->functions.log_param) {
// All we can do is store NULLs for the unused namespaces.
size_t num_xml_namespaces = namespaces.size();
if (moduletype == MOD_TTCN) { //TODO remove this when ASN.1 gets EXER
- output->source.global_vars = mputprintf(output->source.global_vars,
#ifndef NDEBUG
+ output->source.global_vars = mputprintf(output->source.global_vars,
"// written by %s in " __FILE__ " at %d\n"
-#endif
- "static const size_t num_namespaces = %lu;\n"
-#ifndef NDEBUG
, __FUNCTION__, __LINE__
-#endif
- , (unsigned long)num_xml_namespaces
);
+#endif
+
if (num_xml_namespaces != 0 || (control_ns && control_ns_prefix)) {
- output->source.global_vars = mputstr(output->source.global_vars,
- "static const namespace_t xml_namespaces[num_namespaces+1] = {\n");
+ output->source.global_vars = mputprintf(output->source.global_vars,
+ "static const size_t num_namespaces = %lu;\n"
+ "static const namespace_t xml_namespaces[num_namespaces+1] = {\n"
+ , (unsigned long)num_xml_namespaces
+ );
for (size_t i=0; i < namespaces.size(); ++i) {
if (used_namespaces.has_key(i)) {
output->source.global_vars = mputprintf(output->source.global_vars,
}
string extra_str = extra ? ( string('"') + extra + string('"') ) : string("NULL");
output->source.global_vars = mputprintf(output->source.global_vars,
- ", %uU, %uU, %uU, %uU, %s, %luLU, %s, %s, %s, %s, %s, %s, %s",
+ ", %uU, %uU, %uU, %uU, %s, %luLU, %s, %s, %s, %s, %s, %s, %s, %s",
suffix, release, patch, build, extra_str.c_str(),
(unsigned long)num_xml_namespaces,
((num_xml_namespaces || (control_ns && control_ns_prefix)) ? "xml_namespaces" : "0"),
has_post_init ? "post_init_module" : "NULL",
has_set_param ? "set_module_param" : "NULL",
+ has_get_param ? "get_module_param" : "NULL",
has_log_param ? "log_module_param" : "NULL",
has_init_comp ? "init_comp_type" : "NULL",
has_start ? "start_ptc_function" : "NULL",
FATAL_ERROR("Module::generate_functions(): post_init function in ASN.1 module");
if (has_set_param)
FATAL_ERROR("Module::generate_functions(): set_param function in ASN.1 module");
+ if (has_get_param)
+ FATAL_ERROR("Module::generate_functions(): get_param function in ASN.1 module");
if (has_log_param)
FATAL_ERROR("Module::generate_functions(): log_param function in ASN.1 module");
if (has_init_comp)
// language specific parts (definitions, imports, etc.)
//generate_code_internal(&target); <- needed to pass cgh
generate_code_internal(cgh);
+
+ output_struct* output = cgh.get_current_outputstruct();
// string literals
- generate_literals(cgh.get_current_outputstruct());
+ generate_literals(output);
// module level entry points
- generate_functions(cgh.get_current_outputstruct());
+ generate_functions(output);
// type conversion functions for type compatibility
- generate_conversion_functions(cgh.get_current_outputstruct());
+ generate_conversion_functions(output);
+
+ /* generate the initializer function for the TTCN-3 profiler
+ * (this is done at the end of the code generation, to make sure all code
+ * lines have been added to the profiler database) */
+ if (is_file_profiled(get_filename())) {
+ output->source.global_vars = mputstr(output->source.global_vars,
+ "\n/* Initializing TTCN-3 profiler */\n"
+ "void init_ttcn3_profiler()\n"
+ "{\n");
+ char* function_name = 0;
+ int line_no = -1;
+ while (get_profiler_code_line(get_filename(), &function_name, &line_no)) {
+ output->source.global_vars = mputprintf(output->source.global_vars,
+ " ttcn3_prof.create_line(ttcn3_prof.get_element(\"%s\"), %d);\n",
+ get_filename(), line_no);
+ if (0 != function_name) {
+ output->source.global_vars = mputprintf(output->source.global_vars,
+ " ttcn3_prof.create_function(ttcn3_prof.get_element(\"%s\"), %d, \"%s\");\n",
+ get_filename(), line_no, function_name);
+ }
+ }
+ output->source.global_vars = mputstr(output->source.global_vars, "}\n");
+ }
+ /* TTCN-3 debugger:
+ generate the printing function for the types defined in this module
+ and initialize the debugger with this module's global variables,
+ component types and the components' variables */
+ if (debugger_active) {
+ generate_debugger_functions(output);
+ generate_debugger_init(output);
+ }
}
void Module::dump(unsigned level) const