1 /******************************************************************************
2 * Copyright (c) 2000-2016 Ericsson Telecom AB
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
10 * Baranyi, Botond – initial implementation
12 ******************************************************************************/
14 #include "DebuggerStuff.hh"
17 #include "ttcn3/AST_ttcn3.hh"
18 #include "ttcn3/ArrayDimensions.hh"
22 /** Returns a string, that contains the template parameters of the debugger's
23 * port array or timer array printing function.
25 * Recursive (handles one array dimension per call).
27 * @param p_dims the array's dimensions
28 * @param p_element_type name of the array's element C++ class
29 * @param p_array_type name of the array's C++ class ("PORT_ARRAY" or "TIMER_ARRAY")
30 * @param index the index of the currently handled dimension in \a p_dims
32 string
function_params_for_array_dims(Ttcn::ArrayDimensions
* p_dims
,
33 string p_element_type
,
37 if (index
== p_dims
->get_nof_dims()) {
38 return p_element_type
;
42 ret_val
= p_array_type
+ string("<");
44 ret_val
+= function_params_for_array_dims(p_dims
, p_element_type
, p_array_type
, index
+ 1);
45 Ttcn::ArrayDimension
* dim
= p_dims
->get_dim_byIndex(index
);
46 ret_val
+= string(", ") + Int2string(dim
->get_size()) +
47 string(", ") + Int2string(dim
->get_offset());
49 ret_val
+= string(">");
54 /** Returns a string, that contains the template parameters of the debugger's
55 * value array or template array printing function.
57 * Recursive (handles one array dimension per call).
59 * @param p_type the current type (either an array or the array element)
60 * @param p_scope the current scope
61 * @param p_templ indicates whether it's a template array or value array
62 * @param p_first indicates whether this is the first call or a recursive call
64 string
function_params_for_array_type(Type
* p_type
,
70 if (p_type
->get_typetype() != Type::T_ARRAY
) {
71 ret_val
= p_type
->get_genname_value(p_scope
);
73 ret_val
+= "_template";
79 ret_val
= "TEMPLATE_ARRAY<";
82 ret_val
= "VALUE_ARRAY<";
85 Type
* elem_type
= p_type
->get_ofType()->get_type_refd_last();
87 ret_val
+= function_params_for_array_type(elem_type
, p_scope
, false, false) +
88 ", " + function_params_for_array_type(elem_type
, p_scope
, true, false);
91 ret_val
+= function_params_for_array_type(elem_type
, p_scope
, false, false);
93 Ttcn::ArrayDimension
* dim
= p_type
->get_dimension();
94 ret_val
+= string(", ") + Int2string(dim
->get_size()) +
95 string(", ") + Int2string(dim
->get_offset());
97 ret_val
+= string(">");
103 /** Appends the string representations of the specified array dimensions. */
104 string
array_dimensions_to_string(Ttcn::ArrayDimensions
* p_dims
)
107 for (size_t i
= 0; i
< p_dims
->get_nof_dims(); ++i
) {
108 ret_val
+= p_dims
->get_dim_byIndex(i
)->get_stringRepr();
113 void calculate_type_name_and_debug_functions_from_type(Type
* p_type
,
117 string
& p_print_function
,
118 string
& p_set_function
)
120 if (p_type_last
->get_typetype() == Type::T_COMPONENT
) {
121 p_type_name
= "component";
123 else if (p_type_last
->is_structured_type() ||
124 p_type_last
->get_typetype() == Type::T_ENUM_A
||
125 p_type_last
->get_typetype() == Type::T_ENUM_T
||
126 p_type_last
->get_typetype() == Type::T_SIGNATURE
||
127 p_type_last
->get_typetype() == Type::T_FUNCTION
||
128 p_type_last
->get_typetype() == Type::T_ALTSTEP
||
129 p_type_last
->get_typetype() == Type::T_TESTCASE
) {
131 if (p_type_last
->is_pard_type_instance()) {
132 // if the referenced type is an instance of an ASN.1 parameterized type,
133 // then use the last non-parameterized type in the reference chain to
134 // calculate the type name
136 while (t
->is_ref() && !t
->is_pard_type_instance()) {
137 p_type_name
= t
->get_dispname();
138 t
= t
->get_type_refd();
142 p_type_name
= p_type_last
->get_dispname();
144 const Module
* var_type_mod
= p_type_last
->get_my_scope()->get_scope_mod();
145 string module_prefix
;
146 if (var_type_mod
!= p_module
) {
147 module_prefix
= var_type_mod
->get_modid().get_name() + "::";
149 p_print_function
= module_prefix
+ "print_var_" +
150 var_type_mod
->get_modid().get_ttcnname();
151 if (p_type_last
->get_typetype() != Type::T_SIGNATURE
&&
152 p_type_last
->get_typetype() != Type::T_PORT
) {
153 p_set_function
= module_prefix
+ "set_var_" +
154 var_type_mod
->get_modid().get_ttcnname();
158 // built-in type, get the TTCN-3 version of the type if possible
159 switch (p_type_last
->get_typetype()) {
160 case Type::T_GENERALSTRING
:
161 case Type::T_GRAPHICSTRING
:
162 case Type::T_TELETEXSTRING
:
163 case Type::T_VIDEOTEXSTRING
:
164 // these ASN.1 string types are not converted right by Type::get_typetype_ttcn3()
165 p_type_name
= "universal charstring";
168 p_type_name
= "port";
170 case Type::T_UNRESTRICTEDSTRING
:
171 case Type::T_EMBEDDED_PDV
:
172 case Type::T_EXTERNAL
:
173 // these are converted to T_SEQ_T by Type::get_typetype_ttcn3()
174 p_type_name
= Type::get_typename_builtin(p_type_last
->get_typetype());
177 p_type_name
= Type::get_typename_builtin(p_type_last
->get_typetype_ttcn3());
183 char* generate_code_debugger_add_var(char* str
, Common::Assignment
* var_ass
,
184 Module
* current_mod
/* = NULL */,
185 const char* scope_name
/* = NULL */)
187 if (current_mod
== NULL
) {
188 current_mod
= var_ass
->get_my_scope()->get_scope_mod();
191 bool is_lazy_param
= false;
192 bool is_constant
= false;
193 switch (var_ass
->get_asstype()) {
194 case Common::Assignment::A_PAR_VAL
:
195 case Common::Assignment::A_PAR_VAL_IN
:
196 case Common::Assignment::A_PAR_TEMPL_IN
: {
197 if (var_ass
->get_lazy_eval()) {
198 // lazy parameters have their own printing function
199 is_lazy_param
= true;
201 Ttcn::FormalPar
* fpar
= dynamic_cast<Ttcn::FormalPar
*>(var_ass
);
202 is_constant
= fpar
== NULL
|| !fpar
->get_used_as_lvalue();
204 case Common::Assignment::A_CONST
:
205 case Common::Assignment::A_EXT_CONST
:
206 case Common::Assignment::A_MODULEPAR
:
207 case Common::Assignment::A_MODULEPAR_TEMP
:
208 case Common::Assignment::A_TEMPLATE
:
209 is_constant
= true; //scope_name != NULL;
214 // recreate the TTCN-3 version of the type name and determine the type's
215 // printing and overwriting functions
216 string type_name
, print_function
, set_function
;
217 print_function
= is_lazy_param
? "TTCN3_Debugger::print_lazy_param<" :
218 "TTCN3_Debugger::print_base_var";
219 set_function
= "TTCN3_Debugger::set_base_var";
220 if (var_ass
->get_asstype() == Common::Assignment::A_TIMER
||
221 var_ass
->get_asstype() == Common::Assignment::A_PAR_TIMER
) {
223 if (var_ass
->get_Dimensions() != NULL
) {
225 type_name
+= array_dimensions_to_string(var_ass
->get_Dimensions());
226 print_function
= string("TTCN3_Debugger::print_timer_array<") +
227 function_params_for_array_dims(var_ass
->get_Dimensions(),
228 string("TIMER"), string("TIMER_ARRAY")) +
233 Common::Type
* var_type
= var_ass
->get_Type();
234 // get the type at the end of the reference chain, but don't go through
235 // CHARACTER STRINGs, EMBEDDED PDVs and EXTERNALs
236 while (var_type
->is_ref() && var_type
->get_typetype() != Type::T_EXTERNAL
&&
237 var_type
->get_typetype() != Type::T_EMBEDDED_PDV
&&
238 var_type
->get_typetype() != Type::T_UNRESTRICTEDSTRING
) {
239 var_type
= var_type
->get_type_refd();
242 print_function
+= var_type
->get_genname_value(current_mod
);
244 if (var_type
->get_typetype() == Type::T_PORT
&& var_ass
->get_Dimensions() != NULL
) {
246 type_name
= var_type
->get_dispname() +
247 array_dimensions_to_string(var_ass
->get_Dimensions());
248 if (!is_lazy_param
) {
249 print_function
= string("TTCN3_Debugger::print_port_array<") +
250 function_params_for_array_dims(var_ass
->get_Dimensions(),
251 var_type
->get_genname_value(current_mod
),
252 string("PORT_ARRAY")) +
256 else if (var_type
->get_typetype() == Type::T_ARRAY
) {
259 while (t
->get_typetype() == Type::T_ARRAY
) {
260 dims_str
+= t
->get_dimension()->get_stringRepr();
261 t
= t
->get_ofType()->get_type_refd_last();
263 string dummy1
, dummy2
;
264 calculate_type_name_and_debug_functions_from_type(t
, t
, current_mod
,
265 type_name
, dummy1
, dummy2
);
266 type_name
+= dims_str
;
267 if (!is_lazy_param
) {
268 switch (var_ass
->get_asstype()) {
269 case Common::Assignment::A_MODULEPAR_TEMP
:
270 case Common::Assignment::A_TEMPLATE
:
271 case Common::Assignment::A_VAR_TEMPLATE
:
272 case Common::Assignment::A_PAR_TEMPL_IN
:
273 case Common::Assignment::A_PAR_TEMPL_OUT
:
274 case Common::Assignment::A_PAR_TEMPL_INOUT
:
276 print_function
= string("TTCN3_Debugger::print_template_array<") +
277 function_params_for_array_type(var_type
, current_mod
, true) +
279 set_function
= string("TTCN3_Debugger::set_template_array<") +
280 function_params_for_array_type(var_type
, current_mod
, true) +
285 print_function
= string("TTCN3_Debugger::print_value_array<") +
286 function_params_for_array_type(var_type
, current_mod
, false) +
288 set_function
= string("TTCN3_Debugger::set_value_array<") +
289 function_params_for_array_type(var_type
, current_mod
, false) +
297 calculate_type_name_and_debug_functions_from_type(var_ass
->get_Type(),
298 var_type
, current_mod
, type_name
, is_lazy_param
? dummy
: print_function
,
303 switch (var_ass
->get_asstype()) {
304 case Common::Assignment::A_MODULEPAR_TEMP
:
305 case Common::Assignment::A_TEMPLATE
:
306 case Common::Assignment::A_VAR_TEMPLATE
:
307 case Common::Assignment::A_PAR_TEMPL_IN
:
308 case Common::Assignment::A_PAR_TEMPL_OUT
:
309 case Common::Assignment::A_PAR_TEMPL_INOUT
:
310 // add a suffix, if it's a template
311 type_name
+= " template";
313 print_function
+= "_template";
321 print_function
+= ">";
325 if (scope_name
!= NULL
&& !strcmp(scope_name
, "global")) {
326 // only store the module name for global variables
327 module_str
= string("\"") +
328 var_ass
->get_my_scope()->get_scope_mod()->get_modid().get_ttcnname() + string("\"");
334 return mputprintf(str
, "%s%s_scope%sadd_variable(&%s, \"%s\", \"%s\", %s, %s%s%s);\n",
335 scope_name
!= NULL
? " " : "", // add indenting for global variables
336 scope_name
!= NULL
? scope_name
: "debug", // the prefix of the debugger scope:
337 // ("global" for global variables, "debug" for local variables,
338 // or the component name for component variables)
339 scope_name
!= NULL
? "->" : ".", // global scopes are pointers, local scopes
340 // are local variables
341 var_ass
->get_genname_from_scope(current_mod
, "").c_str(), // variable name in C++
342 // (HACK: an empty string is passed as the prefix parameter to get_genname_from_scope,
343 // so the lazy parameter evaluation code is not generated)
344 var_ass
->get_id().get_ttcnname().c_str(), // variable name in TTCN-3
345 type_name
.c_str(), // variable type in TTCN-3, with a suffix if it's a template
346 module_str
.c_str(), // module name, where the variable was defined
347 print_function
.c_str(), // variable printing function
348 is_constant
? "" : ", ", is_constant
? "" : set_function
.c_str());
349 // variable overwriting function (not generated for constants)
352 char* generate_code_debugger_function_init(char* str
, Common::Assignment
* func_ass
)
354 string comp_str
= func_ass
->get_RunsOnType() == NULL
? string("NULL") :
355 string("\"") + func_ass
->get_RunsOnType()->get_dispname() + string("\"");
356 const char* func_type_str
= NULL
;
357 switch (func_ass
->get_asstype()) {
358 case Common::Assignment::A_FUNCTION
:
359 case Common::Assignment::A_FUNCTION_RVAL
:
360 case Common::Assignment::A_FUNCTION_RTEMP
:
361 func_type_str
= "function";
363 case Common::Assignment::A_EXT_FUNCTION
:
364 case Common::Assignment::A_EXT_FUNCTION_RVAL
:
365 case Common::Assignment::A_EXT_FUNCTION_RTEMP
:
366 func_type_str
= "external function";
368 case Common::Assignment::A_TESTCASE
:
369 func_type_str
= "testcase";
371 case Common::Assignment::A_ALTSTEP
:
372 func_type_str
= "altstep";
374 case Common::Assignment::A_TEMPLATE
: // parameterized template
375 func_type_str
= "template";
380 Ttcn::FormalParList
* fp_list
= func_ass
!= NULL
? func_ass
->get_FormalParList() : NULL
;
381 if (fp_list
!= NULL
&& fp_list
->get_nof_fps() != 0) {
383 char* fp_names_str
= NULL
;
384 char* fp_types_str
= NULL
;
385 char* fp_add_var_str
= NULL
;
386 for (size_t i
= 0; i
< fp_list
->get_nof_fps(); ++i
) {
387 // gather everything needed for this parameter in sub-strings
388 Ttcn::FormalPar
* fp
= fp_list
->get_fp_byIndex(i
);
389 const char* fp_type_str
= NULL
;
390 switch (fp
->get_asstype()) {
391 case Common::Assignment::A_PAR_VAL
:
392 case Common::Assignment::A_PAR_VAL_IN
:
393 case Common::Assignment::A_PAR_TEMPL_IN
:
396 case Common::Assignment::A_PAR_VAL_INOUT
:
397 case Common::Assignment::A_PAR_TEMPL_INOUT
:
398 case Common::Assignment::A_PAR_TIMER
: // treat timers and ports as 'inout' parameters
399 case Common::Assignment::A_PAR_PORT
:
400 fp_type_str
= "inout";
402 case Common::Assignment::A_PAR_VAL_OUT
:
403 case Common::Assignment::A_PAR_TEMPL_OUT
:
409 fp_names_str
= mputprintf(fp_names_str
,
410 "param_names[%d] = \"%s\";\n", (int)i
, fp
->get_id().get_ttcnname().c_str());
411 fp_types_str
= mputprintf(fp_types_str
,
412 "param_types[%d] = \"%s\";\n", (int)i
, fp_type_str
);
413 fp_add_var_str
= generate_code_debugger_add_var(fp_add_var_str
, fp
);
415 str
= mputprintf(str
,
416 "charstring_list param_names;\n"
418 "charstring_list param_types;\n"
420 "TTCN3_Debug_Function debug_scope(\"%s\", \"%s\", \"%s\", param_names, param_types, %s);\n"
422 "debug_scope.initial_snapshot();\n"
423 , fp_names_str
, fp_types_str
424 , func_ass
->get_id().get_dispname().c_str(), func_type_str
425 , func_ass
->get_my_scope()->get_scope_mod()->get_modid().get_ttcnname().c_str()
426 , comp_str
.c_str(), fp_add_var_str
);
429 Free(fp_add_var_str
);
433 str
= mputprintf(str
,
434 "charstring_list no_params = NULL_VALUE;\n"
435 "TTCN3_Debug_Function debug_scope(\"%s\", \"%s\", \"%s\", no_params, no_params, %s);\n"
436 "debug_scope.initial_snapshot();\n"
437 , func_ass
->get_id().get_dispname().c_str(), func_type_str
438 , func_ass
->get_my_scope()->get_scope_mod()->get_modid().get_ttcnname().c_str()
This page took 0.043127 seconds and 5 git commands to generate.