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_print_function_from_type(Type
* p_type
,
117 string
& p_print_function
)
119 if (p_type_last
->get_typetype() == Type::T_COMPONENT
) {
120 p_type_name
= "component";
122 else if (p_type_last
->is_structured_type() ||
123 p_type_last
->get_typetype() == Type::T_ENUM_A
||
124 p_type_last
->get_typetype() == Type::T_ENUM_T
||
125 p_type_last
->get_typetype() == Type::T_PORT
||
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 if (var_type_mod
!= p_module
) {
146 p_print_function
= var_type_mod
->get_modid().get_name() + "::";
149 p_print_function
.clear();
151 p_print_function
+= "print_var_" + var_type_mod
->get_modid().get_ttcnname();
154 // built-in type, get the TTCN-3 version of the type if possible
155 switch (p_type_last
->get_typetype()) {
156 case Type::T_GENERALSTRING
:
157 case Type::T_GRAPHICSTRING
:
158 case Type::T_TELETEXSTRING
:
159 case Type::T_VIDEOTEXSTRING
:
160 // these ASN.1 string types are not converted right by Type::get_typetype_ttcn3()
161 p_type_name
= "universal charstring";
163 case Type::T_UNRESTRICTEDSTRING
:
164 case Type::T_EMBEDDED_PDV
:
165 case Type::T_EXTERNAL
:
166 // these are converted to T_SEQ_T by Type::get_typetype_ttcn3()
167 p_type_name
= Type::get_typename_builtin(p_type_last
->get_typetype());
170 p_type_name
= Type::get_typename_builtin(p_type_last
->get_typetype_ttcn3());
176 char* generate_code_debugger_add_var(char* str
, Common::Assignment
* var_ass
,
177 Module
* current_mod
/* = NULL */,
178 const char* scope_name
/* = NULL */)
180 if (current_mod
== NULL
) {
181 current_mod
= var_ass
->get_my_scope()->get_scope_mod();
184 bool is_lazy_param
= false;
185 switch (var_ass
->get_asstype()) {
186 case Common::Assignment::A_PAR_VAL
:
187 case Common::Assignment::A_PAR_VAL_IN
:
188 case Common::Assignment::A_PAR_TEMPL_IN
:
189 if (var_ass
->get_lazy_eval()) {
190 // lazy parameters have their own printing function
191 is_lazy_param
= true;
198 // recreate the TTCN-3 version of the type name and determine the type's printing function
199 string type_name
, print_function
;
200 print_function
= is_lazy_param
? "TTCN3_Debugger::print_lazy_param<" :
201 "TTCN3_Debugger::print_base_var";
202 if (var_ass
->get_asstype() == Common::Assignment::A_TIMER
||
203 var_ass
->get_asstype() == Common::Assignment::A_PAR_TIMER
) {
205 if (var_ass
->get_Dimensions() != NULL
) {
207 type_name
+= array_dimensions_to_string(var_ass
->get_Dimensions());
208 print_function
= string("TTCN3_Debugger::print_timer_array<") +
209 function_params_for_array_dims(var_ass
->get_Dimensions(),
210 string("TIMER"), string("TIMER_ARRAY")) +
215 Common::Type
* var_type
= var_ass
->get_Type();
216 // get the type at the end of the reference chain, but don't go through
217 // CHARACTER STRINGs, EMBEDDED PDVs and EXTERNALs
218 while (var_type
->is_ref() && var_type
->get_typetype() != Type::T_EXTERNAL
&&
219 var_type
->get_typetype() != Type::T_EMBEDDED_PDV
&&
220 var_type
->get_typetype() != Type::T_UNRESTRICTEDSTRING
) {
221 var_type
= var_type
->get_type_refd();
224 print_function
+= var_type
->get_genname_value(current_mod
);
226 if (var_type
->get_typetype() == Type::T_PORT
&& var_ass
->get_Dimensions() != NULL
) {
228 type_name
= var_type
->get_dispname() +
229 array_dimensions_to_string(var_ass
->get_Dimensions());
230 if (!is_lazy_param
) {
231 print_function
= string("TTCN3_Debugger::print_port_array<") +
232 function_params_for_array_dims(var_ass
->get_Dimensions(),
233 var_type
->get_genname_value(current_mod
),
234 string("PORT_ARRAY")) +
238 else if (var_type
->get_typetype() == Type::T_ARRAY
) {
241 while (t
->get_typetype() == Type::T_ARRAY
) {
242 dims_str
+= t
->get_dimension()->get_stringRepr();
243 t
= t
->get_ofType()->get_type_refd_last();
246 calculate_type_name_and_print_function_from_type(t
, t
, current_mod
, type_name
, dummy
);
247 type_name
+= dims_str
;
248 if (!is_lazy_param
) {
249 switch (var_ass
->get_asstype()) {
250 case Common::Assignment::A_MODULEPAR_TEMP
:
251 case Common::Assignment::A_TEMPLATE
:
252 case Common::Assignment::A_VAR_TEMPLATE
:
253 case Common::Assignment::A_PAR_TEMPL_IN
:
254 case Common::Assignment::A_PAR_TEMPL_OUT
:
255 case Common::Assignment::A_PAR_TEMPL_INOUT
:
257 print_function
= string("TTCN3_Debugger::print_template_array<") +
258 function_params_for_array_type(var_type
, current_mod
, true) +
263 print_function
= string("TTCN3_Debugger::print_value_array<") +
264 function_params_for_array_type(var_type
, current_mod
, false) +
272 calculate_type_name_and_print_function_from_type(var_ass
->get_Type(),
273 var_type
, current_mod
, type_name
, is_lazy_param
? dummy
: print_function
);
277 switch (var_ass
->get_asstype()) {
278 case Common::Assignment::A_MODULEPAR_TEMP
:
279 case Common::Assignment::A_TEMPLATE
:
280 case Common::Assignment::A_VAR_TEMPLATE
:
281 case Common::Assignment::A_PAR_TEMPL_IN
:
282 case Common::Assignment::A_PAR_TEMPL_OUT
:
283 case Common::Assignment::A_PAR_TEMPL_INOUT
:
284 // add a suffix, if it's a template
285 type_name
+= " template";
287 print_function
+= "_template";
295 print_function
+= ">";
298 return mputprintf(str
, "%s%s_scope%sadd_variable(&%s, \"%s\", \"%s\", %s);\n",
299 scope_name
!= NULL
? " " : "", // add indenting for global variables
300 scope_name
!= NULL
? scope_name
: "debug", // the prefix of the debugger scope:
301 // ("global" for global variables, "debug" for local variables,
302 // or the component name for component variables)
303 scope_name
!= NULL
? "->" : ".", // global scopes are pointers, local scopes
304 // are local variables
305 var_ass
->get_genname_from_scope(current_mod
, "").c_str(), // variable name in C++
306 // (HACK: an empty string is passed as the prefix parameter to get_genname_from_scope,
307 // so the lazy parameter evaluation code is not generated)
308 var_ass
->get_id().get_ttcnname().c_str(), // variable name in TTCN-3
309 type_name
.c_str(), // variable type in TTCN-3, with a suffix if it's a template
310 print_function
.c_str()); // variable printing function
313 char* generate_code_debugger_function_init(char* str
, Common::Assignment
* func_ass
)
315 string comp_str
= func_ass
->get_RunsOnType() == NULL
? string("NULL") :
316 string("\"") + func_ass
->get_RunsOnType()->get_dispname() + string("\"");
317 const char* func_type_str
= NULL
;
318 switch (func_ass
->get_asstype()) {
319 case Common::Assignment::A_FUNCTION
:
320 case Common::Assignment::A_FUNCTION_RVAL
:
321 case Common::Assignment::A_FUNCTION_RTEMP
:
322 func_type_str
= "function";
324 case Common::Assignment::A_EXT_FUNCTION
:
325 case Common::Assignment::A_EXT_FUNCTION_RVAL
:
326 case Common::Assignment::A_EXT_FUNCTION_RTEMP
:
327 func_type_str
= "external function";
329 case Common::Assignment::A_TESTCASE
:
330 func_type_str
= "testcase";
332 case Common::Assignment::A_ALTSTEP
:
333 func_type_str
= "altstep";
335 case Common::Assignment::A_TEMPLATE
: // parameterized template
336 func_type_str
= "template";
341 Ttcn::FormalParList
* fp_list
= func_ass
!= NULL
? func_ass
->get_FormalParList() : NULL
;
342 if (fp_list
!= NULL
&& fp_list
->get_nof_fps() != 0) {
344 char* fp_names_str
= NULL
;
345 char* fp_types_str
= NULL
;
346 char* fp_add_var_str
= NULL
;
347 for (size_t i
= 0; i
< fp_list
->get_nof_fps(); ++i
) {
348 // gather everything needed for this parameter in sub-strings
349 Ttcn::FormalPar
* fp
= fp_list
->get_fp_byIndex(i
);
350 const char* fp_type_str
= NULL
;
351 switch (fp
->get_asstype()) {
352 case Common::Assignment::A_PAR_VAL
:
353 case Common::Assignment::A_PAR_VAL_IN
:
354 case Common::Assignment::A_PAR_TEMPL_IN
:
357 case Common::Assignment::A_PAR_VAL_INOUT
:
358 case Common::Assignment::A_PAR_TEMPL_INOUT
:
359 case Common::Assignment::A_PAR_TIMER
: // treat timers and ports as 'inout' parameters
360 case Common::Assignment::A_PAR_PORT
:
361 fp_type_str
= "inout";
363 case Common::Assignment::A_PAR_VAL_OUT
:
364 case Common::Assignment::A_PAR_TEMPL_OUT
:
370 fp_names_str
= mputprintf(fp_names_str
,
371 "param_names[%d] = \"%s\";\n", (int)i
, fp
->get_id().get_ttcnname().c_str());
372 fp_types_str
= mputprintf(fp_types_str
,
373 "param_types[%d] = \"%s\";\n", (int)i
, fp_type_str
);
374 fp_add_var_str
= generate_code_debugger_add_var(fp_add_var_str
, fp
);
376 str
= mputprintf(str
,
377 "charstring_list param_names;\n"
379 "charstring_list param_types;\n"
381 "TTCN3_Debug_Function debug_scope(\"%s\", \"%s\", \"%s\", param_names, param_types, %s);\n"
383 "debug_scope.initial_snapshot();\n"
384 , fp_names_str
, fp_types_str
385 , func_ass
->get_id().get_dispname().c_str(), func_type_str
386 , func_ass
->get_my_scope()->get_scope_mod()->get_modid().get_ttcnname().c_str()
387 , comp_str
.c_str(), fp_add_var_str
);
390 Free(fp_add_var_str
);
394 str
= mputprintf(str
,
395 "charstring_list no_params = NULL_VALUE;\n"
396 "TTCN3_Debug_Function debug_scope(\"%s\", \"%s\", \"%s\", no_params, no_params, %s);\n"
397 "debug_scope.initial_snapshot();\n"
398 , func_ass
->get_id().get_dispname().c_str(), func_type_str
399 , func_ass
->get_my_scope()->get_scope_mod()->get_modid().get_ttcnname().c_str()
This page took 0.040944 seconds and 5 git commands to generate.