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
12 * Zalanyi, Balazs Andor
14 ******************************************************************************/
15 #include "CodeGenHelper.hh"
24 CodeGenHelper
* CodeGenHelper::instance
= 0;
26 CodeGenHelper::generated_output_t::generated_output_t() :
29 has_circular_import(false)
31 Code::init_output(&os
);
34 CodeGenHelper::generated_output_t::~generated_output_t() {
35 Code::free_output(&os
);
39 const char* const CodeGenHelper::typetypemap
[] = {
41 "", /**< erroneous (e.g. nonexistent reference) */
42 "", /**< null (ASN.1) */
45 "", /**< integer / ASN */
46 "", /**< real/float */
47 "", /**< enumerated / ASN */
48 "", /**< enumerated / TTCN */
51 "", /**< hexstring (TTCN-3) */
52 "", /**< octetstring */
53 "", /**< charstring (TTCN-3) */
54 "", /**< universal charstring (TTCN-3) */
55 "", /**< UTF8String (ASN.1) */
56 "", /**< NumericString (ASN.1) */
57 "", /**< PrintableString (ASN.1) */
58 "", /**< TeletexString (ASN.1) */
59 "", /**< VideotexString (ASN.1) */
60 "", /**< IA5String (ASN.1) */
61 "", /**< GraphicString (ASN.1) */
62 "", /**< VisibleString (ASN.1) */
63 "", /**< GeneralString (ASN.1) */
64 "", /**< UniversalString (ASN.1) */
65 "", /**< BMPString (ASN.1) */
66 "", /**< UnrestrictedCharacterString (ASN.1) */
67 "", /**< UTCTime (ASN.1) */
68 "", /**< GeneralizedTime (ASN.1) */
69 "", /** Object descriptor, a kind of string (ASN.1) */
70 "", /**< object identifier */
71 "", /**< relative OID (ASN.1) */
72 "_union", /**< choice /ASN, uses u.secho */
73 "_union", /**< union /TTCN, uses u.secho */
74 "_seqof", /**< sequence (record) of */
75 "_setof", /**< set of */
76 "_seq", /**< sequence /ASN, uses u.secho */
77 "_seq", /**< record /TTCN, uses u.secho */
78 "_set", /**< set /ASN, uses u.secho */
79 "_set", /**< set /TTCN, uses u.secho */
80 "", /**< ObjectClassFieldType (ASN.1) */
81 "", /**< open type (ASN.1) */
82 "", /**< ANY (deprecated ASN.1) */
83 "", /**< %EXTERNAL (ASN.1) */
84 "", /**< EMBEDDED PDV (ASN.1) */
85 "", /**< referenced */
86 "", /**< special referenced (by pointer, not by name) */
87 "", /**< selection type (ASN.1) */
88 "", /**< verdict type (TTCN-3) */
89 "", /**< port type (TTCN-3) */
90 "", /**< component type (TTCN-3) */
91 "", /**< address type (TTCN-3) */
92 "", /**< default type (TTCN-3) */
93 "", /**< array (TTCN-3), uses u.array */
94 "", /**< signature (TTCN-3) */
95 "", /**< function reference (TTCN-3) */
96 "", /**< altstep reference (TTCN-3) */
97 "", /**< testcase reference (TTCN-3) */
98 "", /**< anytype (TTCN-3) */
102 CodeGenHelper::CodeGenHelper() :
103 split_mode(SPLIT_NONE
)
106 FATAL_ERROR("Attempted to create a second code generator.");
110 CodeGenHelper
& CodeGenHelper::GetInstance() {
112 FATAL_ERROR("Trying to access to the already destroyed code generator.");
116 void CodeGenHelper::set_split_mode(split_type st
) {
120 bool CodeGenHelper::set_split_mode(const char* type
) {
121 if (strcmp(type
, "none") == 0)
122 split_mode
= SPLIT_NONE
;
123 else if (strcmp(type
, "type") == 0)
124 split_mode
= SPLIT_BY_KIND
;
130 CodeGenHelper::split_type
CodeGenHelper::get_split_mode() const {
134 void CodeGenHelper::add_module(const string
& name
, const string
& dispname
,
135 bool is_ttcn
, bool has_circular_import
) {
136 generated_output_t
* go
= new generated_output_t
;
137 go
->filename
.clear();
138 go
->modulename
= name
;
139 go
->module_dispname
= dispname
;
140 go
->is_module
= true;
141 go
->is_ttcn
= is_ttcn
;
142 go
->has_circular_import
= has_circular_import
;
143 generated_code
.add(dispname
, go
);
144 module_names_t
* mod_names
= new module_names_t
;
145 mod_names
->name
= name
;
146 mod_names
->dispname
= dispname
;
147 modules
.add(mod_names
);
150 output_struct
* CodeGenHelper::get_outputstruct(const string
& name
) {
151 return &generated_code
[name
]->os
;
154 void CodeGenHelper::set_current_module(const string
& name
) {
155 current_module
= name
;
158 output_struct
* CodeGenHelper::get_outputstruct(Ttcn::Definition
* def
) {
159 string key
= get_key(*def
);
160 const string
& new_name
= current_module
+ key
;
161 if (!generated_code
.has_key(new_name
)) {
162 generated_output_t
* go
= new generated_output_t
;
164 go
->modulename
= generated_code
[current_module
]->modulename
;
165 go
->module_dispname
= generated_code
[current_module
]->module_dispname
;
166 generated_code
.add(new_name
, go
);
167 go
->os
.source
.includes
= mprintf("\n#include \"%s.hh\"\n"
168 , current_module
.c_str());
170 return &generated_code
[new_name
]->os
;
173 output_struct
* CodeGenHelper::get_outputstruct(Type
* type
) {
174 string key
= get_key(*type
);
175 const string
& new_name
= current_module
+ key
;
176 if (!generated_code
.has_key(new_name
)) {
177 generated_output_t
* go
= new generated_output_t
;
179 go
->modulename
= generated_code
[current_module
]->modulename
;
180 go
->module_dispname
= generated_code
[current_module
]->module_dispname
;
181 generated_code
.add(new_name
, go
);
182 go
->os
.source
.includes
= mprintf("\n#include \"%s.hh\"\n"
183 , current_module
.c_str());
185 return &generated_code
[new_name
]->os
;
188 output_struct
* CodeGenHelper::get_current_outputstruct() {
189 return &generated_code
[current_module
]->os
;
192 void CodeGenHelper::transfer_value(char* &dst
, char* &src
) {
193 dst
= mputstr(dst
, src
);
198 void CodeGenHelper::finalize_generation(Type
* type
) {
199 string key
= get_key(*type
);
200 if (key
.empty()) return;
202 output_struct
& dst
= *get_current_outputstruct();
203 output_struct
& src
= *get_outputstruct(current_module
+ key
);
204 // key is not empty so these can never be the same
206 transfer_value(dst
.header
.includes
, src
.header
.includes
);
207 transfer_value(dst
.header
.class_decls
, src
.header
.class_decls
);
208 transfer_value(dst
.header
.typedefs
, src
.header
.typedefs
);
209 transfer_value(dst
.header
.class_defs
, src
.header
.class_defs
);
210 transfer_value(dst
.header
.function_prototypes
, src
.header
.function_prototypes
);
211 transfer_value(dst
.header
.global_vars
, src
.header
.global_vars
);
212 transfer_value(dst
.header
.testport_includes
, src
.header
.testport_includes
);
214 transfer_value(dst
.source
.global_vars
, src
.source
.global_vars
);
216 transfer_value(dst
.functions
.pre_init
, src
.functions
.pre_init
);
217 transfer_value(dst
.functions
.post_init
, src
.functions
.post_init
);
219 transfer_value(dst
.functions
.set_param
, src
.functions
.set_param
);
220 transfer_value(dst
.functions
.get_param
, src
.functions
.get_param
);
221 transfer_value(dst
.functions
.log_param
, src
.functions
.log_param
);
222 transfer_value(dst
.functions
.init_comp
, src
.functions
.init_comp
);
223 transfer_value(dst
.functions
.start
, src
.functions
.start
);
224 transfer_value(dst
.functions
.control
, src
.functions
.control
);
227 string
CodeGenHelper::get_key(Ttcn::Definition
& def
) const {
229 switch (split_mode
) {
231 // returns the current module
236 retval
+= "_" + def
.get_id().get_name();
238 case SPLIT_BY_HEURISTICS
:
244 string
CodeGenHelper::get_key(Type
& type
) const {
246 switch (split_mode
) {
249 case SPLIT_BY_KIND
: {
250 Type::typetype_t tt
= type
.get_typetype();
252 case Type::T_CHOICE_A
:
253 case Type::T_CHOICE_T
:
260 retval
+= typetypemap
[(int)tt
];
263 // put it into the module (no suffix)
269 case SPLIT_BY_HEURISTICS
:
275 void CodeGenHelper::write_output() {
277 if (split_mode
== SPLIT_BY_KIND
) {
278 // Create empty files to have a fix set of files to compile
280 for (j
= 0; j
< modules
.size(); j
++) {
281 for (i
= 0; typetypemap
[i
]; i
++) {
282 fname
= modules
[j
]->dispname
+ typetypemap
[i
];
283 if (!generated_code
.has_key(fname
)) {
284 generated_output_t
* go
= new generated_output_t
;
285 go
->filename
= typetypemap
[i
];
286 go
->modulename
= modules
[j
]->name
;
287 go
->module_dispname
= modules
[j
]->dispname
;
288 go
->os
.source
.includes
= mcopystr(
289 "\n//This file intentionally empty."
290 "\n#include <version.h>\n");
291 generated_code
.add(fname
, go
);
296 generated_output_t
* go
;
297 for (i
= 0; i
< generated_code
.size(); i
++) {
298 go
= generated_code
.get_nth_elem(i
);
299 ::write_output(&go
->os
, go
->modulename
.c_str(), go
->module_dispname
.c_str(),
300 go
->filename
.c_str(), go
->is_ttcn
, go
->has_circular_import
, go
->is_module
);
304 CodeGenHelper::~CodeGenHelper() {
306 for (i
= 0; i
< generated_code
.size(); i
++)
307 delete generated_code
.get_nth_elem(i
);
308 generated_code
.clear();
309 for (i
= 0; i
< modules
.size(); i
++)
This page took 0.037453 seconds and 5 git commands to generate.